Replace user switch broadcast by user callback
Bug: 143712534
Test: atest CarServiceTest CarServiceUnitTest
Change-Id: I0bee05ba4ea6e3d283f08db8d54dee40a8617f6f
diff --git a/service/src/com/android/car/CarMediaService.java b/service/src/com/android/car/CarMediaService.java
index f3c9b79..ce8e328 100644
--- a/service/src/com/android/car/CarMediaService.java
+++ b/service/src/com/android/car/CarMediaService.java
@@ -51,6 +51,8 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.car.user.CarUserService;
+
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
@@ -86,6 +88,7 @@
private static final int AUTOPLAY_CONFIG_ADAPTIVE = 2;
private final Context mContext;
+ private final CarUserService mUserService;
private final UserManager mUserManager;
private final MediaSessionManager mMediaSessionManager;
private final MediaSessionUpdater mMediaSessionUpdater = new MediaSessionUpdater();
@@ -148,18 +151,24 @@
}
};
- private final BroadcastReceiver mUserSwitchReceiver = new BroadcastReceiver() {
+ private final CarUserService.UserCallback mUserCallback = new CarUserService.UserCallback() {
+
@Override
- public void onReceive(Context context, Intent intent) {
- mCurrentUser = ActivityManager.getCurrentUser();
+ public void onSwitchUser(int userId) {
if (Log.isLoggable(CarLog.TAG_MEDIA, Log.DEBUG)) {
- Log.d(CarLog.TAG_MEDIA, "Switched to user " + mCurrentUser);
+ Log.d(CarLog.TAG_MEDIA, "Switched to user " + userId);
}
maybeInitUser();
}
+
+ @Override
+ public void onUserLockChanged(int userId, boolean unlocked) {
+ // Do Nothing
+ }
+
};
- public CarMediaService(Context context) {
+ public CarMediaService(Context context, CarUserService userService) {
mContext = context;
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mMediaSessionManager = mContext.getSystemService(MediaSessionManager.class);
@@ -173,10 +182,8 @@
mPackageUpdateFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
mPackageUpdateFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
mPackageUpdateFilter.addDataScheme("package");
-
- IntentFilter userSwitchFilter = new IntentFilter();
- userSwitchFilter.addAction(Intent.ACTION_USER_SWITCHED);
- mContext.registerReceiver(mUserSwitchReceiver, userSwitchFilter);
+ mUserService = userService;
+ mUserService.addUserCallback(mUserCallback);
mPlayOnMediaSourceChangedConfig =
mContext.getResources().getInteger(R.integer.config_mediaSourceChangedAutoplay);
@@ -219,8 +226,8 @@
mPackageUpdateFilter, null, null);
mIsPackageUpdateReceiverRegistered = true;
- mPrimaryMediaComponent =
- isCurrentUserEphemeral() ? getDefaultMediaSource() : getLastMediaSource();
+ mPrimaryMediaComponent = isCurrentUserEphemeral() ? getDefaultMediaSource()
+ : getLastMediaSource();
mActiveUserMediaController = null;
updateMediaSessionCallbackForCurrentUser();
@@ -267,6 +274,7 @@
@Override
public void release() {
mMediaSessionUpdater.unregisterCallbacks();
+ mUserService.removeUserCallback(mUserCallback);
}
@Override
@@ -282,9 +290,8 @@
writer.println(
"\tCurrent browse service extra: " + getClassName(mActiveUserMediaController));
}
- writer.println("\tNumber of active media sessions: "
- + mMediaSessionManager.getActiveSessionsForUser(null,
- ActivityManager.getCurrentUser()).size());
+ writer.println("\tNumber of active media sessions: " + mMediaSessionManager
+ .getActiveSessionsForUser(null, ActivityManager.getCurrentUser()).size());
}
/**
@@ -674,8 +681,7 @@
Deque<String> componentNames = getComponentNameList(serialized);
componentNames.remove(componentName);
componentNames.addFirst(componentName);
- mSharedPrefs.edit().putString(key, serializeComponentNameList(componentNames))
- .apply();
+ mSharedPrefs.edit().putString(key, serializeComponentNameList(componentNames)).apply();
}
}
diff --git a/service/src/com/android/car/ICarImpl.java b/service/src/com/android/car/ICarImpl.java
index 89f14e1..f81f614 100644
--- a/service/src/com/android/car/ICarImpl.java
+++ b/service/src/com/android/car/ICarImpl.java
@@ -188,8 +188,9 @@
mCarDrivingStateService, mCarPropertyService);
mCarPackageManagerService = new CarPackageManagerService(serviceContext,
mCarUXRestrictionsService,
- mSystemActivityMonitoringService);
- mPerUserCarServiceHelper = new PerUserCarServiceHelper(serviceContext);
+ mSystemActivityMonitoringService,
+ mCarUserService);
+ mPerUserCarServiceHelper = new PerUserCarServiceHelper(serviceContext, mCarUserService);
mCarBluetoothService = new CarBluetoothService(serviceContext, mPerUserCarServiceHelper);
mCarInputService = new CarInputService(serviceContext, mHal.getInputHal());
mCarProjectionService = new CarProjectionService(
@@ -224,7 +225,7 @@
new CarConfigurationService(serviceContext, new JsonReaderImpl());
mCarLocationService = new CarLocationService(serviceContext);
mCarTrustedDeviceService = new CarTrustedDeviceService(serviceContext);
- mCarMediaService = new CarMediaService(serviceContext);
+ mCarMediaService = new CarMediaService(serviceContext, mCarUserService);
mCarBugreportManagerService = new CarBugreportManagerService(serviceContext);
if (!Build.IS_USER) {
mCarExperimentalFeatureServiceController = new CarExperimentalFeatureServiceController(
diff --git a/service/src/com/android/car/PerUserCarServiceHelper.java b/service/src/com/android/car/PerUserCarServiceHelper.java
index c72223f..a4148aa 100644
--- a/service/src/com/android/car/PerUserCarServiceHelper.java
+++ b/service/src/com/android/car/PerUserCarServiceHelper.java
@@ -17,16 +17,15 @@
package com.android.car;
import android.car.IPerUserCarService;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.UserHandle;
import android.util.Log;
+import com.android.car.user.CarUserService;
import com.android.internal.annotations.GuardedBy;
import java.io.PrintWriter;
@@ -42,22 +41,21 @@
public class PerUserCarServiceHelper implements CarServiceBase {
private static final String TAG = "PerUserCarSvcHelper";
private static boolean DBG = false;
- private Context mContext;
+ private final Context mContext;
+ private final CarUserService mUserService;
private IPerUserCarService mPerUserCarService;
// listener to call on a ServiceConnection to PerUserCarService
private List<ServiceCallback> mServiceCallbacks;
- private UserSwitchBroadcastReceiver mReceiver;
- private IntentFilter mUserSwitchFilter;
private static final String EXTRA_USER_HANDLE = "android.intent.extra.user_handle";
private final Object mServiceBindLock = new Object();
@GuardedBy("mServiceBindLock")
private boolean mBound = false;
- public PerUserCarServiceHelper(Context context) {
+ public PerUserCarServiceHelper(Context context, CarUserService userService) {
mContext = context;
mServiceCallbacks = new ArrayList<>();
- mReceiver = new UserSwitchBroadcastReceiver();
- setupUserSwitchListener();
+ mUserService = userService;
+ mUserService.addUserCallback(mUserCallback);
}
@Override
@@ -71,39 +69,24 @@
public void release() {
synchronized (mServiceBindLock) {
unbindFromPerUserCarService();
+ mUserService.removeUserCallback(mUserCallback);
}
}
- /**
- * Setting up the intent filter for
- * 2. UserSwitch events
- */
- private void setupUserSwitchListener() {
- mUserSwitchFilter = new IntentFilter();
- mUserSwitchFilter.addAction(Intent.ACTION_USER_SWITCHED);
- mContext.registerReceiver(mReceiver, mUserSwitchFilter);
- if (DBG) {
- Log.d(TAG, "UserSwitch Listener Registered");
- }
- }
+ private final CarUserService.UserCallback mUserCallback = new CarUserService.UserCallback() {
- /**
- * UserSwitchBroadcastReceiver receives broadcasts on User account switches.
- */
- public class UserSwitchBroadcastReceiver extends BroadcastReceiver {
@Override
- public void onReceive(Context context, Intent intent) {
+ public void onUserLockChanged(int userId, boolean unlocked) {
+ // Do Nothing
+ }
+
+ @Override
+ public void onSwitchUser(int userId) {
List<ServiceCallback> callbacks;
if (DBG) {
- Log.d(TAG, "User Switch Happened");
- boolean userSwitched = intent.getAction().equals(
- Intent.ACTION_USER_SWITCHED);
-
- int user = intent.getExtras().getInt(EXTRA_USER_HANDLE);
- if (userSwitched) {
- Log.d(TAG, "New User " + user);
- }
+ Log.d(TAG, "User Switch Happened. New User" + userId);
}
+
// Before unbinding, notify the callbacks about unbinding from the service
// so the callbacks can clean up their state through the binder before the service is
// killed.
@@ -120,7 +103,7 @@
// bind to the service running as the new user
bindToPerUserCarService();
}
- }
+ };
/**
* ServiceConnection to detect connecting/disconnecting to {@link PerUserCarService}
diff --git a/service/src/com/android/car/pm/CarPackageManagerService.java b/service/src/com/android/car/pm/CarPackageManagerService.java
index 085576b..9d8274f 100644
--- a/service/src/com/android/car/pm/CarPackageManagerService.java
+++ b/service/src/com/android/car/pm/CarPackageManagerService.java
@@ -65,6 +65,7 @@
import com.android.car.R;
import com.android.car.SystemActivityMonitoringService;
import com.android.car.SystemActivityMonitoringService.TopTaskInfoContainer;
+import com.android.car.user.CarUserService;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -90,6 +91,7 @@
private static final int LOG_SIZE = 20;
private final Context mContext;
+ private final CarUserService mUserService;
private final SystemActivityMonitoringService mSystemActivityMonitoringService;
private final PackageManager mPackageManager;
private final ActivityManager mActivityManager;
@@ -143,8 +145,6 @@
private final PackageParsingEventReceiver mPackageParsingEventReceiver =
new PackageParsingEventReceiver();
- private final UserSwitchedEventReceiver mUserSwitchedEventReceiver =
- new UserSwitchedEventReceiver();
// To track if the packages have been parsed for building white/black lists. If we haven't had
// received any intents (boot complete or package changed), then the white list is null leading
@@ -186,8 +186,10 @@
public CarPackageManagerService(Context context,
CarUxRestrictionsManagerService uxRestrictionsService,
- SystemActivityMonitoringService systemActivityMonitoringService) {
+ SystemActivityMonitoringService systemActivityMonitoringService,
+ CarUserService userService) {
mContext = context;
+ mUserService = userService;
mCarUxRestrictionsService = uxRestrictionsService;
mSystemActivityMonitoringService = systemActivityMonitoringService;
mPackageManager = mContext.getPackageManager();
@@ -407,7 +409,7 @@
mLock.notifyAll();
}
mContext.unregisterReceiver(mPackageParsingEventReceiver);
- mContext.unregisterReceiver(mUserSwitchedEventReceiver);
+ mUserService.removeUserCallback(mUserCallback);
mSystemActivityMonitoringService.registerActivityLaunchListener(null);
for (int i = 0; i < mUxRestrictionsListeners.size(); i++) {
UxRestrictionsListener listener = mUxRestrictionsListeners.valueAt(i);
@@ -415,12 +417,24 @@
}
}
+ private final CarUserService.UserCallback mUserCallback = new CarUserService.UserCallback() {
+
+ @Override
+ public void onUserLockChanged(int userId, boolean unlocked) {
+ // Do Nothing
+ }
+
+ @Override
+ public void onSwitchUser(int userId) {
+ mHandler.requestParsingInstalledPkgs(0);
+ }
+
+ };
+
// run from HandlerThread
private void doHandleInit() {
startAppBlockingPolicies();
- IntentFilter intent = new IntentFilter();
- intent.addAction(Intent.ACTION_USER_SWITCHED);
- mContext.registerReceiver(mUserSwitchedEventReceiver, intent);
+ mUserService.addUserCallback(mUserCallback);
IntentFilter pkgParseIntent = new IntentFilter();
for (String action : mPackageManagerActions) {
pkgParseIntent.addAction(action);
@@ -666,11 +680,10 @@
Map<String, Set<String>> configWhitelist, Map<String, Set<String>> configBlacklist) {
HashMap<String, AppBlockingPackageInfoWrapper> activityWhitelist = new HashMap<>();
- List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser(
- PackageManager.GET_SIGNATURES | PackageManager.GET_ACTIVITIES
- | PackageManager.MATCH_DIRECT_BOOT_AWARE
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- userId);
+ List<PackageInfo> packages = mPackageManager
+ .getInstalledPackagesAsUser(PackageManager.GET_SIGNATURES
+ | PackageManager.GET_ACTIVITIES | PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId);
for (PackageInfo info : packages) {
if (info.applicationInfo == null) {
continue;
@@ -747,9 +760,8 @@
// Some of the activities in this app are Distraction Optimized.
if (DBG_POLICY_CHECK) {
for (String activity : doActivities) {
- Log.d(CarLog.TAG_PACKAGE,
- "adding " + activity + " from " + info.packageName
- + " to whitelist");
+ Log.d(CarLog.TAG_PACKAGE, "adding " + activity + " from "
+ + info.packageName + " to whitelist");
}
}
activities.addAll(Arrays.asList(doActivities));
@@ -1135,7 +1147,7 @@
!= PackageManager.SIGNATURE_MATCH) {
throw new SecurityException(
"Caller " + mPackageManager.getNameForUid(Binder.getCallingUid())
- + " does not have the right signature");
+ + " does not have the right signature");
}
mCarUxRestrictionsService.setUxRChangeBroadcastEnabled(enable);
}
@@ -1404,21 +1416,6 @@
}
/**
- * Listens to the Boot intent to initiate parsing installed packages.
- */
- private class UserSwitchedEventReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent == null || intent.getAction() == null) {
- return;
- }
- if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
- mHandler.requestParsingInstalledPkgs(0);
- }
- }
- }
-
- /**
* Listens to the package install/uninstall events to know when to initiate parsing
* installed packages.
*/
diff --git a/service/src/com/android/car/user/CarUserService.java b/service/src/com/android/car/user/CarUserService.java
index 610a056..5a541e3 100644
--- a/service/src/com/android/car/user/CarUserService.java
+++ b/service/src/com/android/car/user/CarUserService.java
@@ -36,10 +36,12 @@
import android.location.LocationManager;
import android.os.Binder;
import android.os.RemoteException;
+import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.util.Log;
+import android.util.TimingsTraceLog;
import com.android.car.CarServiceBase;
import com.android.car.R;
@@ -83,7 +85,7 @@
private @UserIdInt int mLastPassengerId;
/**
* Background users that will be restarted in garage mode. This list can include the
- * current foreground user bit the current foreground user should not be restarted.
+ * current foreground user but the current foreground user should not be restarted.
*/
@GuardedBy("mLockUser")
private final ArrayList<Integer> mBackgroundUsersToRestart = new ArrayList<>();
@@ -461,12 +463,23 @@
* @param unlocked Unlocked (={@code true}) or locked (={@code false}).
*/
public void setUserLockStatus(@UserIdInt int userId, boolean unlocked) {
+ TimingsTraceLog t = new TimingsTraceLog(TAG_USER,
+ Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceBegin("onUserLockChanged-" + userId
+ + (unlocked ? "-unlocked" : "-locked"));
for (UserCallback callback : mUserCallbacks) {
+ t.traceBegin("onUserLockChanged-"
+ + callback.getClass().getSimpleName());
callback.onUserLockChanged(userId, unlocked);
+ t.traceEnd();
}
+ t.traceEnd();
+
if (!unlocked) { // nothing else to do when it is locked back.
return;
}
+
+ t.traceBegin("setUserLockStatus-UnlockTasks-" + userId);
ArrayList<Runnable> tasks = null;
synchronized (mLockUser) {
if (userId == UserHandle.USER_SYSTEM) {
@@ -502,6 +515,7 @@
r.run();
}
}
+ t.traceEnd();
}
/**
@@ -594,6 +608,9 @@
* @param userId User id of new user.
*/
public void onSwitchUser(@UserIdInt int userId) {
+ TimingsTraceLog t = new TimingsTraceLog(TAG_USER,
+ Trace.TRACE_TAG_SYSTEM_SERVER);
+ t.traceBegin("onSwitchUser-" + userId);
if (!isSystemUser(userId)) {
mCarUserManagerHelper.setLastActiveUser(userId);
}
@@ -605,8 +622,11 @@
startFirstPassenger(userId);
}
for (UserCallback callback : mUserCallbacks) {
+ t.traceBegin("onSwitchUser-" + callback.getClass().getSimpleName());
callback.onSwitchUser(userId);
+ t.traceEnd();
}
+ t.traceEnd();
}
/**