searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Android原生水印介绍

2024-04-30 08:34:10
19
0

目前有Android系统端有水印的需求,通过源码搜索,发现在系统中自带水印功能,下面看下水印的逻辑:

流程

  1. 代码路径

水印类的实现位置在原生的代码路径中:/frameworks/base/services/core/java/com/android/server/wm/Watermark.java

  1. 调用的地方

在 WindowManagerService.java中定义了局部变量:

    Watermark mWatermark;
    StrictModeFlash mStrictModeFlash;
    CircularDisplayMask mCircularDisplayMask;
    EmulatorDisplayOverlay mEmulatorDisplayOverlay;

当 SystemService启动时候,执行了

private void startOtherServices() {
        final Context context = mSystemContext;
        VibratorService vibrator = null;
        IStorageManager storageManager = null;
        NetworkManagementService networkManagement = null;
        IpSecService ipSecService = null;
        NetworkStatsService networkStats = null;
        ...

        wm.onInitReady();  //这里对wmservice进行了初始化准备
        ...
}

回到WindowManagerSerive中的onInitReady函数中:

public void onInitReady() {
        initPolicy();

        // Add ourself to the Watchdog monitors.
        Watchdog.getInstance().addMonitor(this);

        openSurfaceTransaction();
        try {
            createWatermarkInTransaction();
        } finally {
            closeSurfaceTransaction("createWatermarkInTransaction");
        }

        showEmulatorDisplayOverlayIfNeeded();
}

createWatermarkInTransaction 这个函数就是用来创建水印实例的。

    void createWatermarkInTransaction() {
        if (mWatermark != null) {
            return;
        }

        File file = new File("/system/etc/setup.conf");
        FileInputStream in = null;
        DataInputStream ind = null;
        try {
            in = new FileInputStream(file);
            ind = new DataInputStream(in);
            String line = ind.readLine();
            if (line != null) {
                String[] toks = line.split("%");
                if (toks != null && toks.length > 0) {
                    // TODO(multi-display): Show watermarks on secondary displays.
                    final DisplayContent displayContent = getDefaultDisplayContentLocked();
                    mWatermark = new Watermark(displayContent, displayContent.mRealDisplayMetrics,
                            toks);
                }
            }
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        } finally {
            if (ind != null) {
                try {
                    ind.close();
                } catch (IOException e) {
                }
            } else if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
        }
    }

其中核心文件就是 /system/etc/setup.conf,通过读取该配置文件,将数据内容作为参数初始化Watermark。
mWatermark = new Watermark(displayContent, displayContent.mRealDisplayMetrics,toks);所有的实现都在Watermark.java文件中。查看该文件可以看出,对传入的参数进行了编码转换,所以输入的内容要使用进制的来进行转换:

        StringBuilder builder = new StringBuilder();
        int len = mTokens[0].length();
        len = len & ~1;
        for (int i=0; i<len; i+=2) {
            int c1 = mTokens[0].charAt(i);
            int c2 = mTokens[0].charAt(i+1);
            if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + ;
            else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + ;
            else c1 -= '0';
            if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + ;
            else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + ;
            else c2 -= '0';
            builder.append((char)(-((c1*)+c2)));
        }

而显示的逻辑其实就是增加了一个Layer:

  try {
            ctrl = dc.makeOverlay()
                    .setName("WatermarkSurface")
                    .setSize(1, 1)
                    .setFormat(PixelFormat.TRANSLUCENT)
                    .build();
            ctrl.setLayerStack(mDisplay.getLayerStack());
            ctrl.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER*);
            ctrl.setPosition(0, 0);
            ctrl.show();
            mSurface.copyFrom(ctrl);
        } catch (OutOfResourcesException e) {
    }

绘制时机,WindowAnimator.java中查看

    if (mService.mWatermark != null) {
        mService.mWatermark.drawIfNeeded();
    }

验证

0条评论
0 / 1000
张****龙
18文章数
0粉丝数
张****龙
18 文章 | 0 粉丝
张****龙
18文章数
0粉丝数
张****龙
18 文章 | 0 粉丝
原创

