Merge "Fix BroadcastReceiver leaked during user switching" into tm-dev

This commit is contained in:
Felipe Leme
2022-04-06 14:41:24 +00:00
committed by Android (Google) Code Review
5 changed files with 55 additions and 13 deletions

View File

@@ -2132,15 +2132,19 @@ class StorageManagerService extends IStorageManager.Stub
} }
} }
PackageMonitor monitor = new PackageMonitor() { if (mPackageMonitorsForUser.get(userId) == null) {
PackageMonitor monitor = new PackageMonitor() {
@Override @Override
public void onPackageRemoved(String packageName, int uid) { public void onPackageRemoved(String packageName, int uid) {
updateLegacyStorageApps(packageName, uid, false); updateLegacyStorageApps(packageName, uid, false);
} }
}; };
// TODO(b/149391976): Use different handler? // TODO(b/149391976): Use different handler?
monitor.register(mContext, user, true, mHandler); monitor.register(mContext, user, true, mHandler);
mPackageMonitorsForUser.put(userId, monitor); mPackageMonitorsForUser.put(userId, monitor);
} else {
Slog.w(TAG, "PackageMonitor is already registered for: " + userId);
}
} }
private static long getLastAccessTime(AppOpsManager manager, private static long getLastAccessTime(AppOpsManager manager,

View File

@@ -133,6 +133,10 @@ class BluetoothRouteProvider {
mIntentFilter, null, null); mIntentFilter, null, null);
} }
public void stop() {
mContext.unregisterReceiver(mBroadcastReceiver);
}
/** /**
* Transfers to a given bluetooth route. * Transfers to a given bluetooth route.
* The dedicated BT device with the route would be activated. * The dedicated BT device with the route would be activated.

View File

@@ -1150,6 +1150,8 @@ class MediaRouter2ServiceImpl {
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, userRecord + ": Disposed"); Slog.d(TAG, userRecord + ": Disposed");
} }
userRecord.mHandler.sendMessage(
obtainMessage(UserHandler::stop, userRecord.mHandler));
mUserRecords.remove(userRecord.mUserId); mUserRecords.remove(userRecord.mUserId);
// Note: User already stopped (by switchUser) so no need to send stop message here. // Note: User already stopped (by switchUser) so no need to send stop message here.
} }
@@ -1330,6 +1332,7 @@ class MediaRouter2ServiceImpl {
private void start() { private void start() {
if (!mRunning) { if (!mRunning) {
mRunning = true; mRunning = true;
mSystemProvider.start();
mWatcher.start(); mWatcher.start();
} }
} }
@@ -1338,6 +1341,7 @@ class MediaRouter2ServiceImpl {
if (mRunning) { if (mRunning) {
mRunning = false; mRunning = false;
mWatcher.stop(); // also stops all providers mWatcher.stop(); // also stops all providers
mSystemProvider.stop();
} }
} }

View File

@@ -71,6 +71,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
private final IAudioService mAudioService; private final IAudioService mAudioService;
private final Handler mHandler; private final Handler mHandler;
private final Context mContext; private final Context mContext;
private final UserHandle mUser;
private final BluetoothRouteProvider mBtRouteProvider; private final BluetoothRouteProvider mBtRouteProvider;
private static ComponentName sComponentName = new ComponentName( private static ComponentName sComponentName = new ComponentName(
@@ -86,6 +87,9 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo(); final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo();
int mDeviceVolume; int mDeviceVolume;
private final AudioManagerBroadcastReceiver mAudioReceiver =
new AudioManagerBroadcastReceiver();
private final Object mRequestLock = new Object(); private final Object mRequestLock = new Object();
@GuardedBy("mRequestLock") @GuardedBy("mRequestLock")
private volatile SessionCreationRequest mPendingSessionCreationRequest; private volatile SessionCreationRequest mPendingSessionCreationRequest;
@@ -108,6 +112,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
mIsSystemRouteProvider = true; mIsSystemRouteProvider = true;
mContext = context; mContext = context;
mUser = user;
mHandler = new Handler(Looper.getMainLooper()); mHandler = new Handler(Looper.getMainLooper());
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
@@ -128,21 +133,33 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
} }
}); });
updateSessionInfosIfNeeded(); updateSessionInfosIfNeeded();
}
public void start() {
IntentFilter intentFilter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION); IntentFilter intentFilter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION);
intentFilter.addAction(AudioManager.STREAM_DEVICES_CHANGED_ACTION); intentFilter.addAction(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
mContext.registerReceiverAsUser(new AudioManagerBroadcastReceiver(), user, mContext.registerReceiverAsUser(mAudioReceiver, mUser,
intentFilter, null, null); intentFilter, null, null);
if (mBtRouteProvider != null) { if (mBtRouteProvider != null) {
mHandler.post(() -> { mHandler.post(() -> {
mBtRouteProvider.start(user); mBtRouteProvider.start(mUser);
notifyProviderState(); notifyProviderState();
}); });
} }
updateVolume(); updateVolume();
} }
public void stop() {
mContext.unregisterReceiver(mAudioReceiver);
if (mBtRouteProvider != null) {
mHandler.post(() -> {
mBtRouteProvider.stop();
notifyProviderState();
});
}
}
@Override @Override
public void setCallback(Callback callback) { public void setCallback(Callback callback) {
super.setCallback(callback); super.setCallback(callback);

View File

@@ -618,10 +618,17 @@ public class DataManager {
IntentFilter intentFilter = new IntentFilter(); IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED); intentFilter.addAction(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED);
intentFilter.addAction(SmsApplication.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL); intentFilter.addAction(SmsApplication.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL);
BroadcastReceiver broadcastReceiver = new PerUserBroadcastReceiver(userId);
mBroadcastReceivers.put(userId, broadcastReceiver); if (mBroadcastReceivers.get(userId) == null) {
mContext.registerReceiverAsUser( BroadcastReceiver broadcastReceiver = new PerUserBroadcastReceiver(userId);
broadcastReceiver, UserHandle.of(userId), intentFilter, null, null); mBroadcastReceivers.put(userId, broadcastReceiver);
mContext.registerReceiverAsUser(
broadcastReceiver, UserHandle.of(userId), intentFilter, null, null);
} else {
// Stopped was not called on this user before setup is called again. This
// could happen during consecutive rapid user switching.
if (DEBUG) Log.d(TAG, "PerUserBroadcastReceiver was registered for: " + userId);
}
ContentObserver contactsContentObserver = new ContactsContentObserver( ContentObserver contactsContentObserver = new ContactsContentObserver(
BackgroundThread.getHandler()); BackgroundThread.getHandler());
@@ -639,9 +646,15 @@ public class DataManager {
// Should never occur for local calls. // Should never occur for local calls.
} }
PackageMonitor packageMonitor = new PerUserPackageMonitor(); if (mPackageMonitors.get(userId) == null) {
packageMonitor.register(mContext, null, UserHandle.of(userId), true); PackageMonitor packageMonitor = new PerUserPackageMonitor();
mPackageMonitors.put(userId, packageMonitor); packageMonitor.register(mContext, null, UserHandle.of(userId), true);
mPackageMonitors.put(userId, packageMonitor);
} else {
// Stopped was not called on this user before setup is called again. This
// could happen during consecutive rapid user switching.
if (DEBUG) Log.d(TAG, "PerUserPackageMonitor was registered for: " + userId);
}
if (userId == UserHandle.USER_SYSTEM) { if (userId == UserHandle.USER_SYSTEM) {
// The call log and MMS/SMS messages are shared across user profiles. So only need // The call log and MMS/SMS messages are shared across user profiles. So only need