Loading services/core/java/com/android/server/tv/TvInputManagerService.java +112 −37 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; import android.graphics.Rect; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiDeviceInfo; Loading Loading @@ -76,6 +77,7 @@ import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Pair; Loading Loading @@ -133,6 +135,7 @@ public final class TvInputManagerService extends SystemService { private final Context mContext; private final TvInputHardwareManager mTvInputHardwareManager; private final UserManager mUserManager; // A global lock. private final Object mLock = new Object(); Loading @@ -140,6 +143,9 @@ public final class TvInputManagerService extends SystemService { // ID of the current user. @GuardedBy("mLock") private int mCurrentUserId = UserHandle.USER_SYSTEM; // IDs of the running managed profiles. Their parent user ID should be mCurrentUserId. @GuardedBy("mLock") private final Set<Integer> mRunningManagedProfile = new HashSet<>(); // A map from user id to UserState. @GuardedBy("mLock") Loading @@ -163,6 +169,7 @@ public final class TvInputManagerService extends SystemService { mActivityManager = (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE); mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); synchronized (mLock) { getOrCreateUserStateLocked(mCurrentUserId); Loading Loading @@ -270,6 +277,8 @@ public final class TvInputManagerService extends SystemService { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_SWITCHED); intentFilter.addAction(Intent.ACTION_USER_REMOVED); intentFilter.addAction(Intent.ACTION_USER_STARTED); intentFilter.addAction(Intent.ACTION_USER_STOPPED); mContext.registerReceiverAsUser(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading @@ -278,6 +287,12 @@ public final class TvInputManagerService extends SystemService { switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); } else if (Intent.ACTION_USER_REMOVED.equals(action)) { removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); } else if (Intent.ACTION_USER_STARTED.equals(action)) { int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); startUser(userId); } else if (Intent.ACTION_USER_STOPPED.equals(action)) { int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); stopUser(userId); } } }, UserHandle.ALL, intentFilter, null, null); Loading Loading @@ -423,13 +438,73 @@ public final class TvInputManagerService extends SystemService { } } private void startUser(int userId) { synchronized (mLock) { if (userId == mCurrentUserId || mRunningManagedProfile.contains(userId)) { // user already started return; } UserInfo userInfo = mUserManager.getUserInfo(userId); UserInfo parentInfo = mUserManager.getProfileParent(userId); if (userInfo.isManagedProfile() && parentInfo != null && parentInfo.id == mCurrentUserId) { // only the children of the current user can be started in background startProfileLocked(userId); } } } private void stopUser(int userId) { if (userId == mCurrentUserId) { switchUser(ActivityManager.getCurrentUser()); return; } releaseSessionOfUserLocked(userId); unbindServiceOfUserLocked(userId); mRunningManagedProfile.remove(userId); } private void startProfileLocked(int userId) { buildTvInputListLocked(userId, null); buildTvContentRatingSystemListLocked(userId); mRunningManagedProfile.add(userId); } private void switchUser(int userId) { synchronized (mLock) { if (mCurrentUserId == userId) { return; } if (mUserStates.contains(mCurrentUserId)) { UserState userState = getUserStateLocked(mCurrentUserId); UserInfo userInfo = mUserManager.getUserInfo(userId); if (userInfo.isManagedProfile()) { Slog.w(TAG, "cannot switch to a managed profile!"); return; } for (int runningId : mRunningManagedProfile) { releaseSessionOfUserLocked(runningId); unbindServiceOfUserLocked(runningId); } mRunningManagedProfile.clear(); releaseSessionOfUserLocked(mCurrentUserId); unbindServiceOfUserLocked(mCurrentUserId); mCurrentUserId = userId; buildTvInputListLocked(userId, null); buildTvContentRatingSystemListLocked(userId); mWatchLogHandler.obtainMessage(WatchLogHandler.MSG_SWITCH_CONTENT_RESOLVER, getContentResolverForUser(userId)).sendToTarget(); } } @GuardedBy("mLock") private void releaseSessionOfUserLocked(int userId) { UserState userState = getUserStateLocked(userId); if (userState == null) { return; } List<SessionState> sessionStatesToRelease = new ArrayList<>(); for (SessionState sessionState : userState.sessionStateMap.values()) { if (sessionState.session != null && !sessionState.isRecordingSession) { Loading @@ -444,7 +519,14 @@ public final class TvInputManagerService extends SystemService { } clearSessionAndNotifyClientLocked(sessionState); } } @GuardedBy("mLock") private void unbindServiceOfUserLocked(int userId) { UserState userState = getUserStateLocked(userId); if (userState == null) { return; } for (Iterator<ComponentName> it = userState.serviceStateMap.keySet().iterator(); it.hasNext(); ) { ComponentName component = it.next(); Loading @@ -463,15 +545,6 @@ public final class TvInputManagerService extends SystemService { } } mCurrentUserId = userId; getOrCreateUserStateLocked(userId); buildTvInputListLocked(userId, null); buildTvContentRatingSystemListLocked(userId); mWatchLogHandler.obtainMessage(WatchLogHandler.MSG_SWITCH_CONTENT_RESOLVER, getContentResolverForUser(userId)).sendToTarget(); } } @GuardedBy("mLock") private void clearSessionAndNotifyClientLocked(SessionState state) { if (state.client != null) { Loading Loading @@ -537,6 +610,7 @@ public final class TvInputManagerService extends SystemService { userState.mCallbacks.kill(); userState.mainSessionToken = null; mRunningManagedProfile.remove(userId); mUserStates.remove(userId); if (userId == mCurrentUserId) { Loading Loading @@ -635,7 +709,7 @@ public final class TvInputManagerService extends SystemService { } boolean shouldBind; if (userId == mCurrentUserId) { if (userId == mCurrentUserId || mRunningManagedProfile.contains(userId)) { shouldBind = !serviceState.sessionTokens.isEmpty() || serviceState.isHardware; } else { // For a non-current user, Loading Loading @@ -1295,9 +1369,10 @@ public final class TvInputManagerService extends SystemService { String uniqueSessionId = UUID.randomUUID().toString(); try { synchronized (mLock) { if (userId != mCurrentUserId && !isRecordingSession) { // A non-recording session of a background (non-current) user // should not be created. if (userId != mCurrentUserId && !mRunningManagedProfile.contains(userId) && !isRecordingSession) { // Only current user and its running managed profiles can create // non-recording sessions. // Let the client get onConnectionFailed callback for this case. sendSessionTokenToClientLocked(client, inputId, null, null, seq); return; Loading Loading
services/core/java/com/android/server/tv/TvInputManagerService.java +112 −37 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; import android.graphics.Rect; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiDeviceInfo; Loading Loading @@ -76,6 +77,7 @@ import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Pair; Loading Loading @@ -133,6 +135,7 @@ public final class TvInputManagerService extends SystemService { private final Context mContext; private final TvInputHardwareManager mTvInputHardwareManager; private final UserManager mUserManager; // A global lock. private final Object mLock = new Object(); Loading @@ -140,6 +143,9 @@ public final class TvInputManagerService extends SystemService { // ID of the current user. @GuardedBy("mLock") private int mCurrentUserId = UserHandle.USER_SYSTEM; // IDs of the running managed profiles. Their parent user ID should be mCurrentUserId. @GuardedBy("mLock") private final Set<Integer> mRunningManagedProfile = new HashSet<>(); // A map from user id to UserState. @GuardedBy("mLock") Loading @@ -163,6 +169,7 @@ public final class TvInputManagerService extends SystemService { mActivityManager = (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE); mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); synchronized (mLock) { getOrCreateUserStateLocked(mCurrentUserId); Loading Loading @@ -270,6 +277,8 @@ public final class TvInputManagerService extends SystemService { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_SWITCHED); intentFilter.addAction(Intent.ACTION_USER_REMOVED); intentFilter.addAction(Intent.ACTION_USER_STARTED); intentFilter.addAction(Intent.ACTION_USER_STOPPED); mContext.registerReceiverAsUser(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading @@ -278,6 +287,12 @@ public final class TvInputManagerService extends SystemService { switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); } else if (Intent.ACTION_USER_REMOVED.equals(action)) { removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); } else if (Intent.ACTION_USER_STARTED.equals(action)) { int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); startUser(userId); } else if (Intent.ACTION_USER_STOPPED.equals(action)) { int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); stopUser(userId); } } }, UserHandle.ALL, intentFilter, null, null); Loading Loading @@ -423,13 +438,73 @@ public final class TvInputManagerService extends SystemService { } } private void startUser(int userId) { synchronized (mLock) { if (userId == mCurrentUserId || mRunningManagedProfile.contains(userId)) { // user already started return; } UserInfo userInfo = mUserManager.getUserInfo(userId); UserInfo parentInfo = mUserManager.getProfileParent(userId); if (userInfo.isManagedProfile() && parentInfo != null && parentInfo.id == mCurrentUserId) { // only the children of the current user can be started in background startProfileLocked(userId); } } } private void stopUser(int userId) { if (userId == mCurrentUserId) { switchUser(ActivityManager.getCurrentUser()); return; } releaseSessionOfUserLocked(userId); unbindServiceOfUserLocked(userId); mRunningManagedProfile.remove(userId); } private void startProfileLocked(int userId) { buildTvInputListLocked(userId, null); buildTvContentRatingSystemListLocked(userId); mRunningManagedProfile.add(userId); } private void switchUser(int userId) { synchronized (mLock) { if (mCurrentUserId == userId) { return; } if (mUserStates.contains(mCurrentUserId)) { UserState userState = getUserStateLocked(mCurrentUserId); UserInfo userInfo = mUserManager.getUserInfo(userId); if (userInfo.isManagedProfile()) { Slog.w(TAG, "cannot switch to a managed profile!"); return; } for (int runningId : mRunningManagedProfile) { releaseSessionOfUserLocked(runningId); unbindServiceOfUserLocked(runningId); } mRunningManagedProfile.clear(); releaseSessionOfUserLocked(mCurrentUserId); unbindServiceOfUserLocked(mCurrentUserId); mCurrentUserId = userId; buildTvInputListLocked(userId, null); buildTvContentRatingSystemListLocked(userId); mWatchLogHandler.obtainMessage(WatchLogHandler.MSG_SWITCH_CONTENT_RESOLVER, getContentResolverForUser(userId)).sendToTarget(); } } @GuardedBy("mLock") private void releaseSessionOfUserLocked(int userId) { UserState userState = getUserStateLocked(userId); if (userState == null) { return; } List<SessionState> sessionStatesToRelease = new ArrayList<>(); for (SessionState sessionState : userState.sessionStateMap.values()) { if (sessionState.session != null && !sessionState.isRecordingSession) { Loading @@ -444,7 +519,14 @@ public final class TvInputManagerService extends SystemService { } clearSessionAndNotifyClientLocked(sessionState); } } @GuardedBy("mLock") private void unbindServiceOfUserLocked(int userId) { UserState userState = getUserStateLocked(userId); if (userState == null) { return; } for (Iterator<ComponentName> it = userState.serviceStateMap.keySet().iterator(); it.hasNext(); ) { ComponentName component = it.next(); Loading @@ -463,15 +545,6 @@ public final class TvInputManagerService extends SystemService { } } mCurrentUserId = userId; getOrCreateUserStateLocked(userId); buildTvInputListLocked(userId, null); buildTvContentRatingSystemListLocked(userId); mWatchLogHandler.obtainMessage(WatchLogHandler.MSG_SWITCH_CONTENT_RESOLVER, getContentResolverForUser(userId)).sendToTarget(); } } @GuardedBy("mLock") private void clearSessionAndNotifyClientLocked(SessionState state) { if (state.client != null) { Loading Loading @@ -537,6 +610,7 @@ public final class TvInputManagerService extends SystemService { userState.mCallbacks.kill(); userState.mainSessionToken = null; mRunningManagedProfile.remove(userId); mUserStates.remove(userId); if (userId == mCurrentUserId) { Loading Loading @@ -635,7 +709,7 @@ public final class TvInputManagerService extends SystemService { } boolean shouldBind; if (userId == mCurrentUserId) { if (userId == mCurrentUserId || mRunningManagedProfile.contains(userId)) { shouldBind = !serviceState.sessionTokens.isEmpty() || serviceState.isHardware; } else { // For a non-current user, Loading Loading @@ -1295,9 +1369,10 @@ public final class TvInputManagerService extends SystemService { String uniqueSessionId = UUID.randomUUID().toString(); try { synchronized (mLock) { if (userId != mCurrentUserId && !isRecordingSession) { // A non-recording session of a background (non-current) user // should not be created. if (userId != mCurrentUserId && !mRunningManagedProfile.contains(userId) && !isRecordingSession) { // Only current user and its running managed profiles can create // non-recording sessions. // Let the client get onConnectionFailed callback for this case. sendSessionTokenToClientLocked(client, inputId, null, null, seq); return; Loading