diff options
3 files changed, 43 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 056f25542294..9627c4394db7 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -105,6 +105,7 @@ import android.util.TypedXmlSerializer; import android.util.Xml; import android.view.IWindowManager; +import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; @@ -455,6 +456,8 @@ public class ShortcutService extends IShortcutService.Stub { private final boolean mIsAppSearchEnabled; + private ComponentName mChooserActivity; + static class InvalidFileFormatException extends Exception { public InvalidFileFormatException(String message, Throwable cause) { super(message, cause); @@ -1646,6 +1649,26 @@ public class ShortcutService extends IShortcutService.Stub { return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID; } + @VisibleForTesting + ComponentName injectChooserActivity() { + if (mChooserActivity == null) { + mChooserActivity = ComponentName.unflattenFromString( + mContext.getResources().getString(R.string.config_chooserActivity)); + } + return mChooserActivity; + } + + private boolean isCallerChooserActivity() { + // TODO(b/228975502): Migrate this check to a proper permission or role check + final int callingUid = injectBinderCallingUid(); + ComponentName systemChooser = injectChooserActivity(); + if (systemChooser == null) { + return false; + } + int uid = injectGetPackageUid(systemChooser.getPackageName(), UserHandle.USER_SYSTEM); + return uid == callingUid; + } + private void enforceSystemOrShell() { if (!(isCallerSystem() || isCallerShell())) { throw new SecurityException("Caller must be system or shell"); @@ -2525,7 +2548,9 @@ public class ShortcutService extends IShortcutService.Stub { IntentFilter filter, @UserIdInt int userId) { Preconditions.checkStringNotEmpty(packageName, "packageName"); Objects.requireNonNull(filter, "intentFilter"); - verifyCaller(packageName, userId); + if (!isCallerChooserActivity()) { + verifyCaller(packageName, userId); + } enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_APP_PREDICTIONS, "getShareTargets"); synchronized (mLock) { 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 a79a52c1c198..e4ee4d064724 100644 --- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java @@ -538,6 +538,11 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } @Override + ComponentName injectChooserActivity() { + return mInjectedChooserActivity; + } + + @Override void wtf(String message, Throwable th) { // During tests, WTF is fatal. fail(message + " exception: " + th + "\n" + Log.getStackTraceString(th)); @@ -678,6 +683,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { protected int mInjectedCallingUid; protected String mInjectedClientPackage; + protected ComponentName mInjectedChooserActivity; protected Map<String, PackageInfo> mInjectedPackages; @@ -723,6 +729,9 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { protected static final String LAUNCHER_4 = "com.android.launcher.4"; protected static final int LAUNCHER_UID_4 = 10014; + protected static final String CHOOSER_ACTIVITY_PACKAGE = "com.android.intentresolver"; + protected static final int CHOOSER_ACTIVITY_UID = 10015; + protected static final int USER_0 = UserHandle.USER_SYSTEM; protected static final int USER_10 = 10; protected static final int USER_11 = 11; diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java index a350dfbad662..867890f938ba 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java @@ -6901,6 +6901,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { } public void testGetShareTargets_permission() { + addPackage(CHOOSER_ACTIVITY_PACKAGE, CHOOSER_ACTIVITY_UID, 10, "sig1"); + mInjectedChooserActivity = + ComponentName.createRelative(CHOOSER_ACTIVITY_PACKAGE, ".ChooserActivity"); IntentFilter filter = new IntentFilter(); assertExpectException(SecurityException.class, "Missing permission", () -> @@ -6909,6 +6912,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // Has permission, now it should pass. mCallerPermissions.add(permission.MANAGE_APP_PREDICTIONS); mManager.getShareTargets(filter); + + runWithCaller(CHOOSER_ACTIVITY_PACKAGE, USER_0, () -> { + // Access is allowed when called from the configured system ChooserActivity + mManager.getShareTargets(filter); + }); } public void testHasShareTargets_permission() { |