Merge cherrypicks of [12620612, 12620613, 12620936, 12620457, 12616684, 12621005, 12620883, 12620884, 12620846, 12620847, 12620869, 12620848, 12620849, 12620961, 12620962, 12620827, 12620614, 12620197, 12620885, 12620198, 12621039, 12621040, 12621041, 12620937, 12620615, 12620886] into rvc-release
Change-Id: I0d6914fa9ddf68ed7bd63a4621e5e2a6c10ad1b2
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -207,7 +207,7 @@ public class Notification implements Parcelable
|
||||
* <p>
|
||||
* 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) {
|
||||
|
||||
@@ -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.
|
||||
* <p>For empty lists of {@link Locale} items it is better to use {@link #getEmptyLocaleList()},
|
||||
* which returns a pre-constructed empty list.</p>
|
||||
*
|
||||
* @throws NullPointerException if any of the input locales is <code>null</code>.
|
||||
* @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<Locale> localeList = new ArrayList<>();
|
||||
final HashSet<Locale> seenLocales = new HashSet<Locale>();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
<!-- virtual display test permissions -->
|
||||
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" />
|
||||
<uses-permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT" />
|
||||
<uses-permission android:name="android.permission.ADD_TRUSTED_DISPLAY" />
|
||||
|
||||
<!-- color extraction test permissions -->
|
||||
<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -4198,13 +4198,9 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
Iterator<ResolveInfo> 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<String> permissions = ArrayUtils.isEmpty(p.getRequestedPermissions())
|
||||
Set<String> 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<PackageInfo> list, PackageSetting ps,
|
||||
String[] permissions, boolean[] tmp, int flags, int userId) {
|
||||
int numMatch = 0;
|
||||
final PermissionsState permissionsState = ps.getPermissionsState();
|
||||
for (int i=0; i<permissions.length; i++) {
|
||||
final String permission = permissions[i];
|
||||
if (permissionsState.hasPermission(permission, userId)) {
|
||||
if (checkPermission(permission, ps.name, userId) == PERMISSION_GRANTED) {
|
||||
tmp[i] = true;
|
||||
numMatch++;
|
||||
} else {
|
||||
@@ -19185,6 +19196,14 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
final int flags = action.flags;
|
||||
final boolean systemApp = isSystemApp(ps);
|
||||
|
||||
// We need to get the permission state before package state is (potentially) destroyed.
|
||||
final SparseBooleanArray hadSuspendAppsPermission = new SparseBooleanArray();
|
||||
// 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);
|
||||
}
|
||||
|
||||
final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
|
||||
|
||||
if ((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)
|
||||
@@ -19251,8 +19270,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
affectedUserIds = resolveUserIds(userId);
|
||||
}
|
||||
for (final int affectedUserId : affectedUserIds) {
|
||||
if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS,
|
||||
affectedUserId)) {
|
||||
if (hadSuspendAppsPermission.get(affectedUserId)) {
|
||||
unsuspendForSuspendingPackage(packageName, affectedUserId);
|
||||
removeAllDistractingPackageRestrictions(affectedUserId);
|
||||
}
|
||||
@@ -21017,8 +21035,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
pkgSetting.setEnabled(newState, userId, callingPackage);
|
||||
if ((newState == COMPONENT_ENABLED_STATE_DISABLED_USER
|
||||
|| newState == COMPONENT_ENABLED_STATE_DISABLED)
|
||||
&& pkgSetting.getPermissionsState().hasPermission(
|
||||
Manifest.permission.SUSPEND_APPS, userId)) {
|
||||
&& checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
|
||||
== PERMISSION_GRANTED) {
|
||||
// This app should not generally be allowed to get disabled by the UI, but if it
|
||||
// ever does, we don't want to end up with some of the user's apps permanently
|
||||
// suspended.
|
||||
|
||||
Reference in New Issue
Block a user