OSDN Git Service

Track USB data link in batterystats
authorMike Ma <yanmin@google.com>
Sun, 25 Mar 2018 09:32:35 +0000 (02:32 -0700)
committerMike Ma <yanmin@google.com>
Tue, 27 Mar 2018 19:05:48 +0000 (12:05 -0700)
Record USB data link state in addition to plug & charging state, since
modern USB controller can keep USB data link connected with minimum
current. Device is not acutally charging at those times.
Test: manual
Fixes: 76209292

Change-Id: I0710d547399a631d594488a524682ccc32a25ce6

core/java/android/os/BatteryStats.java
core/java/com/android/internal/app/IBatteryStats.aidl
core/java/com/android/internal/os/BatteryStatsImpl.java
core/res/AndroidManifest.xml
services/core/java/com/android/server/am/BatteryStatsService.java

index f528d63..6ebb102 100644 (file)
@@ -1585,6 +1585,7 @@ public abstract class BatteryStats implements Parcelable {
         public static final int STATE2_CAMERA_FLAG = 1<<21;
         public static final int STATE2_BLUETOOTH_SCAN_FLAG = 1 << 20;
         public static final int STATE2_CELLULAR_HIGH_TX_POWER_FLAG = 1 << 19;
+        public static final int STATE2_USB_DATA_LINK_FLAG = 1 << 18;
 
         public static final int MOST_INTERESTING_STATES2 =
                 STATE2_POWER_SAVE_FLAG | STATE2_WIFI_ON_FLAG | STATE2_DEVICE_IDLE_MASK
@@ -2363,8 +2364,7 @@ public abstract class BatteryStats implements Parcelable {
                 SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES),
     };
 
-    public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS
-            = new BitDescription[] {
+    public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS = new BitDescription[] {
         new BitDescription(HistoryItem.STATE2_POWER_SAVE_FLAG, "power_save", "ps"),
         new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"),
         new BitDescription(HistoryItem.STATE2_WIFI_RUNNING_FLAG, "wifi_running", "Ww"),
@@ -2375,6 +2375,7 @@ public abstract class BatteryStats implements Parcelable {
                 new String[] { "off", "light", "full", "???" },
                 new String[] { "off", "light", "full", "???" }),
         new BitDescription(HistoryItem.STATE2_CHARGING_FLAG, "charging", "ch"),
+        new BitDescription(HistoryItem.STATE2_USB_DATA_LINK_FLAG, "usb_data", "Ud"),
         new BitDescription(HistoryItem.STATE2_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"),
         new BitDescription(HistoryItem.STATE2_BLUETOOTH_ON_FLAG, "bluetooth", "b"),
         new BitDescription(HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK,
index 514ff76..03dd77f 100644 (file)
@@ -93,6 +93,7 @@ interface IBatteryStats {
     void noteVibratorOff(int uid);
     void noteGpsChanged(in WorkSource oldSource, in WorkSource newSource);
     void noteGpsSignalQuality(int signalLevel);
+    void noteUsbConnectionState(boolean connected);
     void noteScreenState(int state);
     void noteScreenBrightness(int brightness);
     void noteUserActivity(int uid, int event);
index 3c150c1..9993a76 100644 (file)
@@ -767,6 +767,8 @@ public class BatteryStatsImpl extends BatteryStats {
     int mCameraOnNesting;
     StopwatchTimer mCameraOnTimer;
 
+    int mUsbDataState; // 0: unknown, 1: disconnected, 2: connected
+
     int mGpsSignalQualityBin = -1;
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
     protected final StopwatchTimer[] mGpsSignalQualityTimer =
@@ -5240,6 +5242,19 @@ public class BatteryStatsImpl extends BatteryStats {
         }
     }
 
+    public void noteUsbConnectionStateLocked(boolean connected) {
+        int newState = connected ? 2 : 1;
+        if (mUsbDataState != newState) {
+            mUsbDataState = newState;
+            if (connected) {
+                mHistoryCur.states2 |= HistoryItem.STATE2_USB_DATA_LINK_FLAG;
+            } else {
+                mHistoryCur.states2 &= ~HistoryItem.STATE2_USB_DATA_LINK_FLAG;
+            }
+            addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+        }
+    }
+
     void stopAllPhoneSignalStrengthTimersLocked(int except) {
         final long elapsedRealtime = mClocks.elapsedRealtime();
         for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
index c4d3667..3fb52dc 100644 (file)
                   android:exported="false">
         </receiver>
 
+        <receiver android:name="com.android.server.am.BatteryStatsService$UsbConnectionReceiver"
+                  android:exported="false">
+            <intent-filter>
+                <action android:name="android.intent.action.BOOT_COMPLETED" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.hardware.usb.action.USB_STATE" />
+            </intent-filter>
+        </receiver>
+
         <service android:name="android.hardware.location.GeofenceHardwareService"
             android:permission="android.permission.LOCATION_HARDWARE"
             android:exported="false" />
index 3c49ece..46873d5 100644 (file)
@@ -18,9 +18,13 @@ package com.android.server.am;
 
 import android.app.ActivityManager;
 import android.bluetooth.BluetoothActivityEnergyInfo;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.hardware.usb.UsbManager;
 import android.net.wifi.WifiActivityEnergyInfo;
 import android.os.PowerManager.ServiceType;
 import android.os.PowerSaveState;
@@ -34,6 +38,7 @@ import android.os.ParcelFileDescriptor;
 import android.os.ParcelFormatException;
 import android.os.PowerManagerInternal;
 import android.os.Process;
+import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -70,7 +75,6 @@ import java.nio.CharBuffer;
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CodingErrorAction;
 import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
@@ -684,6 +688,13 @@ public final class BatteryStatsService extends IBatteryStats.Stub
         }
     }
 
+    public void noteUsbConnectionState(boolean connected) {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteUsbConnectionStateLocked(connected);
+        }
+    }
+
     public void notePhoneSignalStrength(SignalStrength signalStrength) {
         enforceCallingPermission();
         synchronized (mStats) {
@@ -1116,6 +1127,35 @@ public final class BatteryStatsService extends IBatteryStats.Stub
                 Binder.getCallingPid(), Binder.getCallingUid(), null);
     }
 
+    public final static class UsbConnectionReceiver extends BroadcastReceiver {
+        private static final String TAG = UsbConnectionReceiver.class.getSimpleName();
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
+                final Intent usbState = context.registerReceiver(null, new IntentFilter(UsbManager.ACTION_USB_STATE));
+                if (usbState != null) {
+                    handleUsbState(usbState);
+                }
+            } else if (UsbManager.ACTION_USB_STATE.equals(action)) {
+                handleUsbState(intent);
+            }
+        }
+        private void handleUsbState(Intent intent) {
+            IBatteryStats bs = getService();
+            if (bs == null) {
+                Slog.w(TAG, "Could not access batterystats");
+                return;
+            }
+            boolean connected = intent.getExtras().getBoolean(UsbManager.USB_CONNECTED);
+            try {
+                bs.noteUsbConnectionState(connected);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Could not access batterystats: ", e);
+            }
+        }
+    }
+
     final class WakeupReasonThread extends Thread {
         private static final int MAX_REASON_SIZE = 512;
         private CharsetDecoder mDecoder;