Register broadcast receiver at runtime instead
Cannot find class when registering Usb connection broadcast receiver
in AndroidManifest, causing system process to crash. Switch to
register receiver at runtime when boot complete.
Fixes: 77274266
Test: Manually plug & unplug usb cable, and reboot device
Test: Verify usb_data appears in batterystats dump
Test: Verify there is no crash log
Change-Id: If4a9e85aa81173ad6d8cb6ce28cc030814c520a5
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 03dd77f..514ff76 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -93,7 +93,6 @@
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);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 89f6156..5da3874 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -21,10 +21,13 @@
import android.app.ActivityManager;
import android.bluetooth.BluetoothActivityEnergyInfo;
import android.bluetooth.UidTraffic;
+import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.database.ContentObserver;
+import android.hardware.usb.UsbManager;
import android.net.ConnectivityManager;
import android.net.NetworkStats;
import android.net.Uri;
@@ -766,7 +769,10 @@
int mCameraOnNesting;
StopwatchTimer mCameraOnTimer;
- int mUsbDataState; // 0: unknown, 1: disconnected, 2: connected
+ private static final int USB_DATA_UNKNOWN = 0;
+ private static final int USB_DATA_DISCONNECTED = 1;
+ private static final int USB_DATA_CONNECTED = 2;
+ int mUsbDataState = USB_DATA_UNKNOWN;
int mGpsSignalQualityBin = -1;
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
@@ -5241,8 +5247,30 @@
}
}
- public void noteUsbConnectionStateLocked(boolean connected) {
- int newState = connected ? 2 : 1;
+ private void registerUsbStateReceiver(Context context) {
+ final IntentFilter usbStateFilter = new IntentFilter();
+ usbStateFilter.addAction(UsbManager.ACTION_USB_STATE);
+ context.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final boolean state = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
+ synchronized (BatteryStatsImpl.this) {
+ noteUsbConnectionStateLocked(state);
+ }
+ }
+ }, usbStateFilter);
+ synchronized (this) {
+ if (mUsbDataState == USB_DATA_UNKNOWN) {
+ final Intent usbState = context.registerReceiver(null, usbStateFilter);
+ final boolean initState = usbState != null && usbState.getBooleanExtra(
+ UsbManager.USB_CONNECTED, false);
+ noteUsbConnectionStateLocked(initState);
+ }
+ }
+ }
+
+ private void noteUsbConnectionStateLocked(boolean connected) {
+ int newState = connected ? USB_DATA_CONNECTED : USB_DATA_DISCONNECTED;
if (mUsbDataState != newState) {
mUsbDataState = newState;
if (connected) {
@@ -13218,6 +13246,7 @@
public void systemServicesReady(Context context) {
mConstants.startObserving(context.getContentResolver());
+ registerUsbStateReceiver(context);
}
@VisibleForTesting
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 04c4130..b7b5f23 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4253,16 +4253,6 @@
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" />