zoukankan      html  css  js  c++  java
  • USB充电插拔与USB Debugging connect提示

    在 packages/apps/Settings/src/com/android/settings/DevelopmentSettings.java 找到关于 USB Debug Enable 的代码:

    1 Settings.Secure.putInt(getContentResolver(), Settings.Secure.ADB_ENABLED,  0 );  
    Settings.Secure.putInt(getContentResolver(), Settings.Secure.ADB_ENABLED, 0);
    

      别处将根据其值动态变化做出相应动作如状态栏消息提示。

    void  observe() {  
        ContentResolver resolver = mContext.getContentResolver();  
        resolver.registerContentObserver(Settings.Secure.getUriFor(  
                Settings.Secure.ADB_ENABLED), false ,  this );  
        update();  
    }  
      
    @Override   public   void  onChange( boolean  selfChange) {  
        update();  
    }  
      
    public   void  update() {  
        ContentResolver resolver = mContext.getContentResolver();  
        mAdbEnabled = Settings.Secure.getInt(resolver,  
                    Settings.Secure.ADB_ENABLED, 0 ) !=  0 ;  
        updateAdbNotification();  
    }  
    
            void observe() {
                ContentResolver resolver = mContext.getContentResolver();
                resolver.registerContentObserver(Settings.Secure.getUriFor(
                        Settings.Secure.ADB_ENABLED), false, this);
                update();
            }
            @Override public void onChange(boolean selfChange) {
                update();
            }
            public void update() {
                ContentResolver resolver = mContext.getContentResolver();
                mAdbEnabled = Settings.Secure.getInt(resolver,
                            Settings.Secure.ADB_ENABLED, 0) != 0;
                updateAdbNotification();
            }
    

      

    当激活时,在状态栏中给出通知提示:

    notificationManager.notify(  
                                com.android.internal .R. string .adb_active_notification_title,  
                                mAdbNotification);  
    

      

    notificationManager.notify(
                                com.android.internal.R.string.adb_active_notification_title,
                                mAdbNotification);
    

      

    知的内容在资源字符串(英文)在字符串资源文件 frameworks/base/core/res/res/values/strings.xml 中, 定义如下:

    <!-- Title of notification shown when ADB is actively connected to the phone. -->   
    < string   name = "adbactivenotificationtitle" > USB debugging connected </ string >   
    <!-- Message of notification shown when ADB is actively connected to the phone. -->   
    < string   name = "adbactivenotificationmessage" > A computer is connected to your phone. </ string >   
    

      

    <!-- Title of notification shown when ADB is actively connected to the phone. -->
    <string name="adbactivenotificationtitle">USB debugging connected</string>
    <!-- Message of notification shown when ADB is actively connected to the phone. -->
    <string name="adbactivenotificationmessage">A computer is connected to your phone.</string>
    

      

    改变该 Settings 值将通过如下方式影响到实际使用:

    在文件中 frameworks/base/services/java/com/android/server/SystemServer.java

    private   class  AdbSettingsObserver  extends  ContentObserver {  
            public  AdbSettingsObserver() {  
                super ( null );  
            }  
            @Override   
            public   void  onChange( boolean  selfChange) {  
                boolean  enableAdb = (Settings.Secure.getInt(mContentResolver,  
                    Settings.Secure.ADB_ENABLED, 0 ) >  0 );  
                // setting this secure property will start or stop adbd   
               SystemProperties.set("persist.service.adb.enable" , enableAdb ?  "1"  :  "0" );  
            }  
    }  
    

      

    private class AdbSettingsObserver extends ContentObserver {
            public AdbSettingsObserver() {
                super(null);
            }
            @Override
            public void onChange(boolean selfChange) {
                boolean enableAdb = (Settings.Secure.getInt(mContentResolver,
                    Settings.Secure.ADB_ENABLED, 0) > 0);
                // setting this secure property will start or stop adbd
               SystemProperties.set("persist.service.adb.enable", enableAdb ? "1" : "0");
            }
    }
    

      

    可见,当设置系统属性 persist.service.adb.enable 的值时,将影响到 adbd 守护进程相应动作 ( 停止和开启 ) ,这将影响到是否查看 log 等供开发者使用的 adb 功能。

    Bug 案例分析:

    private   void  updateAdbNotification() {  
            Log.d(TAG, "2. mBatteryPlugged=" +mBatteryPlugged);  
      
    if  (mAdbEnabled && mBatteryPlugged == BatteryManager.BATTERYPLUGGEDUSB) {  
      
              Log.d(TAG, "adb enabled, Battery Plugged usb" );  
      
             if  ( "0" .equals(SystemProperties.get( "persist.adb.notify" ))) {  
      
             Log.d(TAG, "return directly" );  
      
            return ;  
    }             
     if  (!mAdbNotificationShown) {  
                                    //…省略部分代码   
      
                        mAdbNotificationShown = true ;  
                        notificationManager.notify(  
                                com.android.internal.R.string.adb_active_notification_title,  
                                mAdbNotification);  
                    }  
                }  
                  
            } else   if  (mAdbNotificationShown) {  
                //…省略部分代码   
                    mAdbNotificationShown = false ;  
                    notificationManager.cancel(  
                            com.android.internal.R.string.adb_active_notification_title);  
                }  
            }  
        }  
    

      

    private void updateAdbNotification() {  
            Log.d(TAG, "2. mBatteryPlugged="+mBatteryPlugged);  
    if (mAdbEnabled && mBatteryPlugged == BatteryManager.BATTERYPLUGGEDUSB) {  
              Log.d(TAG, "adb enabled, Battery Plugged usb");  
             if ("0".equals(SystemProperties.get("persist.adb.notify"))) {  
             Log.d(TAG, "return directly");  
            return;  
    }             
     if (!mAdbNotificationShown) {  
                                    //…省略部分代码  
                        mAdbNotificationShown = true;  
                        notificationManager.notify(  
                                com.android.internal.R.string.adb_active_notification_title,  
                                mAdbNotification);  
                    }  
                }  
                  
            } else if (mAdbNotificationShown) {  
                //…省略部分代码  
                    mAdbNotificationShown = false;  
                    notificationManager.cancel(  
                            com.android.internal.R.string.adb_active_notification_title);  
                }  
            }  
        }  
    

      

    症状:当插上 USB 线与 PC 相连再拔掉时,才显示“ USB Debugging connected ”

    分析:通过上述介绍的代码搜索,只有 NotificationManagerService.java 才会出现此提示,也就是说只要当监测到用户修改Settings 中的设置值时和接收到 intent (即 usb 插拔充电)时才会调用 updateAdbNotification() 函数:

    D/NotificationService( 1557):  mBatteryPlugged = 1   
    D/NotificationService( 1557): 2. mBatteryPlugged = 1   
    D/NotificationService( 1557): mBatteryPlugged = 1   
    D/NotificationService( 1557): 2. mBatteryPlugged = 1   
    D/NotificationService( 1557): mBatteryPlugged = 2   
    D/NotificationService( 1557): 2. mBatteryPlugged = 2   
    D/NotificationService( 1557): adb enabled, Battery Plugged usb  
    D/NotificationService( 1557): adb show notification  
    D/NotificationService( 1557): mBatteryPlugged = 0   
    D/NotificationService( 1557): 2. mBatteryPlugged = 0   
    D/NotificationService( 1557): adb cancel notification  
    D/NotificationService( 1557): mBatteryPlugged = 0   
    D/NotificationService( 1557): 2. mBatteryPlugged = 0   
    

      

    D/NotificationService( 1557): mBatteryPlugged=1
    D/NotificationService( 1557): 2. mBatteryPlugged=1
    D/NotificationService( 1557): mBatteryPlugged=1
    D/NotificationService( 1557): 2. mBatteryPlugged=1
    D/NotificationService( 1557): mBatteryPlugged=2
    D/NotificationService( 1557): 2. mBatteryPlugged=2
    D/NotificationService( 1557): adb enabled, Battery Plugged usb
    D/NotificationService( 1557): adb show notification
    D/NotificationService( 1557): mBatteryPlugged=0
    D/NotificationService( 1557): 2. mBatteryPlugged=0
    D/NotificationService( 1557): adb cancel notification
    D/NotificationService( 1557): mBatteryPlugged=0
    D/NotificationService( 1557): 2. mBatteryPlugged=0
    

      

    结合 log 看出, mBatteryPlugged 在usb线连上时 为 1 (即 BATTERY_PLUGGED_AC ,不是2即BatteryManager.BATTERY_PLUGGED_USB )而不能进入,在拔掉瞬间为 2 ,则发出提示;在拔掉之后为0。

    mBatteryPlugged 的值来自于 Intent :

    mBatteryPlugged = intent.getIntExtra( "plugged" ,  0 );  
                    updateAdbNotification();  
    

      

    mBatteryPlugged = intent.getIntExtra("plugged", 0);
                    updateAdbNotification();
    

      

    它发起于下面代码(见文件 frameworks/base/services/java/com/android/server/ BatteryService.java )

    private  synchronized final  void  update() {  
        native_update();//JNI层去读取各种值   
      
        boolean logOutlier = false ;  
        long  dischargeDuration = 0;  
          
        mBatteryLevelCritical = mBatteryLevel <= CRITICAL_BATTERY_LEVEL;  
        if  (mAcOnline) {  
            mPlugType = BatteryManager.BATTERY_PLUGGED_AC;  
        } else   if  (mUsbOnline) {  
            mPlugType = BatteryManager.BATTERY_PLUGGED_USB;  
        } else  {  
            mPlugType = BATTERY_PLUGGED_NONE;  
        }  
    

      

        private synchronized final void update() {
            native_update();//JNI层去读取各种值
            boolean logOutlier = false;
            long dischargeDuration = 0;
            
            mBatteryLevelCritical = mBatteryLevel <= CRITICAL_BATTERY_LEVEL;
            if (mAcOnline) {
                mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
            } else if (mUsbOnline) {
                mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
            } else {
                mPlugType = BATTERY_PLUGGED_NONE;
            }
    

      

    在文件中 com_android_server_BatteryService.cpp 中,函数:

    static   void  android_server_BatteryService_update(JNIEnv* env, jobject obj)  
    

      

    static void android_server_BatteryService_update(JNIEnv* env, jobject obj)  
    

      

    会从 sys 系统下读取需要的值:

    #define AC_ONLINE_PATH "/sys/class/power_supply/ac/online"   
    #define USB_ONLINE_PATH "/sys/class/power_supply/usb/online"   
    #define BATTERY_STATUS_PATH "/sys/class/power_supply/battery/status"   
    #define BATTERY_HEALTH_PATH "/sys/class/power_supply/battery/health"   
    #define BATTERY_PRESENT_PATH "/sys/class/power_supply/battery/present"   
    #define BATTERY_CAPACITY_PATH "/sys/class/power_supply/battery/capacity"   
    #define BATTERY_VOLTAGE_PATH "/sys/class/power_supply/battery/batt_vol"   
    #define BATTERY_TEMPERATURE_PATH "/sys/class/power_supply/battery/batt_temp"   
    #define BATTERY_TECHNOLOGY_PATH "/sys/class/power_supply/battery/technology"   
    

      

    #define AC_ONLINE_PATH "/sys/class/power_supply/ac/online"
    #define USB_ONLINE_PATH "/sys/class/power_supply/usb/online"
    #define BATTERY_STATUS_PATH "/sys/class/power_supply/battery/status"
    #define BATTERY_HEALTH_PATH "/sys/class/power_supply/battery/health"
    #define BATTERY_PRESENT_PATH "/sys/class/power_supply/battery/present"
    #define BATTERY_CAPACITY_PATH "/sys/class/power_supply/battery/capacity"
    #define BATTERY_VOLTAGE_PATH "/sys/class/power_supply/battery/batt_vol"
    #define BATTERY_TEMPERATURE_PATH "/sys/class/power_supply/battery/batt_temp"
    #define BATTERY_TECHNOLOGY_PATH "/sys/class/power_supply/battery/technology"
    

      

    其中前 2 项标明了是 AC 还是 USB 充电。

    因此,问题产生在系统底层识别 usb 充电信息错误,导致错误的时刻去显示 USB Debugging connect 信息。

    总结:

    当系统的 BatteryService ( BatteryService.java )调用 JNI 层( com_android_server_BatteryService.cpp ),通过 sys 系统文件获得充电(如 usb 充电)及电池信息,然后通过 intent 发送出去。 NotificationManagerService.java 在接收到广播信息后,分析是 usb 充电则采取相应的提示信息。

    另外, NotificationManagerService 还监听着 Settings 里用户是否修改了设置的值,采取相应动作(是否更新提示信息、是否停掉或开启 adbd 守护进程等)。




  • 相关阅读:
    Python反射机制
    并发和并行的区别
    I/O模型
    python 字符串零散方法记录
    python 关于占位符格式化
    Python 十进制转二进制、八进制、十六进制
    python中str函数isdigit、isdecimal、isnumeric的区别
    文件的修改
    LF 模块三
    stackoverflow os.path.abspath and os.path.realpath
  • 原文地址:https://www.cnblogs.com/jqyp/p/2310074.html
Copyright © 2011-2022 走看看