Loading services/core/java/com/android/server/wm/ActivityRecord.java +1 −1 Original line number Diff line number Diff line Loading @@ -2782,7 +2782,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A reparent(newTaskFrag, position); } private boolean isHomeIntent(Intent intent) { static boolean isHomeIntent(Intent intent) { return ACTION_MAIN.equals(intent.getAction()) && (intent.hasCategory(CATEGORY_HOME) || intent.hasCategory(CATEGORY_SECONDARY_HOME)) Loading services/core/java/com/android/server/wm/ActivityStartInterceptor.java +94 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,9 @@ import static android.app.PendingIntent.FLAG_ONE_SHOT; import static android.app.admin.DevicePolicyManager.EXTRA_RESTRICTION; import static android.app.admin.DevicePolicyManager.POLICY_SUSPEND_PACKAGES; import static android.content.Context.KEYGUARD_SERVICE; import static android.content.Intent.ACTION_MAIN; import static android.content.Intent.CATEGORY_HOME; import static android.content.Intent.CATEGORY_SECONDARY_HOME; import static android.content.Intent.EXTRA_INTENT; import static android.content.Intent.EXTRA_PACKAGE_NAME; import static android.content.Intent.EXTRA_TASK_ID; Loading @@ -39,6 +42,7 @@ import android.app.ActivityOptions; import android.app.KeyguardManager; import android.app.TaskInfo; import android.app.admin.DevicePolicyManagerInternal; import android.content.ComponentName; import android.content.Context; import android.content.IIntentSender; import android.content.Intent; Loading @@ -52,6 +56,7 @@ import android.os.Bundle; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; Loading @@ -63,6 +68,7 @@ import com.android.server.LocalServices; import com.android.server.am.ActivityManagerService; import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptResult; /** * A class that contains activity intercepting logic for {@link ActivityStarter#startActivityLocked} * It's initialized via setStates and interception occurs via the intercept method. Loading @@ -71,6 +77,7 @@ import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptResult * is no guarantee that other system services are already present. */ class ActivityStartInterceptor { private static final String TAG = "ActivityStartInterceptor"; private final ActivityTaskManagerService mService; private final ActivityTaskSupervisor mSupervisor; Loading Loading @@ -106,6 +113,11 @@ class ActivityStartInterceptor { Task mInTask; ActivityOptions mActivityOptions; /** * Whether the component is specified originally in the given Intent. */ boolean mComponentSpecified; ActivityStartInterceptor( ActivityTaskManagerService service, ActivityTaskSupervisor supervisor) { this(service, supervisor, service.mRootWindowContainer, service.mContext); Loading Loading @@ -144,6 +156,13 @@ class ActivityStartInterceptor { return new IntentSender(target); } // TODO: consolidate this method with the one below since this is used for test only. boolean intercept(Intent intent, ResolveInfo rInfo, ActivityInfo aInfo, String resolvedType, Task inTask, int callingPid, int callingUid, ActivityOptions activityOptions) { return intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, callingUid, activityOptions, false); } /** * Intercept the launch intent based on various signals. If an interception happened the * internal variables get assigned and need to be read explicitly by the caller. Loading @@ -151,7 +170,8 @@ class ActivityStartInterceptor { * @return true if an interception occurred */ boolean intercept(Intent intent, ResolveInfo rInfo, ActivityInfo aInfo, String resolvedType, Task inTask, int callingPid, int callingUid, ActivityOptions activityOptions) { Task inTask, int callingPid, int callingUid, ActivityOptions activityOptions, boolean componentSpecified) { mUserManager = UserManager.get(mServiceContext); mIntent = intent; Loading @@ -162,6 +182,7 @@ class ActivityStartInterceptor { mResolvedType = resolvedType; mInTask = inTask; mActivityOptions = activityOptions; mComponentSpecified = componentSpecified; if (interceptQuietProfileIfNeeded()) { // If work profile is turned off, skip the work challenge since the profile can only Loading @@ -184,6 +205,10 @@ class ActivityStartInterceptor { if (interceptLockedManagedProfileIfNeeded()) { return true; } if (interceptHomeIfNeeded()) { // Replace primary home intents if the home intent is not in the correct format. return true; } final SparseArray<ActivityInterceptorCallback> callbacks = mService.getActivityInterceptorCallbacks(); Loading Loading @@ -403,6 +428,74 @@ class ActivityStartInterceptor { return true; } private boolean interceptHomeIfNeeded() { if (mService.mRootWindowContainer == null) { return false; } boolean intercepted = false; if (!ACTION_MAIN.equals(mIntent.getAction()) || (!mIntent.hasCategory(CATEGORY_HOME) && !mIntent.hasCategory(CATEGORY_SECONDARY_HOME))) { // not a home intent return false; } if (mComponentSpecified) { final ComponentName homeComponent = mIntent.getComponent(); final Intent homeIntent = mService.getHomeIntent(); final ActivityInfo aInfo = mService.mRootWindowContainer.resolveHomeActivity( mUserId, homeIntent); if (!aInfo.getComponentName().equals(homeComponent)) { // Do nothing if the intent is not for the default home component. return false; } } if (!ActivityRecord.isHomeIntent(mIntent) || mComponentSpecified) { // This is not a standard home intent, make it so if possible. normalizeHomeIntent(); intercepted = true; } if (intercepted) { mCallingPid = mRealCallingPid; mCallingUid = mRealCallingUid; mResolvedType = null; mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, mUserId, /* flags= */ 0, mRealCallingUid); mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, /*profilerInfo=*/ null); } return intercepted; } private void normalizeHomeIntent() { Slog.w(TAG, "The home Intent is not correctly formatted"); if (mIntent.getCategories().size() > 1) { Slog.d(TAG, "Purge home intent categories"); boolean isSecondaryHome = false; final Object[] categories = mIntent.getCategories().toArray(); for (int i = categories.length - 1; i >= 0; i--) { final String category = (String) categories[i]; if (CATEGORY_SECONDARY_HOME.equals(category)) { isSecondaryHome = true; } mIntent.removeCategory(category); } mIntent.addCategory(isSecondaryHome ? CATEGORY_SECONDARY_HOME : CATEGORY_HOME); } if (mIntent.getType() != null || mIntent.getData() != null) { Slog.d(TAG, "Purge home intent data/type"); mIntent.setType(null); } if (mComponentSpecified) { Slog.d(TAG, "Purge home intent component, " + mIntent.getComponent()); mIntent.setComponent(null); } mIntent.addFlags(FLAG_ACTIVITY_NEW_TASK); } /** * Called when an activity is successfully launched. */ Loading services/core/java/com/android/server/wm/ActivityStarter.java +1 −1 Original line number Diff line number Diff line Loading @@ -1057,7 +1057,7 @@ class ActivityStarter { mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage, callingFeatureId); if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, callingUid, checkedOptions)) { callingUid, checkedOptions, request.componentSpecified)) { // activity start was intercepted, e.g. because the target user is currently in quiet // mode (turn off work) or the target application is suspended intent = mInterceptor.mIntent; Loading services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -228,6 +228,18 @@ public class ActivityStartInterceptorTest { return dialogInfo; } @Test public void testInterceptIncorrectHomeIntent() { // Create a non-standard home intent final Intent homeIntent = new Intent(Intent.ACTION_MAIN); homeIntent.addCategory(Intent.CATEGORY_HOME); homeIntent.addCategory(Intent.CATEGORY_LAUNCHER); // Ensure the intent is intercepted and normalized to standard home intent. assertTrue(mInterceptor.intercept(homeIntent, null, mAInfo, null, null, 0, 0, null, false)); assertTrue(ActivityRecord.isHomeIntent(homeIntent)); } @Test public void testInterceptLockTaskModeViolationPackage() { when(mLockTaskController.isActivityAllowed( Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +1 −1 Original line number Diff line number Diff line Loading @@ -2782,7 +2782,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A reparent(newTaskFrag, position); } private boolean isHomeIntent(Intent intent) { static boolean isHomeIntent(Intent intent) { return ACTION_MAIN.equals(intent.getAction()) && (intent.hasCategory(CATEGORY_HOME) || intent.hasCategory(CATEGORY_SECONDARY_HOME)) Loading
services/core/java/com/android/server/wm/ActivityStartInterceptor.java +94 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,9 @@ import static android.app.PendingIntent.FLAG_ONE_SHOT; import static android.app.admin.DevicePolicyManager.EXTRA_RESTRICTION; import static android.app.admin.DevicePolicyManager.POLICY_SUSPEND_PACKAGES; import static android.content.Context.KEYGUARD_SERVICE; import static android.content.Intent.ACTION_MAIN; import static android.content.Intent.CATEGORY_HOME; import static android.content.Intent.CATEGORY_SECONDARY_HOME; import static android.content.Intent.EXTRA_INTENT; import static android.content.Intent.EXTRA_PACKAGE_NAME; import static android.content.Intent.EXTRA_TASK_ID; Loading @@ -39,6 +42,7 @@ import android.app.ActivityOptions; import android.app.KeyguardManager; import android.app.TaskInfo; import android.app.admin.DevicePolicyManagerInternal; import android.content.ComponentName; import android.content.Context; import android.content.IIntentSender; import android.content.Intent; Loading @@ -52,6 +56,7 @@ import android.os.Bundle; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; Loading @@ -63,6 +68,7 @@ import com.android.server.LocalServices; import com.android.server.am.ActivityManagerService; import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptResult; /** * A class that contains activity intercepting logic for {@link ActivityStarter#startActivityLocked} * It's initialized via setStates and interception occurs via the intercept method. Loading @@ -71,6 +77,7 @@ import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptResult * is no guarantee that other system services are already present. */ class ActivityStartInterceptor { private static final String TAG = "ActivityStartInterceptor"; private final ActivityTaskManagerService mService; private final ActivityTaskSupervisor mSupervisor; Loading Loading @@ -106,6 +113,11 @@ class ActivityStartInterceptor { Task mInTask; ActivityOptions mActivityOptions; /** * Whether the component is specified originally in the given Intent. */ boolean mComponentSpecified; ActivityStartInterceptor( ActivityTaskManagerService service, ActivityTaskSupervisor supervisor) { this(service, supervisor, service.mRootWindowContainer, service.mContext); Loading Loading @@ -144,6 +156,13 @@ class ActivityStartInterceptor { return new IntentSender(target); } // TODO: consolidate this method with the one below since this is used for test only. boolean intercept(Intent intent, ResolveInfo rInfo, ActivityInfo aInfo, String resolvedType, Task inTask, int callingPid, int callingUid, ActivityOptions activityOptions) { return intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, callingUid, activityOptions, false); } /** * Intercept the launch intent based on various signals. If an interception happened the * internal variables get assigned and need to be read explicitly by the caller. Loading @@ -151,7 +170,8 @@ class ActivityStartInterceptor { * @return true if an interception occurred */ boolean intercept(Intent intent, ResolveInfo rInfo, ActivityInfo aInfo, String resolvedType, Task inTask, int callingPid, int callingUid, ActivityOptions activityOptions) { Task inTask, int callingPid, int callingUid, ActivityOptions activityOptions, boolean componentSpecified) { mUserManager = UserManager.get(mServiceContext); mIntent = intent; Loading @@ -162,6 +182,7 @@ class ActivityStartInterceptor { mResolvedType = resolvedType; mInTask = inTask; mActivityOptions = activityOptions; mComponentSpecified = componentSpecified; if (interceptQuietProfileIfNeeded()) { // If work profile is turned off, skip the work challenge since the profile can only Loading @@ -184,6 +205,10 @@ class ActivityStartInterceptor { if (interceptLockedManagedProfileIfNeeded()) { return true; } if (interceptHomeIfNeeded()) { // Replace primary home intents if the home intent is not in the correct format. return true; } final SparseArray<ActivityInterceptorCallback> callbacks = mService.getActivityInterceptorCallbacks(); Loading Loading @@ -403,6 +428,74 @@ class ActivityStartInterceptor { return true; } private boolean interceptHomeIfNeeded() { if (mService.mRootWindowContainer == null) { return false; } boolean intercepted = false; if (!ACTION_MAIN.equals(mIntent.getAction()) || (!mIntent.hasCategory(CATEGORY_HOME) && !mIntent.hasCategory(CATEGORY_SECONDARY_HOME))) { // not a home intent return false; } if (mComponentSpecified) { final ComponentName homeComponent = mIntent.getComponent(); final Intent homeIntent = mService.getHomeIntent(); final ActivityInfo aInfo = mService.mRootWindowContainer.resolveHomeActivity( mUserId, homeIntent); if (!aInfo.getComponentName().equals(homeComponent)) { // Do nothing if the intent is not for the default home component. return false; } } if (!ActivityRecord.isHomeIntent(mIntent) || mComponentSpecified) { // This is not a standard home intent, make it so if possible. normalizeHomeIntent(); intercepted = true; } if (intercepted) { mCallingPid = mRealCallingPid; mCallingUid = mRealCallingUid; mResolvedType = null; mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, mUserId, /* flags= */ 0, mRealCallingUid); mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, /*profilerInfo=*/ null); } return intercepted; } private void normalizeHomeIntent() { Slog.w(TAG, "The home Intent is not correctly formatted"); if (mIntent.getCategories().size() > 1) { Slog.d(TAG, "Purge home intent categories"); boolean isSecondaryHome = false; final Object[] categories = mIntent.getCategories().toArray(); for (int i = categories.length - 1; i >= 0; i--) { final String category = (String) categories[i]; if (CATEGORY_SECONDARY_HOME.equals(category)) { isSecondaryHome = true; } mIntent.removeCategory(category); } mIntent.addCategory(isSecondaryHome ? CATEGORY_SECONDARY_HOME : CATEGORY_HOME); } if (mIntent.getType() != null || mIntent.getData() != null) { Slog.d(TAG, "Purge home intent data/type"); mIntent.setType(null); } if (mComponentSpecified) { Slog.d(TAG, "Purge home intent component, " + mIntent.getComponent()); mIntent.setComponent(null); } mIntent.addFlags(FLAG_ACTIVITY_NEW_TASK); } /** * Called when an activity is successfully launched. */ Loading
services/core/java/com/android/server/wm/ActivityStarter.java +1 −1 Original line number Diff line number Diff line Loading @@ -1057,7 +1057,7 @@ class ActivityStarter { mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage, callingFeatureId); if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, callingUid, checkedOptions)) { callingUid, checkedOptions, request.componentSpecified)) { // activity start was intercepted, e.g. because the target user is currently in quiet // mode (turn off work) or the target application is suspended intent = mInterceptor.mIntent; Loading
services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -228,6 +228,18 @@ public class ActivityStartInterceptorTest { return dialogInfo; } @Test public void testInterceptIncorrectHomeIntent() { // Create a non-standard home intent final Intent homeIntent = new Intent(Intent.ACTION_MAIN); homeIntent.addCategory(Intent.CATEGORY_HOME); homeIntent.addCategory(Intent.CATEGORY_LAUNCHER); // Ensure the intent is intercepted and normalized to standard home intent. assertTrue(mInterceptor.intercept(homeIntent, null, mAInfo, null, null, 0, 0, null, false)); assertTrue(ActivityRecord.isHomeIntent(homeIntent)); } @Test public void testInterceptLockTaskModeViolationPackage() { when(mLockTaskController.isActivityAllowed( Loading