summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Makoto Onuki <omakoto@google.com> 2018-05-01 15:50:37 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-05-01 15:50:37 +0000
commiteac8a05d19d0c29f8e4310db62d5ed41bc4773b9 (patch)
tree88f02cb22621e3e76d6a457f38ff8227eff90798
parentd53c5bb4f3b0ae6e65cd7431df646b40d9b94728 (diff)
parent1a34274336c19b50173ea60071dfc6427d40dbf6 (diff)
Merge "Propagate calling UID to AM from LauncherApps" into pi-dev
-rw-r--r--core/java/android/app/ActivityManagerInternal.java11
-rw-r--r--core/java/android/content/pm/ILauncherApps.aidl5
-rw-r--r--core/java/android/content/pm/LauncherApps.java6
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java25
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java18
-rw-r--r--services/core/java/com/android/server/am/ActivityStartController.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityStartInterceptor.java17
-rw-r--r--services/core/java/com/android/server/am/ActivityStarter.java15
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java26
9 files changed, 91 insertions, 34 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 97c9fa58622f..7338bfea9d4d 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -236,6 +236,17 @@ public abstract class ActivityManagerInternal {
int userId, Intent[] intents, Bundle bOptions);
/**
+ * Start activity {@code intent} without calling user-id check.
+ *
+ * - DO NOT call it with the calling UID cleared.
+ * - The caller must do the calling user ID check.
+ *
+ * @return error codes used by {@link IActivityManager#startActivity} and its siblings.
+ */
+ public abstract int startActivityAsUser(IApplicationThread caller, String callingPackage,
+ Intent intent, @Nullable Bundle options, int userId);
+
+ /**
* Get the procstate for the UID. The return value will be between
* {@link ActivityManager#MIN_PROCESS_STATE} and {@link ActivityManager#MAX_PROCESS_STATE}.
* Note if the UID doesn't exist, it'll return {@link ActivityManager#PROCESS_STATE_NONEXISTENT}
diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl
index ae1c2071eeca..ba7710b8ef48 100644
--- a/core/java/android/content/pm/ILauncherApps.aidl
+++ b/core/java/android/content/pm/ILauncherApps.aidl
@@ -16,6 +16,7 @@
package android.content.pm;
+import android.app.IApplicationThread;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentSender;
@@ -42,10 +43,10 @@ interface ILauncherApps {
String callingPackage, String packageName, in UserHandle user);
ActivityInfo resolveActivity(
String callingPackage, in ComponentName component, in UserHandle user);
- void startActivityAsUser(String callingPackage,
+ void startActivityAsUser(in IApplicationThread caller, String callingPackage,
in ComponentName component, in Rect sourceBounds,
in Bundle opts, in UserHandle user);
- void showAppDetailsAsUser(
+ void showAppDetailsAsUser(in IApplicationThread caller,
String callingPackage, in ComponentName component, in Rect sourceBounds,
in Bundle opts, in UserHandle user);
boolean isPackageEnabled(String callingPackage, String packageName, in UserHandle user);
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 8717601cfde0..fa423e29406a 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -548,7 +548,8 @@ public class LauncherApps {
Log.i(TAG, "StartMainActivity " + component + " " + user.getIdentifier());
}
try {
- mService.startActivityAsUser(mContext.getPackageName(),
+ mService.startActivityAsUser(mContext.getIApplicationThread(),
+ mContext.getPackageName(),
component, sourceBounds, opts, user);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
@@ -568,7 +569,8 @@ public class LauncherApps {
Rect sourceBounds, Bundle opts) {
logErrorForInvalidProfileAccess(user);
try {
- mService.showAppDetailsAsUser(mContext.getPackageName(),
+ mService.showAppDetailsAsUser(mContext.getIApplicationThread(),
+ mContext.getPackageName(),
component, sourceBounds, opts, user);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 193d3f498317..a8e63f6695d4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5049,9 +5049,20 @@ public class ActivityManagerService extends IActivityManager.Stub
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
+ return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
+ resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
+ true /*validateIncomingUser*/);
+ }
+
+ public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
+ Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
+ int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
+ boolean validateIncomingUser) {
enforceNotIsolatedCaller("startActivity");
- userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
- userId, false, ALLOW_FULL_ONLY, "startActivity", null);
+
+ userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
+ Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
+
// TODO: Switch to user app stacks here.
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
@@ -26344,6 +26355,16 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
+ public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
+ Intent intent, Bundle options, int userId) {
+ return ActivityManagerService.this.startActivityAsUser(
+ caller, callerPacakge, intent,
+ intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+ null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
+ false /*validateIncomingUser*/);
+ }
+
+ @Override
public int getUidProcessState(int uid) {
return getUidState(uid);
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 548290e4dec4..4ace68947957 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1315,10 +1315,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
return aInfo;
}
- ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId) {
- return resolveIntent(intent, resolvedType, userId, 0, Binder.getCallingUid());
- }
-
ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags,
int filterCallingUid) {
synchronized (mService) {
@@ -1330,9 +1326,19 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
|| (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
modifiedFlags |= PackageManager.MATCH_INSTANT;
}
- return mService.getPackageManagerInternalLocked().resolveIntent(
- intent, resolvedType, modifiedFlags, userId, true, filterCallingUid);
+ // In order to allow cross-profile lookup, we clear the calling identity here.
+ // Note the binder identity won't affect the result, but filterCallingUid will.
+
+ // Cross-user/profile call check are done at the entry points
+ // (e.g. AMS.startActivityAsUser).
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return mService.getPackageManagerInternalLocked().resolveIntent(
+ intent, resolvedType, modifiedFlags, userId, true, filterCallingUid);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
} finally {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java
index 31ccf3530fb9..5e29d10908ca 100644
--- a/services/core/java/com/android/server/am/ActivityStartController.java
+++ b/services/core/java/com/android/server/am/ActivityStartController.java
@@ -233,7 +233,7 @@ public class ActivityStartController {
* ensures {@code targetUserId} is a real user ID and not a special user ID such as
* {@link android.os.UserHandle#USER_ALL}, etc.
*/
- private int checkTargetUser(int targetUserId, boolean validateIncomingUser,
+ int checkTargetUser(int targetUserId, boolean validateIncomingUser,
int realCallingPid, int realCallingUid, String reason) {
if (validateIncomingUser) {
return mService.mUserController.handleIncomingUser(realCallingPid, realCallingUid,
diff --git a/services/core/java/com/android/server/am/ActivityStartInterceptor.java b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
index 5b6b50869dda..8c3ff34aa73d 100644
--- a/services/core/java/com/android/server/am/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
@@ -203,7 +203,7 @@ class ActivityStartInterceptor {
mResolvedType = null;
final UserInfo parent = mUserManager.getProfileParent(mUserId);
- mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id);
+ mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id, 0, mRealCallingUid);
mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, null /*profilerInfo*/);
return true;
}
@@ -223,9 +223,11 @@ class ActivityStartInterceptor {
final UserInfo parent = mUserManager.getProfileParent(mUserId);
if (parent != null) {
- mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id);
+ mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id, 0,
+ mRealCallingUid);
} else {
- mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, mUserId);
+ mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, mUserId, 0,
+ mRealCallingUid);
}
mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, null /*profilerInfo*/);
return true;
@@ -244,7 +246,8 @@ class ActivityStartInterceptor {
final Intent moreDetailsIntent = new Intent(Intent.ACTION_SHOW_SUSPENDED_APP_DETAILS)
.setPackage(suspendingPackage);
final String requiredPermission = Manifest.permission.SEND_SHOW_SUSPENDED_APP_DETAILS;
- final ResolveInfo resolvedInfo = mSupervisor.resolveIntent(moreDetailsIntent, null, userId);
+ final ResolveInfo resolvedInfo = mSupervisor.resolveIntent(moreDetailsIntent, null, userId,
+ 0, mRealCallingUid);
if (resolvedInfo != null && resolvedInfo.activityInfo != null
&& requiredPermission.equals(resolvedInfo.activityInfo.permission)) {
moreDetailsIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, suspendedPackage)
@@ -276,7 +279,7 @@ class ActivityStartInterceptor {
mCallingPid = mRealCallingPid;
mCallingUid = mRealCallingUid;
mResolvedType = null;
- mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, 0);
+ mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, mUserId, 0, mRealCallingUid);
mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, null /*profilerInfo*/);
return true;
}
@@ -309,7 +312,7 @@ class ActivityStartInterceptor {
}
final UserInfo parent = mUserManager.getProfileParent(mUserId);
- mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id);
+ mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id, 0, mRealCallingUid);
mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, null /*profilerInfo*/);
return true;
}
@@ -362,7 +365,7 @@ class ActivityStartInterceptor {
mCallingUid = mRealCallingUid;
mResolvedType = null;
- mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, mUserId);
+ mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, mUserId, 0, mRealCallingUid);
mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, null /*profilerInfo*/);
return true;
}
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 7ff7d9a9b6c4..fb4107cfd221 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -791,7 +791,7 @@ class ActivityStarter {
callingUid = realCallingUid;
callingPid = realCallingPid;
- rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
+ rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0, realCallingUid);
aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
null /*profilerInfo*/);
@@ -952,6 +952,9 @@ class ActivityStarter {
mSupervisor.getActivityMetricsLogger().notifyActivityLaunching();
boolean componentSpecified = intent.getComponent() != null;
+ final int realCallingPid = Binder.getCallingPid();
+ final int realCallingUid = Binder.getCallingUid();
+
// Save a copy in case ephemeral needs it
final Intent ephemeralIntent = new Intent(intent);
// Don't modify the client's object!
@@ -969,7 +972,8 @@ class ActivityStarter {
componentSpecified = false;
}
- ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
+ ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
+ 0 /* matchFlags */, realCallingUid);
if (rInfo == null) {
UserInfo userInfo = mSupervisor.getUserInfo(userId);
if (userInfo != null && userInfo.isManagedProfile()) {
@@ -991,7 +995,7 @@ class ActivityStarter {
rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- Binder.getCallingUid());
+ realCallingUid);
}
}
}
@@ -999,8 +1003,6 @@ class ActivityStarter {
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
synchronized (mService) {
- final int realCallingPid = Binder.getCallingPid();
- final int realCallingUid = Binder.getCallingUid();
int callingPid;
if (callingUid >= 0) {
callingPid = -1;
@@ -1073,7 +1075,8 @@ class ActivityStarter {
callingUid = Binder.getCallingUid();
callingPid = Binder.getCallingPid();
componentSpecified = true;
- rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId);
+ rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,
+ 0 /* matchFlags */, realCallingUid);
aInfo = rInfo != null ? rInfo.activityInfo : null;
if (aInfo != null) {
aInfo = mService.getActivityInfoForUser(aInfo, userId);
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 595de9e35a7f..feac8e6a4509 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -21,6 +21,7 @@ import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AppGlobals;
+import android.app.IApplicationThread;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -560,7 +561,7 @@ public class LauncherAppsService extends SystemService {
}
@Override
- public void startActivityAsUser(String callingPackage,
+ public void startActivityAsUser(IApplicationThread caller, String callingPackage,
ComponentName component, Rect sourceBounds,
Bundle opts, UserHandle user) throws RemoteException {
if (!canAccessProfile(user.getIdentifier(), "Cannot start activity")) {
@@ -574,6 +575,8 @@ public class LauncherAppsService extends SystemService {
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
launchIntent.setPackage(component.getPackageName());
+ boolean canLaunch = false;
+
final int callingUid = injectBinderCallingUid();
long ident = Binder.clearCallingIdentity();
try {
@@ -604,35 +607,42 @@ public class LauncherAppsService extends SystemService {
// this component so ok to launch.
launchIntent.setPackage(null);
launchIntent.setComponent(component);
- mContext.startActivityAsUser(launchIntent, opts, user);
- return;
+ canLaunch = true;
+ break;
}
}
- throw new SecurityException("Attempt to launch activity without "
- + " category Intent.CATEGORY_LAUNCHER " + component);
+ if (!canLaunch) {
+ throw new SecurityException("Attempt to launch activity without "
+ + " category Intent.CATEGORY_LAUNCHER " + component);
+ }
} finally {
Binder.restoreCallingIdentity(ident);
}
+ mActivityManagerInternal.startActivityAsUser(caller, callingPackage,
+ launchIntent, opts, user.getIdentifier());
}
@Override
- public void showAppDetailsAsUser(String callingPackage, ComponentName component,
+ public void showAppDetailsAsUser(IApplicationThread caller,
+ String callingPackage, ComponentName component,
Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException {
if (!canAccessProfile(user.getIdentifier(), "Cannot show app details")) {
return;
}
+ final Intent intent;
long ident = Binder.clearCallingIdentity();
try {
String packageName = component.getPackageName();
- Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
+ intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", packageName, null));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setSourceBounds(sourceBounds);
- mContext.startActivityAsUser(intent, opts, user);
} finally {
Binder.restoreCallingIdentity(ident);
}
+ mActivityManagerInternal.startActivityAsUser(caller, callingPackage,
+ intent, opts, user.getIdentifier());
}
/** Checks if user is a profile of or same as listeningUser.