• launcher homeSettings notificationDots


    背景描述

    Android12,修改源码中launcher包名后,需要修改很多默认配置。其它模块调用launcher包名修改,framework默认配置修改,gms下面overlay修改等等。
    本问简单记录一下桌面设置中“通知圆点”。在修改包名之后变成三角形,没有默认open的问题。

    问题跟踪

    1、问题原因
    因为界面在launcher中,现在launcher中找到菜单的显示逻辑,看看是根据什么判断的状态。
    packages\apps\Launcher3\src\com\android\launcher3\settings\NotificationDotsPreference.java

    private static final String NOTIFICATION_ENABLED_LISTENERS = "enabled_notification_listeners";
        @Override
        public void onSettingsChanged(boolean enabled) {
            int summary = enabled
                    ? R.string.notification_dots_desc_on
                    : R.string.notification_dots_desc_off;
    
            boolean serviceEnabled = true;
            if (enabled) {
                // Check if the listener is enabled or not.
                //获取setting数据库中的值
                String enabledListeners = Settings.Secure.getString(
                        getContext().getContentResolver(), NOTIFICATION_ENABLED_LISTENERS);
                //当前类包类名
                ComponentName myListener =
                        new ComponentName(getContext(), NotificationListener.class);
                //判断是否打开
                serviceEnabled = enabledListeners != null &&
                        (enabledListeners.contains(myListener.flattenToString()) ||
                                enabledListeners.contains(myListener.flattenToShortString()));
                if (!serviceEnabled) {
                    summary = R.string.title_missing_notification_access;
                }
            }
            setWidgetFrameVisible(!serviceEnabled);
            setFragment(serviceEnabled ? null : NotificationAccessConfirmation.class.getName());
            setSummary(summary);
            NotifyDotNumWrapper.setNotifyDotsExtPrefEnabled(getContext(), enabled && !mWidgetFrameVisible);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    以上可以看出,其实关键在于Settings.Secure.getString(getContext().getContentResolver(), NOTIFICATION_ENABLED_LISTENERS);这个值。
    正常情况下adb打印如下:

    adb shell settings get secure enabled_notification_listeners
    com.google.android.projection.gearhead/com.google.android.gearhead.notifications.SharedNotificationListenerManager$ListenerService:com.android.launcher3/com.android.launcher3.notification.NotificationListener
    
    • 1
    • 2

    修改包名之后,这个值没有launcher的NotificationListener了。所以launcher桌面设置中显示三角形。
    2、NOTIFICATION_ENABLED_LISTENERS
    NOTIFICATION_ENABLED_LISTENERS = “enabled_notification_listeners”
    那么现在的问题就是这个值是哪里设置进去的。
    弯路1:
    一开始以为是在setting或者settingprovider里,后来发现这两个代码里没有相关的东西。
    弯路2:
    在framework中搜索enabled_notification_listeners,发现直接调用enabled_notification_listeners的地方,没有调用Settings.Secure.putStringForUser()方法。那么可能是间接调用然后本地临时变量存了key值,再去put。这样就不容易找到默认值是哪里写入的了。
    解套
    1、frameworks\base\core\java\android\provider\Settings.java

    直接找到putStringForUser方法,添加调用堆栈打印:
    if("enabled_notification_listeners".equals(name)){
    	Log.i(TAG,  "putStringForUser"+Log.getStackTraceString(new Throwable()));
    }
    
    • 1
    • 2
    • 3
    • 4
    2022-11-23 23:19:28.003 1125-1255/system_process I/Settings: putStringForUserjava.lang.Throwable
            at android.provider.Settings$Secure.putStringForUser(Settings.java:5900)
            at android.provider.Settings$Secure.putStringForUser(Settings.java:5890)
            at com.android.server.notification.ManagedServices.writeXml(ManagedServices.java:536)
            at com.android.server.notification.NotificationManagerService.writePolicyXml(NotificationManagerService.java:1100)
            at com.android.server.notification.NotificationManagerService.access$200(NotificationManagerService.java:338)
            at com.android.server.notification.NotificationManagerService$SavePolicyFileRunnable.run(NotificationManagerService.java:1075)
            at android.os.Handler.handleCallback(Handler.java:938)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2、由此跟踪到frameworks\base\services\core\java\com\android\server\notification\ManagedServices.java
    写值的方法都在这个类里

    writeXml方法去调用的put值
    //它里面所有put的值来源mApproved
    protected ArrayMap<Integer, ArrayMap<Boolean, ArraySet<String>>> mApproved = new ArrayMap<>();
    //查一查mApproved值的来源
    //整个类只有2个地方调用mApproved.put
    //添加堆栈打印,再次编译后得到调用堆栈如下
    //setPackageOrComponentEnabled方法
      addDefaultComponentOrPackage: java.lang.Throwable
     	at com.android.server.notification.ManagedServices.addDefaultComponentOrPackage(ManagedServices.java:219)
     	at com.android.server.notification.NotificationManagerService$NotificationListeners.loadDefaultsFromConfig(NotificationManagerService.java:10247)
     	at com.android.server.notification.NotificationManagerService.loadDefaultApprovedServices(NotificationManagerService.java:748)
     	at com.android.server.notification.NotificationManagerService.loadPolicyFile(NotificationManagerService.java:1040)
     	at com.android.server.notification.NotificationManagerService.init(NotificationManagerService.java:2384)
     	at com.android.server.notification.NotificationManagerService.onStart(NotificationManagerService.java:2554)
     	at com.android.server.SystemServiceManager.startService(SystemServiceManager.java:205)
     	at com.android.server.SystemServiceManager.startService(SystemServiceManager.java:192)
     	at com.android.server.SystemServer.startOtherServices(SystemServer.java:2064)
     	at com.android.server.SystemServer.run(SystemServer.java:933)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    由此可见,系统启动流程中启动了service,service的init调用了加载默认配置。
    3、跟踪上面流程中,加载默认配置的值是配在哪里
    frameworks\base\services\core\java\com\android\server\notification\NotificationManagerService.java
    内部类public class NotificationListeners extends ManagedServices

            @Override
            protected void loadDefaultsFromConfig() {
                String defaultListenerAccess = mContext.getResources().getString(
                        R.string.config_defaultListenerAccessPackages);
                Log.v(TAG, " loadDefaultsFromConfig defaultListenerAccess: "+defaultListenerAccess);
                if (defaultListenerAccess != null) {
                    String[] listeners =
                            defaultListenerAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR);
                    for (int i = 0; i < listeners.length; i++) {
                        if (TextUtils.isEmpty(listeners[i])) {
                            continue;
                        }
                        ArraySet<ComponentName> approvedListeners =
                                this.queryPackageForServices(listeners[i],
                                        MATCH_DIRECT_BOOT_AWARE
                                                | MATCH_DIRECT_BOOT_UNAWARE, USER_SYSTEM);
    
                        for (int k = 0; k < approvedListeners.size(); k++) {
                            ComponentName cn = approvedListeners.valueAt(k);
                            Log.v(TAG, " loadDefaultsFromConfig cn: "+cn);
                            addDefaultComponentOrPackage(cn.flattenToString());
                        }
                    }
                }
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    最终定位到config_defaultListenerAccessPackages配置。
    vendor\partner_gms\overlay\GmsConfigOverlayCommon\res\values\config.xml

    <string name="config_defaultListenerAccessPackages" translatable="false">com.tblenovo.launcher:com.google.android.projection.gearhead</string>
    
    • 1
    流程

    1、SystemServer.startOtherServices
    NotificationManagerService.init
    NotificationManagerService.loadPolicyFile

        protected void loadPolicyFile() {
            if (DBG) Slog.d(TAG, "loadPolicyFile");
            if(mPolicyFile != null ){
                if (mPolicyFile.getBaseFile() != null){
                    Slog.d(TAG, "loadPolicyFile: "+mPolicyFile.getBaseFile().getAbsolutePath());
                }
            }
            synchronized (mPolicyFile) {
                InputStream infile = null;
                try {
                    infile = mPolicyFile.openRead();
                    readPolicyXml(infile, false /*forRestore*/, UserHandle.USER_ALL);
                } catch (FileNotFoundException e) {
                    // No data yet
                    // Load default managed services approvals
                    loadDefaultApprovedServices(USER_SYSTEM);//加载默认配置
                    allowDefaultApprovedServices(USER_SYSTEM);//默认配置bind并缓存
                } catch (IOException e) {
                    Log.wtf(TAG, "Unable to read notification policy", e);
                } catch (NumberFormatException e) {
                    Log.wtf(TAG, "Unable to parse notification policy", e);
                } catch (XmlPullParserException e) {
                    Log.wtf(TAG, "Unable to parse notification policy", e);
                } finally {
                    IoUtils.closeQuietly(infile);
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    //文件不存在时加载默认值,文件存在时加载文件。文件路径如下
    final File systemDir = new File(Environment.getDataDirectory(), "system");
    new File(systemDir, "notification_policy.xml"), "notification-policy"),
    
    • 1
    • 2
    • 3
  • 相关阅读:
    C# 串口接收1次数据会进入2次串口接收事件serialPort1_DataReceived,第2次进入时串口缓冲区为空
    分类预测 | Matlab特征分类预测全家桶(BP/SVM/ELM/RF/LSTM/BiLSTM/GRU/CNN)
    问题 A: 求最长公共子串(串)
    SystemC入门学习-第8章 测试平台的编写
    LeetCode刷题系列 -- 921. 使括号有效的最少添加
    Java Reflect 反射
    Oracle EBS Interface/API(42) -会计账户组合交叉验证规则标准API和客制化API
    四数之和 - 力扣中等
    Java中加减乘除的性能和位运算的性能比较
    NDepend v2022.2.1.9665 专业版
  • 原文地址:https://blog.csdn.net/a396604593/article/details/128025161