Android原生水印介绍

2024-04-30 08:34:10
19
0

目前有Android系统端有水印的需求,通过源码搜索,发现在系统中自带水印功能,下面看下水印的逻辑:

流程

  1. 代码路径

水印类的实现位置在原生的代码路径中:/frameworks/base/services/core/java/com/android/server/wm/Watermark.java

  1. 调用的地方

在 WindowManagerService.java中定义了局部变量:

    Watermark mWatermark;
    StrictModeFlash mStrictModeFlash;
    CircularDisplayMask mCircularDisplayMask;
    EmulatorDisplayOverlay mEmulatorDisplayOverlay;

当 SystemService启动时候,执行了

private void startOtherServices() {
        final Context context = mSystemContext;
        VibratorService vibrator = null;
        IStorageManager storageManager = null;
        NetworkManagementService networkManagement = null;
        IpSecService ipSecService = null;
        NetworkStatsService networkStats = null;
        ...

        wm.onInitReady();  //这里对wmservice进行了初始化准备
        ...
}

回到WindowManagerSerive中的onInitReady函数中:

public void onInitReady() {
        initPolicy();

        // Add ourself to the Watchdog monitors.
        Watchdog.getInstance().addMonitor(this);

        openSurfaceTransaction();
        try {
            createWatermarkInTransaction();
        } finally {
            closeSurfaceTransaction("createWatermarkInTransaction");
        }

        showEmulatorDisplayOverlayIfNeeded();
}

createWatermarkInTransaction 这个函数就是用来创建水印实例的。

    void createWatermarkInTransaction() {
        if (mWatermark != null) {
            return;
        }

        File file = new File("/system/etc/setup.conf");
        FileInputStream in = null;
        DataInputStream ind = null;
        try {
            in = new FileInputStream(file);
            ind = new DataInputStream(in);
            String line = ind.readLine();
            if (line != null) {
                String[] toks = line.split("%");
                if (toks != null && toks.length > 0) {
                    // TODO(multi-display): Show watermarks on secondary displays.
                    final DisplayContent displayContent = getDefaultDisplayContentLocked();
                    mWatermark = new Watermark(displayContent, displayContent.mRealDisplayMetrics,
                            toks);
                }
            }
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        } finally {
            if (ind != null) {
                try {
                    ind.close();
                } catch (IOException e) {
                }
            } else if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
        }
    }

其中核心文件就是 /system/etc/setup.conf,通过读取该配置文件,将数据内容作为参数初始化Watermark。
mWatermark = new Watermark(displayContent, displayContent.mRealDisplayMetrics,toks);所有的实现都在Watermark.java文件中。查看该文件可以看出,对传入的参数进行了编码转换,所以输入的内容要使用进制的来进行转换:

        StringBuilder builder = new StringBuilder();
        int len = mTokens[0].length();
        len = len & ~1;
        for (int i=0; i<len; i+=2) {
            int c1 = mTokens[0].charAt(i);
            int c2 = mTokens[0].charAt(i+1);
            if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + ;
            else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + ;
            else c1 -= '0';
            if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + ;
            else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + ;
            else c2 -= '0';
            builder.append((char)(-((c1*)+c2)));
        }

而显示的逻辑其实就是增加了一个Layer:

  try {
            ctrl = dc.makeOverlay()
                    .setName("WatermarkSurface")
                    .setSize(1, 1)
                    .setFormat(PixelFormat.TRANSLUCENT)
                    .build();
            ctrl.setLayerStack(mDisplay.getLayerStack());
            ctrl.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER*);
            ctrl.setPosition(0, 0);
            ctrl.show();
            mSurface.copyFrom(ctrl);
        } catch (OutOfResourcesException e) {
    }

绘制时机,WindowAnimator.java中查看

    if (mService.mWatermark != null) {
        mService.mWatermark.drawIfNeeded();
    }

验证

文章来自个人专栏
linux相关
18 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0