Merge \\"Start shortcuts as if publisher apps did using PendingIntent\\" into nyc-mr1-dev am: 60efbf2586

am: 20a9ca9311

Change-Id: I3bb569bb53b95176dc5e3b19f4122cf75511ac1e
This commit is contained in:
Makoto Onuki
2016-06-30 22:02:51 +00:00
committed by android-build-merger
5 changed files with 84 additions and 9 deletions

View File

@@ -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);
}

View File

@@ -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,

View File

@@ -21748,6 +21748,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 {

View File

@@ -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

View File

@@ -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.