diff options
author | 2025-02-16 17:14:27 -0800 | |
---|---|---|
committer | 2025-02-16 17:14:27 -0800 | |
commit | 38ebd31fdb4447be861083666eb7a23f495394b2 (patch) | |
tree | 9235e75ee2a8f66b92f891b10a81a7f105d5b852 /service | |
parent | b3c7ae6054307d23deb1307632a81b052c8bc564 (diff) | |
parent | 42c4b557335340bd03a6214f92d4bcad3ea897ab (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.java | 70 |
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()); + }); + } } |