Merge "Merge rvc-release RP1A.201105.002 to stage-aosp-master - DO NOT MERGE" into stage-aosp-master

This commit is contained in:
Bill Yi
2020-11-04 18:18:23 +00:00
committed by Android (Google) Code Review
12 changed files with 148 additions and 39 deletions

View File

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

View File

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

View File

@@ -1134,15 +1134,14 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
if (invokeCallback) {
control.cancel();
}
boolean stateChanged = false;
for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
RunningAnimation runningAnimation = mRunningAnimations.get(i);
if (runningAnimation.runner == control) {
mRunningAnimations.remove(i);
ArraySet<Integer> types = toInternalType(control.getTypes());
for (int j = types.size() - 1; j >= 0; j--) {
if (getSourceConsumer(types.valueAt(j)).notifyAnimationFinished()) {
mHost.notifyInsetsChanged();
}
stateChanged |= getSourceConsumer(types.valueAt(j)).notifyAnimationFinished();
}
if (invokeCallback && runningAnimation.startDispatched) {
dispatchAnimationEnd(runningAnimation.runner.getAnimation());
@@ -1150,6 +1149,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
break;
}
}
if (stateChanged) {
mHost.notifyInsetsChanged();
updateRequestedState();
}
}
private void applyLocalVisibilityOverride() {

View File

@@ -2792,6 +2792,7 @@
<item>power</item>
<item>restart</item>
<item>logout</item>
<item>screenshot</item>
<item>bugreport</item>
</string-array>
@@ -3506,6 +3507,7 @@
mode -->
<string-array translatable="false" name="config_priorityOnlyDndExemptPackages">
<item>com.android.dialer</item>
<item>com.android.server.telecom</item>
<item>com.android.systemui</item>
<item>android</item>
</string-array>

View File

@@ -27,6 +27,7 @@ import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.statusBars;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
@@ -742,6 +743,20 @@ public class InsetsControllerTest {
mController.onControlsChanged(createSingletonControl(ITYPE_IME));
assertEquals(newState.getSource(ITYPE_IME),
mTestHost.getModifiedState().peekSource(ITYPE_IME));
// The modified frames cannot be updated if there is an animation.
mController.onControlsChanged(createSingletonControl(ITYPE_NAVIGATION_BAR));
mController.hide(navigationBars());
newState = new InsetsState(mController.getState(), true /* copySource */);
newState.getSource(ITYPE_NAVIGATION_BAR).getFrame().top--;
mController.onStateChanged(newState);
assertNotEquals(newState.getSource(ITYPE_NAVIGATION_BAR),
mTestHost.getModifiedState().peekSource(ITYPE_NAVIGATION_BAR));
// The modified frames can be updated while the animation is done.
mController.cancelExistingAnimations();
assertEquals(newState.getSource(ITYPE_NAVIGATION_BAR),
mTestHost.getModifiedState().peekSource(ITYPE_NAVIGATION_BAR));
});
}

View File

