summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-06-30 05:30:11 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-06-30 05:30:11 +0000
commit927dc5f7b6828ee271ca8bdd2a4113a8f63d983f (patch)
treef117efc38641fac2fbefbbcf0f8bd6c23a6e21bb
parent40783c3736d6535f07e529774ff2c2b130a6a01b (diff)
parentef7f436892b6305db65f7feff6023eb08ac3be4a (diff)
downloadbase-927dc5f7b6828ee271ca8bdd2a4113a8f63d983f.tar.gz
Merge cherrypicks of [15151696, 15151717, 15151893, 15151895, 15151897, 15151898, 15150909, 15151854, 15151855, 15151385, 15151702, 15151705, 15151707] into security-aosp-pi-releaseandroid-security-9.0.0_r72
Change-Id: I24eedd0c2f1ba5de720e5a1b6e18523fccb13ecf
-rw-r--r--core/java/android/text/Layout.java9
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java7
-rwxr-xr-x[-rw-r--r--]services/core/java/com/android/server/notification/NotificationManagerService.java34
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java12
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java95
5 files changed, 140 insertions, 17 deletions
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index c02f7ef65a77..3154acccc6d8 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -2280,7 +2280,10 @@ public abstract class Layout {
final int ellipsisStringLen = ellipsisString.length();
// Use the ellipsis string only if there are that at least as many characters to replace.
final boolean useEllipsisString = ellipsisCount >= ellipsisStringLen;
- for (int i = 0; i < ellipsisCount; i++) {
+ final int min = Math.max(0, start - ellipsisStart - lineStart);
+ final int max = Math.min(ellipsisCount, end - ellipsisStart - lineStart);
+
+ for (int i = min; i < max; i++) {
final char c;
if (useEllipsisString && i < ellipsisStringLen) {
c = ellipsisString.charAt(i);
@@ -2289,9 +2292,7 @@ public abstract class Layout {
}
final int a = i + ellipsisStart + lineStart;
- if (start <= a && a < end) {
- dest[destoff + a - start] = c;
- }
+ dest[destoff + a - start] = c;
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index c105a33d5c6b..9d1dad4eced9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -76,7 +76,6 @@ import com.android.internal.util.MemInfoReader;
import com.android.internal.util.Preconditions;
import java.io.BufferedReader;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -722,8 +721,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
return -1;
}
- File file = new File(filename);
- file.delete();
+ // Writes an error message to stderr on failure
ParcelFileDescriptor fd = openFileForSystem(filename, "w");
if (fd == null) {
return -1;
@@ -874,8 +872,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
String process = getNextArgRequired();
String heapFile = getNextArgRequired();
- File file = new File(heapFile);
- file.delete();
+ // Writes an error message to stderr on failure
ParcelFileDescriptor fd = openFileForSystem(heapFile, "w");
if (fd == null) {
return -1;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 75613bc6c2ef..73eeda336b96 100644..100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -91,6 +91,7 @@ import android.app.AutomaticZenRule;
import android.app.IActivityManager;
import android.app.INotificationManager;
import android.app.ITransientNotification;
+import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
@@ -367,6 +368,8 @@ public class NotificationManagerService extends SystemService {
final ArrayMap<String, NotificationRecord> mSummaryByGroupKey = new ArrayMap<>();
final ArrayMap<Integer, ArrayList<NotifyingApp>> mRecentApps = new ArrayMap<>();
+ private KeyguardManager mKeyguardManager;
+
// The last key in this list owns the hardware.
ArrayList<String> mLights = new ArrayList<>();
@@ -1258,6 +1261,10 @@ public class NotificationManagerService extends SystemService {
}
@VisibleForTesting
+ void setKeyguardManager(KeyguardManager keyguardManager) {
+ mKeyguardManager = keyguardManager;
+ }
+
void setVibrator(Vibrator vibrator) {
mVibrator = vibrator;
}
@@ -1631,6 +1638,7 @@ public class NotificationManagerService extends SystemService {
mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
mAudioManagerInternal = getLocalService(AudioManagerInternal.class);
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+ mKeyguardManager = getContext().getSystemService(KeyguardManager.class);
mZenModeHelper.onSystemReady();
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
// This observer will force an update when observe is called, causing us to
@@ -4793,7 +4801,6 @@ public class NotificationManagerService extends SystemService {
boolean beep = false;
boolean blink = false;
- final Notification notification = record.sbn.getNotification();
final String key = record.getKey();
// Should this notification make noise, vibe, or use the LED?
@@ -4810,7 +4817,7 @@ public class NotificationManagerService extends SystemService {
// If the notification will appear in the status bar, it should send an accessibility
// event
if (!record.isUpdate && record.getImportance() > IMPORTANCE_MIN) {
- sendAccessibilityEvent(notification, record.sbn.getPackageName());
+ sendAccessibilityEvent(record);
sentAccessibilityEvent = true;
}
@@ -4834,7 +4841,7 @@ public class NotificationManagerService extends SystemService {
boolean hasAudibleAlert = hasValidSound || hasValidVibrate;
if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {
if (!sentAccessibilityEvent) {
- sendAccessibilityEvent(notification, record.sbn.getPackageName());
+ sendAccessibilityEvent(record);
sentAccessibilityEvent = true;
}
if (DBG) Slog.v(TAG, "Interrupting!");
@@ -5397,17 +5404,30 @@ public class NotificationManagerService extends SystemService {
return (x < low) ? low : ((x > high) ? high : x);
}
- void sendAccessibilityEvent(Notification notification, CharSequence packageName) {
+ void sendAccessibilityEvent(NotificationRecord record) {
if (!mAccessibilityManager.isEnabled()) {
return;
}
- AccessibilityEvent event =
+ final Notification notification = record.getNotification();
+ final CharSequence packageName = record.sbn.getPackageName();
+ final AccessibilityEvent event =
AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
event.setPackageName(packageName);
event.setClassName(Notification.class.getName());
- event.setParcelableData(notification);
- CharSequence tickerText = notification.tickerText;
+ final int visibilityOverride = record.getPackageVisibilityOverride();
+ final int notifVisibility = visibilityOverride == NotificationManager.VISIBILITY_NO_OVERRIDE
+ ? notification.visibility : visibilityOverride;
+ final int userId = record.getUser().getIdentifier();
+ final boolean needPublic = userId >= 0 && mKeyguardManager.isDeviceLocked(userId);
+ if (needPublic && notifVisibility != Notification.VISIBILITY_PUBLIC) {
+ // Emit the public version if we're on the lockscreen and this notification isn't
+ // publicly visible.
+ event.setParcelableData(notification.publicVersion);
+ } else {
+ event.setParcelableData(notification);
+ }
+ final CharSequence tickerText = notification.tickerText;
if (!TextUtils.isEmpty(tickerText)) {
event.getText().add(tickerText);
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 027507679f0e..e3b713a2b027 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -818,6 +818,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private boolean mAodShowing;
+ private boolean mLockNowPending = false;
+
private static final int MSG_ENABLE_POINTER_LOCATION = 1;
private static final int MSG_DISABLE_POINTER_LOCATION = 2;
private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
@@ -7757,6 +7759,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mKeyguardDelegate.doKeyguardTimeout(options);
}
mLockScreenTimerActive = false;
+ mLockNowPending = false;
options = null;
}
}
@@ -7766,7 +7769,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
- ScreenLockTimeout mScreenLockTimeout = new ScreenLockTimeout();
+ final ScreenLockTimeout mScreenLockTimeout = new ScreenLockTimeout();
@Override
public void lockNow(Bundle options) {
@@ -7778,10 +7781,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mScreenLockTimeout.setLockOptions(options);
}
mHandler.post(mScreenLockTimeout);
+ synchronized (mScreenLockTimeout) {
+ mLockNowPending = true;
+ }
}
private void updateLockScreenTimeout() {
synchronized (mScreenLockTimeout) {
+ if (mLockNowPending) {
+ Log.w(TAG, "lockNow pending, ignore updating lockscreen timeout");
+ return;
+ }
boolean enable = (mAllowLockscreenWhenOn && mAwake &&
mKeyguardDelegate != null && mKeyguardDelegate.isSecure(mCurrentUserId));
if (mLockScreenTimerActive != enable) {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 78099996a1a0..e7b36860a767 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -25,6 +25,7 @@ import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
@@ -40,6 +41,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
+import android.app.KeyguardManager;
import android.app.Notification;
import android.app.Notification.Builder;
import android.app.NotificationChannel;
@@ -71,6 +73,7 @@ import com.android.server.lights.Light;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.Mockito;
@@ -90,6 +93,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
NotificationUsageStats mUsageStats;
@Mock
IAccessibilityManager mAccessibilityService;
+ @Mock
+ KeyguardManager mKeyguardManager;
private NotificationManagerService mService;
private String mPkg = "com.android.server.notification";
@@ -129,6 +134,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10);
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
when(mUsageStats.isAlertRateLimited(any())).thenReturn(false);
+ when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false);
long serviceReturnValue = IntPair.of(
AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED,
@@ -149,6 +155,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
mService.setFallbackVibrationPattern(FALLBACK_VIBRATION_PATTERN);
mService.setUsageStats(mUsageStats);
mService.setAccessibilityManager(accessibilityManager);
+ mService.setKeyguardManager(mKeyguardManager);
}
//
@@ -406,6 +413,94 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
}
@Test
+ public void testLockedPrivateA11yRedaction() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
+ r.getNotification().visibility = Notification.VISIBILITY_PRIVATE;
+ when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
+ AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+ when(accessibilityManager.isEnabled()).thenReturn(true);
+ mService.setAccessibilityManager(accessibilityManager);
+
+ mService.buzzBeepBlinkLocked(r);
+
+ ArgumentCaptor<AccessibilityEvent> eventCaptor =
+ ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+ verify(accessibilityManager, times(1))
+ .sendAccessibilityEvent(eventCaptor.capture());
+
+ AccessibilityEvent event = eventCaptor.getValue();
+ assertEquals(r.getNotification().publicVersion, event.getParcelableData());
+ }
+
+ @Test
+ public void testLockedOverridePrivateA11yRedaction() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ r.setPackageVisibilityOverride(Notification.VISIBILITY_PRIVATE);
+ r.getNotification().visibility = Notification.VISIBILITY_PUBLIC;
+ when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
+ AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+ when(accessibilityManager.isEnabled()).thenReturn(true);
+ mService.setAccessibilityManager(accessibilityManager);
+
+ mService.buzzBeepBlinkLocked(r);
+
+ ArgumentCaptor<AccessibilityEvent> eventCaptor =
+ ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+ verify(accessibilityManager, times(1))
+ .sendAccessibilityEvent(eventCaptor.capture());
+
+ AccessibilityEvent event = eventCaptor.getValue();
+ assertEquals(r.getNotification().publicVersion, event.getParcelableData());
+ }
+
+ @Test
+ public void testLockedPublicA11yNoRedaction() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
+ r.getNotification().visibility = Notification.VISIBILITY_PUBLIC;
+ when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true);
+ AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+ when(accessibilityManager.isEnabled()).thenReturn(true);
+ mService.setAccessibilityManager(accessibilityManager);
+
+ mService.buzzBeepBlinkLocked(r);
+
+ ArgumentCaptor<AccessibilityEvent> eventCaptor =
+ ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+ verify(accessibilityManager, times(1))
+ .sendAccessibilityEvent(eventCaptor.capture());
+
+ AccessibilityEvent event = eventCaptor.getValue();
+ assertEquals(r.getNotification(), event.getParcelableData());
+ }
+
+ @Test
+ public void testUnlockedPrivateA11yNoRedaction() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
+ r.getNotification().visibility = Notification.VISIBILITY_PRIVATE;
+ when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false);
+ AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class);
+ when(accessibilityManager.isEnabled()).thenReturn(true);
+ mService.setAccessibilityManager(accessibilityManager);
+
+ mService.buzzBeepBlinkLocked(r);
+
+ ArgumentCaptor<AccessibilityEvent> eventCaptor =
+ ArgumentCaptor.forClass(AccessibilityEvent.class);
+
+ verify(accessibilityManager, times(1))
+ .sendAccessibilityEvent(eventCaptor.capture());
+
+ AccessibilityEvent event = eventCaptor.getValue();
+ assertEquals(r.getNotification(), event.getParcelableData());
+ }
+
+ @Test
public void testBeepInsistently() throws Exception {
NotificationRecord r = getInsistentBeepyNotification();