Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit c124bc9f authored by Kevin F. Haggerty's avatar Kevin F. Haggerty
Browse files

Merge tag 'android-security-9.0.0_r72' into staging/lineage-16.0_merge_android-security-9.0.0_r72

Android security 9.0.0 release 72

* tag 'android-security-9.0.0_r72':
  Don't attach private Notification to A11yEvent when user locked
  Improve ellipsize performance
  Fix side effects of trace-ipc and dumpheap commands
  Fix race condition between lockNow() and updateLockscreenTimeout

Conflicts:
	services/core/java/com/android/server/notification/NotificationManagerService.java
	services/core/java/com/android/server/policy/PhoneWindowManager.java
	services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java

Change-Id: I1c3c9e0cb63673d606f81657c5c93c722e6ec147
parents 4ad01f7d 927dc5f7
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -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,11 +2292,9 @@ public abstract class Layout {
            }

            final int a = i + ellipsisStart + lineStart;
            if (start <= a && a < end) {
            dest[destoff + a - start] = c;
        }
    }
    }

    /**
     * Stores information about bidirectional (left-to-right or right-to-left)
+2 −5
Original line number Diff line number Diff line
@@ -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;
@@ -719,8 +718,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;
@@ -871,8 +869,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;
+27 −7
Original line number Diff line number Diff line
@@ -97,6 +97,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;
@@ -381,6 +382,8 @@ public class NotificationManagerService extends SystemService {
    final ArrayMap<Integer, ArrayList<NotifyingApp>> mRecentApps = new ArrayMap<>();
    final ArrayMap<String, Long> mLastSoundTimestamps = new ArrayMap<>();

    private KeyguardManager mKeyguardManager;

    // The last key in this list owns the hardware.
    ArrayList<String> mLights = new ArrayList<>();

@@ -1286,6 +1289,10 @@ public class NotificationManagerService extends SystemService {
    }

    @VisibleForTesting
    void setKeyguardManager(KeyguardManager keyguardManager) {
        mKeyguardManager = keyguardManager;
    }

    void setVibrator(Vibrator vibrator) {
        mVibrator = vibrator;
    }
@@ -1670,6 +1677,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
@@ -4876,7 +4884,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?
@@ -4893,7 +4900,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;
        }

@@ -4917,7 +4924,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!");
@@ -5551,17 +5558,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());
        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);
        CharSequence tickerText = notification.tickerText;
        }
        final CharSequence tickerText = notification.tickerText;
        if (!TextUtils.isEmpty(tickerText)) {
            event.getText().add(tickerText);
        }
+11 −1
Original line number Diff line number Diff line
@@ -896,6 +896,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {

    private boolean mAodShowing;

    private boolean mLockNowPending = false;

    private final List<DeviceKeyHandler> mDeviceKeyHandlers = new ArrayList<>();
    private LineageButtons mLineageButtons;

@@ -8511,6 +8513,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    mKeyguardDelegate.doKeyguardTimeout(options);
                }
                mLockScreenTimerActive = false;
                mLockNowPending = false;
                options = null;
            }
        }
@@ -8520,7 +8523,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }
    }

    ScreenLockTimeout mScreenLockTimeout = new ScreenLockTimeout();
    final ScreenLockTimeout mScreenLockTimeout = new ScreenLockTimeout();

    @Override
    public void lockNow(Bundle options) {
@@ -8532,10 +8535,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) {
+95 −0
Original line number Diff line number Diff line
@@ -27,6 +27,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;
@@ -42,6 +43,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;
@@ -74,6 +76,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;
@@ -93,6 +96,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
    NotificationUsageStats mUsageStats;
    @Mock
    IAccessibilityManager mAccessibilityService;
    @Mock
    KeyguardManager mKeyguardManager;

    private NotificationManagerService mService;
    private String mPkg = "com.android.server.notification";
@@ -132,6 +137,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,
@@ -155,6 +161,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
        mService.mScreenOn = false;
        mService.mInCall = false;
        mService.mNotificationPulseEnabled = true;
        mService.setKeyguardManager(mKeyguardManager);
    }

    //
@@ -421,6 +428,94 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
        assertTrue(r.isInterruptive());
    }

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