@@ -19,6 +19,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_GLOBAL_ACTIONS;
import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
@@ -547,7 +548,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
if (!mDeviceProvisioned && !action.showBeforeProvisioning()) {
return false;
}
return true;
return action.shouldShow();
}
/**
@@ -962,6 +963,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
@VisibleForTesting
class ScreenshotAction extends SinglePressAction implements LongPressAction {
final String KEY_SYSTEM_NAV_2BUTTONS = "system_nav_2buttons";
public ScreenshotAction() {
super(R.drawable.ic_screenshot, R.string.global_action_screenshot);
}
@@ -993,6 +996,19 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
return false;
}
@Override
public boolean shouldShow() {
// Include screenshot in power menu for legacy nav because it is not accessible
// through Recents in that mode
return is2ButtonNavigationEnabled();
}
boolean is2ButtonNavigationEnabled() {
return NAV_BAR_MODE_2BUTTON == mContext.getResources().getInteger(
com.android.internal.R.integer.config_navBarInteractionMode);
}
@Override
public boolean onLongPress() {
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SCREENRECORD_LONG_PRESS)) {
@@ -1616,6 +1632,10 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
* @return
*/
CharSequence getMessage();
default boolean shouldShow() {
return true;
}
}
/**

View File

@@ -49,6 +49,7 @@ import android.testing.TestableLooper;
import android.util.FeatureFlagUtils;
import android.view.IWindowManager;
import android.view.View;
import android.view.WindowManagerPolicyConstants;
import android.widget.FrameLayout;
import androidx.test.filters.SmallTest;
@@ -241,6 +242,28 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_SCREENSHOT_LONG_PRESS);
}
@Test
public void testShouldShowScreenshot() {
mContext.getOrCreateTestableResources().addOverride(
com.android.internal.R.integer.config_navBarInteractionMode,
WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON);
GlobalActionsDialog.ScreenshotAction screenshotAction =
mGlobalActionsDialog.makeScreenshotActionForTesting();
assertThat(screenshotAction.shouldShow()).isTrue();
}
@Test
public void testShouldNotShowScreenshot() {
mContext.getOrCreateTestableResources().addOverride(
com.android.internal.R.integer.config_navBarInteractionMode,
WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON);
GlobalActionsDialog.ScreenshotAction screenshotAction =
mGlobalActionsDialog.makeScreenshotActionForTesting();
assertThat(screenshotAction.shouldShow()).isFalse();
}
private void verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent event) {
mTestableLooper.processAllMessages();
verify(mUiEventLogger, times(1))

View File

@@ -4206,13 +4206,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();
}
@@ -4388,8 +4384,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);
@@ -8587,10 +8599,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 {
@@ -19199,6 +19210,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)
@@ -19265,8 +19284,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);
}
@@ -21036,8 +21054,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.

View File

@@ -4578,15 +4578,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return false;
}
// Check if the activity is on a sleeping display, and if it can turn it ON.
if (getDisplay().isSleeping()) {
final boolean canTurnScreenOn = !mSetToSleep || canTurnScreenOn()
|| canShowWhenLocked() || containsDismissKeyguardWindow();
if (!canTurnScreenOn) {
return false;
}
}
// Now check whether it's really visible depending on Keyguard state, and update
// {@link ActivityStack} internal states.
// Inform the method if this activity is the top activity of this stack, but exclude the
@@ -4597,6 +4588,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final boolean visibleIgnoringDisplayStatus = stack.checkKeyguardVisibility(this,
visibleIgnoringKeyguard, isTop && isTopNotPinnedStack);
// Check if the activity is on a sleeping display, and if it can turn it ON.
// TODO(b/163993448): Do not make activity visible before display awake.
if (visibleIgnoringDisplayStatus && getDisplay().isSleeping()) {
return !mSetToSleep || canTurnScreenOn();
}
return visibleIgnoringDisplayStatus;
}

View File

@@ -1704,8 +1704,9 @@ class ActivityStack extends Task {
// If the most recent activity was noHistory but was only stopped rather
// than stopped+finished because the device went to sleep, we need to make
// sure to finish it as we're making a new activity topmost.
if (shouldSleepActivities() && mLastNoHistoryActivity != null &&
!mLastNoHistoryActivity.finishing) {
if (shouldSleepActivities() && mLastNoHistoryActivity != null
&& !mLastNoHistoryActivity.finishing
&& mLastNoHistoryActivity != next) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"no-history finish of " + mLastNoHistoryActivity + " on new resume");
mLastNoHistoryActivity.finishIfPossible("resume-no-history", false /* oomAdj */);

View File

@@ -1481,9 +1481,10 @@ class ActivityStarter {
// anyone interested in this piece of information.
final ActivityStack homeStack = targetTask.getDisplayArea().getRootHomeTask();
final boolean homeTaskVisible = homeStack != null && homeStack.shouldBeVisible(null);
final ActivityRecord top = targetTask.getTopNonFinishingActivity();
final boolean visible = top != null && top.isVisible();
mService.getTaskChangeNotificationController().notifyActivityRestartAttempt(
targetTask.getTaskInfo(), homeTaskVisible, clearedTask,
targetTask.getTopNonFinishingActivity().isVisible());
targetTask.getTaskInfo(), homeTaskVisible, clearedTask, visible);
}
}

View File

@@ -1099,6 +1099,34 @@ public class ActivityRecordTests extends ActivityTestsBase {
verify(topActivity).destroyIfPossible(anyString());
}
/**
* Verify the visibility of a show-when-locked and dismiss keyguard activity on sleeping
* display.
*/
@Test
public void testDisplaySleeping_activityInvisible() {
final KeyguardController keyguardController =
mActivity.mStackSupervisor.getKeyguardController();
doReturn(true).when(keyguardController).isKeyguardLocked();
final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
topActivity.mVisibleRequested = true;
topActivity.nowVisible = true;
topActivity.setState(RESUMED, "test" /*reason*/);
doReturn(true).when(topActivity).containsDismissKeyguardWindow();
doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
any() /* starting */, anyInt() /* configChanges */,
anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
topActivity.setShowWhenLocked(true);
// Verify the top activity is occluded keyguard.
assertEquals(topActivity, mStack.topRunningActivity());
assertTrue(mStack.topActivityOccludesKeyguard());
final DisplayContent display = mActivity.mDisplayContent;
doReturn(true).when(display).isSleeping();
assertFalse(topActivity.shouldBeVisible());
}
/**
* Verify that complete finish request for a show-when-locked activity must ensure the
* keyguard occluded state being updated.