summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
author DC Xu <dcxu@google.com> 2025-02-16 17:14:27 -0800
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2025-02-16 17:14:27 -0800
commit38ebd31fdb4447be861083666eb7a23f495394b2 (patch)
tree9235e75ee2a8f66b92f891b10a81a7f105d5b852 /service
parentb3c7ae6054307d23deb1307632a81b052c8bc564 (diff)
parent42c4b557335340bd03a6214f92d4bcad3ea897ab (diff)
Merge "Disable components of bluetooth package in PackageManager on HAL crash" into main
Diffstat (limited to 'service')
-rw-r--r--service/src/com/android/server/bluetooth/BluetoothManagerService.java70
1 files changed, 69 insertions, 1 deletions
diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java
index 0cfdfea987..20d8dbf073 100644
--- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java
+++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java
@@ -1344,7 +1344,15 @@ class BluetoothManagerService {
Log.e(TAG, "Unknown service disconnected: " + name);
return;
}
- mHandler.sendEmptyMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
+
+ if (Flags.setComponentAvailableFix()) {
+ mHandler
+ .obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED,
+ componentName.getPackageName())
+ .sendToTarget();
+ } else {
+ mHandler.sendEmptyMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
+ }
}
}
@@ -1577,6 +1585,10 @@ class BluetoothManagerService {
case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED:
Log.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED");
+ if (Flags.setComponentAvailableFix()) {
+ disableBluetoothComponents((String) msg.obj);
+ }
+
if (!resetAdapter()) {
break;
}
@@ -2452,4 +2464,60 @@ class BluetoothManagerService {
return pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
|| pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
}
+
+ /**
+ * In case of a Bluetooth crash, mark it's enabled components as non longer available to
+ * trigger the PACKAGE_CHANGED intent. This should not be needed in a normal shutdown as the
+ * Bluetooth clean its components on its own
+ */
+ private void disableBluetoothComponents(String packageName) {
+ PackageManager pm = mContext.getPackageManager();
+ PackageInfo packageInfo = null;
+
+ try {
+ packageInfo = pm.getPackageInfo(
+ packageName,
+ PackageManager.GET_SERVICES |
+ PackageManager.GET_ACTIVITIES |
+ PackageManager.GET_RECEIVERS |
+ PackageManager.GET_PROVIDERS);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Package not found: " + packageName, e);
+ return;
+ }
+
+ // Refer to updateOppLauncherComponentState()
+ List<String> baseBluetoothOppActivities = List.of(
+ "com.android.bluetooth.opp.BluetoothOppLauncherActivity",
+ "com.android.bluetooth.opp.BluetoothOppBtEnableActivity",
+ "com.android.bluetooth.opp.BluetoothOppBtEnablingActivity",
+ "com.android.bluetooth.opp.BluetoothOppBtErrorActivity"
+ );
+
+ disableComponents(pm, packageInfo.activities, packageName, baseBluetoothOppActivities);
+ disableComponents(pm, packageInfo.services, packageName, null);
+ disableComponents(pm, packageInfo.receivers, packageName, null);
+ disableComponents(pm, packageInfo.providers, packageName, null);
+ }
+
+ private <T extends android.content.pm.ComponentInfo> void disableComponents(
+ PackageManager pm, T[] components, String packageName, List<String> componentsToKeep) {
+ if (components == null) {
+ return;
+ }
+
+ Arrays.stream(components)
+ .filter(componentInfo -> !componentInfo.enabled)
+ .map(componentInfo -> new ComponentName(packageName, componentInfo.name))
+ .filter(componentName ->
+ (componentsToKeep == null ||
+ !componentsToKeep.contains(componentName.getClassName())))
+ .forEach(componentName -> {
+ pm.setComponentEnabledSetting(
+ componentName,
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP);
+ Log.i(TAG, "Disabled component: " + componentName.flattenToString());
+ });
+ }
}