From e752ae55522f2657bb26bd2351ef879a73fa6efb Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 13 Aug 2020 01:45:09 +0000 Subject: [PATCH 1/5] DO NOT MERGE Don't allow non-instant permissions for instant apps. Bug: 140256621 Test: atest EphemeralTest Change-Id: Id07342c0347c0b4d2ccb3f58a4af9fda7a20d6ef (cherry picked from commit d83e3a350d1a2a6fd317b19ad22ee5647781870e) --- .../server/pm/PackageManagerService.java | 45 +++++++++++++------ 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 63c721a5da7b3..7a38a45335724 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4198,13 +4198,9 @@ public class PackageManagerService extends IPackageManager.Stub Iterator iter = matches.iterator(); while (iter.hasNext()) { final ResolveInfo rInfo = iter.next(); - final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName); - if (ps != null) { - final PermissionsState permissionsState = ps.getPermissionsState(); - if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0) - || Build.IS_ENG) { - continue; - } + if (checkPermission(Manifest.permission.INSTALL_PACKAGES, + rInfo.activityInfo.packageName, 0) == PERMISSION_GRANTED || Build.IS_ENG) { + continue; } iter.remove(); } @@ -4380,8 +4376,24 @@ public class PackageManagerService extends IPackageManager.Stub final int[] gids = (flags & PackageManager.GET_GIDS) == 0 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); // Compute granted permissions only if package has requested permissions - final Set permissions = ArrayUtils.isEmpty(p.getRequestedPermissions()) + Set permissions = ArrayUtils.isEmpty(p.getRequestedPermissions()) ? Collections.emptySet() : permissionsState.getPermissions(userId); + if (state.instantApp) { + permissions = new ArraySet<>(permissions); + permissions.removeIf(permissionName -> { + BasePermission permission = mPermissionManager.getPermissionTEMP( + permissionName); + if (permission == null) { + return true; + } + if (!permission.isInstant()) { + EventLog.writeEvent(0x534e4554, "140256621", UserHandle.getUid(userId, + ps.appId), permissionName); + return true; + } + return false; + }); + } PackageInfo packageInfo = PackageInfoUtils.generate(p, gids, flags, ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId, ps); @@ -8579,10 +8591,9 @@ public class PackageManagerService extends IPackageManager.Stub private void addPackageHoldingPermissions(ArrayList list, PackageSetting ps, String[] permissions, boolean[] tmp, int flags, int userId) { int numMatch = 0; - final PermissionsState permissionsState = ps.getPermissionsState(); for (int i=0; i Date: Mon, 31 Aug 2020 18:28:41 +0000 Subject: [PATCH 2/5] DO NOT MERGE Fix NPE in executeDeletePackageLIF. The parameter allUserHandles may sometimes be null. Change-Id: Ie58cabe4bb1cae7173ad1d027e993a0b82a9f1ef Bug: 167233572 Bug: 140256621 Test: atest EphemeralTest (cherry picked from commit 01e0f4813af8502faaa683d55dbbc024b3080741) --- .../core/java/com/android/server/pm/PackageManagerService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 7a38a45335724..c3c655d632e74 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -19198,7 +19198,8 @@ public class PackageManagerService extends IPackageManager.Stub // We need to get the permission state before package state is (potentially) destroyed. final SparseBooleanArray hadSuspendAppsPermission = new SparseBooleanArray(); - for (int userId : allUserHandles) { + // allUserHandles could be null, so call mUserManager.getUserIds() directly which is cached anyway. + for (int userId : mUserManager.getUserIds()) { hadSuspendAppsPermission.put(userId, checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId) == PERMISSION_GRANTED); } From 27ef1fc697faed77c7d2bdabf9432718680e1cae Mon Sep 17 00:00:00 2001 From: Andrii Kulian Date: Fri, 31 Jul 2020 18:46:28 -0700 Subject: [PATCH 3/5] Require permission to create trusted displays Bug: 162627132 Test: atest VirtualDisplayTest#testTrustedVirtualDisplay Test: atest frameworks/base/packages/SystemUI/tests/src/com/android/systemui/bubbles Test: atest DisplayTest Test: atest VirtualDisplayTest#testTrustedVirtualDisplay Test: atest VirtualDisplayTest#testUntrustedSysDecorVirtualDisplay Test: adb logcat -b events Change-Id: Id06b2013ef5fdeadf321f14f8b611c733031d54d Merged-In: Id06b2013ef5fdeadf321f14f8b611c733031d54d (cherry picked from commit f21c885ca7e86f77c808ab17fe1de650474de487) --- core/java/android/app/ActivityView.java | 15 +++++++++++++-- .../window/VirtualDisplayTaskEmbedder.java | 9 ++++++++- core/tests/coretests/AndroidManifest.xml | 1 + .../hardware/display/VirtualDisplayTest.java | 19 +++++++++++++++++++ .../systemui/bubbles/BubbleExpandedView.java | 2 +- .../server/display/DisplayManagerService.java | 15 +++++++++++---- 6 files changed, 53 insertions(+), 8 deletions(-) diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index 98a23f2b00750..3cb6293f07066 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -105,7 +105,8 @@ public class ActivityView extends ViewGroup implements android.window.TaskEmbedd public ActivityView( @NonNull Context context, @NonNull AttributeSet attrs, int defStyle, boolean singleTaskInstance, boolean usePublicVirtualDisplay) { - this(context, attrs, defStyle, singleTaskInstance, usePublicVirtualDisplay, false); + this(context, attrs, defStyle, singleTaskInstance, usePublicVirtualDisplay, + false /* disableSurfaceViewBackgroundLayer */); } /** @hide */ @@ -113,12 +114,22 @@ public class ActivityView extends ViewGroup implements android.window.TaskEmbedd @NonNull Context context, @NonNull AttributeSet attrs, int defStyle, boolean singleTaskInstance, boolean usePublicVirtualDisplay, boolean disableSurfaceViewBackgroundLayer) { + this(context, attrs, defStyle, singleTaskInstance, usePublicVirtualDisplay, + disableSurfaceViewBackgroundLayer, false /* useTrustedDisplay */); + } + + // TODO(b/162901735): Refactor ActivityView with Builder + /** @hide */ + public ActivityView( + @NonNull Context context, @NonNull AttributeSet attrs, int defStyle, + boolean singleTaskInstance, boolean usePublicVirtualDisplay, + boolean disableSurfaceViewBackgroundLayer, boolean useTrustedDisplay) { super(context, attrs, defStyle); if (useTaskOrganizer()) { mTaskEmbedder = new TaskOrganizerTaskEmbedder(context, this); } else { mTaskEmbedder = new VirtualDisplayTaskEmbedder(context, this, singleTaskInstance, - usePublicVirtualDisplay); + usePublicVirtualDisplay, useTrustedDisplay); } mSurfaceView = new SurfaceView(context, null, 0, 0, disableSurfaceViewBackgroundLayer); // Since ActivityView#getAlpha has been overridden, we should use parent class's alpha diff --git a/core/java/android/window/VirtualDisplayTaskEmbedder.java b/core/java/android/window/VirtualDisplayTaskEmbedder.java index 9ccb4c172158d..9013da36007e4 100644 --- a/core/java/android/window/VirtualDisplayTaskEmbedder.java +++ b/core/java/android/window/VirtualDisplayTaskEmbedder.java @@ -19,6 +19,7 @@ package android.window; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; +import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED; import static android.view.Display.INVALID_DISPLAY; import android.app.ActivityManager; @@ -63,6 +64,7 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { private int mDisplayDensityDpi; private final boolean mSingleTaskInstance; private final boolean mUsePublicVirtualDisplay; + private final boolean mUseTrustedDisplay; private VirtualDisplay mVirtualDisplay; private Insets mForwardedInsets; private DisplayMetrics mTmpDisplayMetrics; @@ -77,10 +79,12 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { * only applicable if virtual displays are used */ public VirtualDisplayTaskEmbedder(Context context, VirtualDisplayTaskEmbedder.Host host, - boolean singleTaskInstance, boolean usePublicVirtualDisplay) { + boolean singleTaskInstance, boolean usePublicVirtualDisplay, + boolean useTrustedDisplay) { super(context, host); mSingleTaskInstance = singleTaskInstance; mUsePublicVirtualDisplay = usePublicVirtualDisplay; + mUseTrustedDisplay = useTrustedDisplay; } /** @@ -103,6 +107,9 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { if (mUsePublicVirtualDisplay) { virtualDisplayFlags |= VIRTUAL_DISPLAY_FLAG_PUBLIC; } + if (mUseTrustedDisplay) { + virtualDisplayFlags |= VIRTUAL_DISPLAY_FLAG_TRUSTED; + } mVirtualDisplay = displayManager.createVirtualDisplay( DISPLAY_NAME + "@" + System.identityHashCode(this), mHost.getWidth(), diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml index 5c2841aff1d83..7597e87321530 100644 --- a/core/tests/coretests/AndroidManifest.xml +++ b/core/tests/coretests/AndroidManifest.xml @@ -129,6 +129,7 @@ + diff --git a/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java b/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java index daf613976358e..0f6284d22d106 100644 --- a/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java +++ b/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java @@ -247,6 +247,25 @@ public class VirtualDisplayTest extends AndroidTestCase { assertDisplayUnregistered(display); } + /** + * Ensures that an application can create a trusted virtual display with the permission + * {@code ADD_TRUSTED_DISPLAY}. + */ + public void testTrustedVirtualDisplay() throws Exception { + VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME, + WIDTH, HEIGHT, DENSITY, mSurface, + DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED); + assertNotNull("virtual display must not be null", virtualDisplay); + + Display display = virtualDisplay.getDisplay(); + try { + assertDisplayRegistered(display, Display.FLAG_PRIVATE | Display.FLAG_TRUSTED); + } finally { + virtualDisplay.release(); + } + assertDisplayUnregistered(display); + } + private void assertDisplayRegistered(Display display, int flags) { assertNotNull("display object must not be null", display); assertTrue("display must be valid", display.isValid()); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index 3d3171208b150..110a5ab67f0d8 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -301,7 +301,7 @@ public class BubbleExpandedView extends LinearLayout { mActivityView = new ActivityView(mContext, null /* attrs */, 0 /* defStyle */, true /* singleTaskInstance */, false /* usePublicVirtualDisplay*/, - true /* disableSurfaceViewBackgroundLayer */); + true /* disableSurfaceViewBackgroundLayer */, true /* useTrustedDisplay */); // Set ActivityView's alpha value as zero, since there is no view content to be shown. setContentVisibility(false); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 1058000e0b68f..9a8be287690fd 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -86,6 +86,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.text.TextUtils; +import android.util.EventLog; import android.util.IntArray; import android.util.Pair; import android.util.Slog; @@ -2191,10 +2192,16 @@ public final class DisplayManagerService extends SystemService { } } - if (callingUid == Process.SYSTEM_UID - || checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { - flags |= VIRTUAL_DISPLAY_FLAG_TRUSTED; - } else { + if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0) { + if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { + EventLog.writeEvent(0x534e4554, "162627132", callingUid, + "Attempt to create a trusted display without holding permission!"); + throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " + + "create a trusted virtual display."); + } + } + + if ((flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) { flags &= ~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; } From d3a2b5832f6ca9da74cda814ec76aec679b3389a Mon Sep 17 00:00:00 2001 From: Seigo Nonaka Date: Wed, 26 Aug 2020 14:42:08 -0700 Subject: [PATCH 4/5] Accept repeated locale as an input of LocaleList construction. Repeated locale has not been accepted and IllegalArgumentException is thrown. Instead of throwing exception, dropping repeated locale instead. Bug: 152410253 Test: atest LocaleListTest Change-Id: I80f243678ac3024eaeb0349f770cff897df7f332 (cherry picked from commit 7ee68787cca0837f59658d5174e1d586dfe80ad4) --- core/java/android/os/LocaleList.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java index ab4bb0b9f2cd0..9c0bc45a346e9 100644 --- a/core/java/android/os/LocaleList.java +++ b/core/java/android/os/LocaleList.java @@ -25,6 +25,7 @@ import android.icu.util.ULocale; import com.android.internal.annotations.GuardedBy; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -151,18 +152,18 @@ public final class LocaleList implements Parcelable { /** * Creates a new {@link LocaleList}. * + * If two or more same locales are passed, the repeated locales will be dropped. *

For empty lists of {@link Locale} items it is better to use {@link #getEmptyLocaleList()}, * which returns a pre-constructed empty list.

* * @throws NullPointerException if any of the input locales is null. - * @throws IllegalArgumentException if any of the input locales repeat. */ public LocaleList(@NonNull Locale... list) { if (list.length == 0) { mList = sEmptyList; mStringRepresentation = ""; } else { - final Locale[] localeList = new Locale[list.length]; + final ArrayList localeList = new ArrayList<>(); final HashSet seenLocales = new HashSet(); final StringBuilder sb = new StringBuilder(); for (int i = 0; i < list.length; i++) { @@ -170,10 +171,10 @@ public final class LocaleList implements Parcelable { if (l == null) { throw new NullPointerException("list[" + i + "] is null"); } else if (seenLocales.contains(l)) { - throw new IllegalArgumentException("list[" + i + "] is a repetition"); + // Dropping duplicated locale entries. } else { final Locale localeClone = (Locale) l.clone(); - localeList[i] = localeClone; + localeList.add(localeClone); sb.append(localeClone.toLanguageTag()); if (i < list.length - 1) { sb.append(','); @@ -181,7 +182,7 @@ public final class LocaleList implements Parcelable { seenLocales.add(localeClone); } } - mList = localeList; + mList = localeList.toArray(new Locale[localeList.size()]); mStringRepresentation = sb.toString(); } } From aaf6b40e1746db6189f6078dcd28d8f153a4cc50 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Wed, 26 Aug 2020 17:07:53 -0400 Subject: [PATCH 5/5] Sanitize more of the notification text fields Test: manual; monitor SystemUI performance when an app tries to post a messaging style notification with messages with long text Bug: 158304295 Bug: 147358092 Merged-In: c953fdf6bc498ca791aed49df04e5a07c935b63a Change-Id: I0e2ea12fc3351b1a56645b556720ea2306f5422a (cherry picked from commit c953fdf6bc498ca791aed49df04e5a07c935b63a) (cherry picked from commit a19f9ed2b1c04fe7e73bab1a8ca51400dbf8a07a) --- core/java/android/app/Notification.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 79d2a8102358a..609083e719ba6 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -207,7 +207,7 @@ public class Notification implements Parcelable *

* Avoids spamming the system with overly large strings such as full e-mails. */ - private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024; + private static final int MAX_CHARSEQUENCE_LENGTH = 1024; /** * Maximum entries of reply text that are accepted by Builder and friends. @@ -7830,7 +7830,7 @@ public class Notification implements Parcelable */ public Message(@NonNull CharSequence text, long timestamp, @Nullable Person sender, boolean remoteInputHistory) { - mText = text; + mText = safeCharSequence(text); mTimestamp = timestamp; mSender = sender; mRemoteInputHistory = remoteInputHistory; @@ -7944,7 +7944,7 @@ public class Notification implements Parcelable bundle.putLong(KEY_TIMESTAMP, mTimestamp); if (mSender != null) { // Legacy listeners need this - bundle.putCharSequence(KEY_SENDER, mSender.getName()); + bundle.putCharSequence(KEY_SENDER, safeCharSequence(mSender.getName())); bundle.putParcelable(KEY_SENDER_PERSON, mSender); } if (mDataMimeType != null) {