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 守护进程等)。




你可能感兴趣的:(connect)