summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMakoto Onuki <omakoto@google.com>2016-06-30 21:55:18 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-06-30 21:55:18 +0000
commit20a9ca93117eeaa197db7632b1e95b51aae4f2ef (patch)
treecd94190dcf731c6dda9619047e1d2e692bd33d9d
parentf38d4bb413eb36bed211d06094f6da2eccdc5905 (diff)
parent60efbf25865ae395548c38be42b856e6ede22f7d (diff)
Merge \"Start shortcuts as if publisher apps did using PendingIntent\" into nyc-mr1-dev
am: 60efbf2586 Change-Id: If43a09cd1580edb318404f56459b8557b69b7d5a
-rw-r--r--core/java/android/app/ActivityManagerInternal.java9
-rw-r--r--core/java/android/content/pm/ILauncherApps.aidl2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java27
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java43
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java12
5 files changed, 84 insertions, 9 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 33ae553fb57f..6dd14fd263e3 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -19,7 +19,9 @@ package android.app;
import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.IIntentSender;
+import android.content.Intent;
import android.content.res.Configuration;
+import android.os.Bundle;
import android.os.IBinder;
import android.service.voice.IVoiceInteractionSession;
@@ -161,4 +163,11 @@ public abstract class ActivityManagerInternal {
*/
public abstract void updatePersistentConfigurationForUser(@NonNull Configuration values,
int userId);
+
+ /**
+ * Create an {@link IIntentSender} to start an activity, as if {@code packageName} on
+ * user {@code userId} created it.
+ */
+ public abstract IIntentSender getActivityIntentSenderAsPackage(String packageName,
+ int userId, int requestCode, Intent intent, int flags, Bundle bOptions);
}
diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl
index 430c7e706b64..c19e6382775a 100644
--- a/core/java/android/content/pm/ILauncherApps.aidl
+++ b/core/java/android/content/pm/ILauncherApps.aidl
@@ -51,7 +51,7 @@ interface ILauncherApps {
in List shortcutIds, in ComponentName componentName, int flags, in UserHandle user);
void pinShortcuts(String callingPackage, String packageName, in List<String> shortcutIds,
in UserHandle user);
- boolean startShortcut(String callingPackage, String packageName, String id,
+ void startShortcut(String callingPackage, String packageName, String id,
in Rect sourceBounds, in Bundle startActivityOptions, int userId);
int getShortcutIconResId(String callingPackage, String packageName, String id,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ae9492fd3b22..e5579e29c208 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -21724,6 +21724,33 @@ public final class ActivityManagerService extends ActivityManagerNative
updateConfigurationLocked(values, null, false, true, userId);
}
}
+
+ @Override
+ public IIntentSender getActivityIntentSenderAsPackage(
+ String packageName, int userId, int requestCode, Intent intent,
+ int flags, Bundle bOptions) {
+ String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
+ mContext.getContentResolver()) : null;
+
+ // UID of the package on user userId.
+ // "= 0" is needed because otherwise catch(RemoteException) would make it look like
+ // packageUid may not be initialized.
+ int packageUid = 0;
+ try {
+ packageUid = AppGlobals.getPackageManager().getPackageUid(
+ packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
+ } catch (RemoteException e) {
+ // Shouldn't happen.
+ }
+
+ synchronized (ActivityManagerService.this) {
+ return getIntentSenderLocked(
+ ActivityManager.INTENT_SENDER_ACTIVITY, packageName, packageUid,
+ UserHandle.getUserId(packageUid), /*token*/ null, /*resultWho*/ null,
+ requestCode, new Intent[] {intent}, new String[]{resolvedType},
+ flags, bOptions);
+ }
+ }
}
private final class SleepTokenImpl extends SleepToken {
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 46da60764e7e..03d5645f7e5d 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -19,9 +19,13 @@ package com.android.server.pm;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
+import android.app.ActivityManagerInternal;
+import android.app.ActivityManagerNative;
import android.app.AppGlobals;
+import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
+import android.content.IIntentSender;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -98,6 +102,7 @@ public class LauncherAppsService extends SystemService {
private final Context mContext;
private final PackageManager mPm;
private final UserManager mUm;
+ private final ActivityManagerInternal mActivityManagerInternal;
private final ShortcutServiceInternal mShortcutServiceInternal;
private final PackageCallbackList<IOnAppsChangedListener> mListeners
= new PackageCallbackList<IOnAppsChangedListener>();
@@ -110,6 +115,8 @@ public class LauncherAppsService extends SystemService {
mContext = context;
mPm = mContext.getPackageManager();
mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ mActivityManagerInternal = Preconditions.checkNotNull(
+ LocalServices.getService(ActivityManagerInternal.class));
mShortcutServiceInternal = Preconditions.checkNotNull(
LocalServices.getService(ShortcutServiceInternal.class));
mShortcutServiceInternal.addListener(mPackageMonitor);
@@ -432,7 +439,7 @@ public class LauncherAppsService extends SystemService {
}
@Override
- public boolean startShortcut(String callingPackage, String packageName, String shortcutId,
+ public void startShortcut(String callingPackage, String packageName, String shortcutId,
Rect sourceBounds, Bundle startActivityOptions, int userId) {
verifyCallingPackage(callingPackage);
ensureInUserProfiles(userId, "Cannot start activity for unrelated profile " + userId);
@@ -451,20 +458,40 @@ public class LauncherAppsService extends SystemService {
final Intent intent = mShortcutServiceInternal.createShortcutIntent(getCallingUserId(),
callingPackage, packageName, shortcutId, userId);
if (intent == null) {
- return false;
+ return;
}
// Note the target activity doesn't have to be exported.
- intent.setSourceBounds(sourceBounds);
prepareIntentForLaunch(intent, sourceBounds);
- final long ident = Binder.clearCallingIdentity();
+ startShortcutIntentAsPublisher(
+ intent, packageName, startActivityOptions, userId);
+ }
+
+ @VisibleForTesting
+ protected void startShortcutIntentAsPublisher(@NonNull Intent intent,
+ @NonNull String publisherPackage, Bundle startActivityOptions, int userId) {
+
try {
- mContext.startActivityAsUser(intent, startActivityOptions, UserHandle.of(userId));
- } finally {
- Binder.restoreCallingIdentity(ident);
+ final IIntentSender intentSender;
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ intentSender = mActivityManagerInternal.getActivityIntentSenderAsPackage(
+ publisherPackage, userId, /* requestCode= */ 0,
+ intent, PendingIntent.FLAG_ONE_SHOT,
+ /* options= */ startActivityOptions);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+
+ // Negative result means a failure.
+ ActivityManagerNative.getDefault().sendIntentSender(
+ intentSender, 0, null, null, null, null, null);
+
+ } catch (RemoteException e) {
+ return;
}
- return true;
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 7cf03af23d05..b6084d5a1387 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -37,6 +37,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.UserIdInt;
import android.app.Activity;
+import android.app.ActivityManagerInternal;
import android.app.IUidObserver;
import android.app.usage.UsageStatsManagerInternal;
import android.content.BroadcastReceiver;
@@ -466,6 +467,13 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
void injectRestoreCallingIdentity(long token) {
mInjectedCallingUid = (int) token;
}
+
+ @Override
+ protected void startShortcutIntentAsPublisher(@NonNull Intent intent,
+ @NonNull String publisherPackage, Bundle startActivityOptions, int userId) {
+ // Just forward to startActivityAsUser() during unit tests.
+ mContext.startActivityAsUser(intent, startActivityOptions, UserHandle.of(userId));
+ }
}
protected class LauncherAppsTestable extends LauncherApps {
@@ -518,6 +526,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
protected PackageManagerInternal mMockPackageManagerInternal;
protected UserManager mMockUserManager;
protected UsageStatsManagerInternal mMockUsageStatsManagerInternal;
+ protected ActivityManagerInternal mMockActivityManagerInternal;
protected static final String CALLING_PACKAGE_1 = "com.android.test.1";
protected static final int CALLING_UID_1 = 10001;
@@ -616,11 +625,14 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
mMockPackageManagerInternal = mock(PackageManagerInternal.class);
mMockUserManager = mock(UserManager.class);
mMockUsageStatsManagerInternal = mock(UsageStatsManagerInternal.class);
+ mMockActivityManagerInternal = mock(ActivityManagerInternal.class);
LocalServices.removeServiceForTest(PackageManagerInternal.class);
LocalServices.addService(PackageManagerInternal.class, mMockPackageManagerInternal);
LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
LocalServices.addService(UsageStatsManagerInternal.class, mMockUsageStatsManagerInternal);
+ LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+ LocalServices.addService(ActivityManagerInternal.class, mMockActivityManagerInternal);
// Prepare injection values.