diff options
| author | 2017-05-18 01:55:42 +0000 | |
|---|---|---|
| committer | 2017-05-18 01:55:45 +0000 | |
| commit | b114e4ff82ba0b4d2d684d8dfbcb7f7e4a1f8d8d (patch) | |
| tree | 99ba1bc9aaafb21f2e8cdec40471551f7cd9c5d0 | |
| parent | f17d3b89d3eb2f7ba6857e25ea4bf6fb6ea07efa (diff) | |
| parent | e549a8d62108c7c7dabedbf4e77b9a653781723b (diff) | |
Merge "Optimize latency when unlocking phone" into oc-dev
19 files changed, 233 insertions, 101 deletions
diff --git a/core/res/res/anim/lock_screen_behind_enter.xml b/core/res/res/anim/lock_screen_behind_enter.xml index c96e2809d8a9..c1d26e339a22 100644 --- a/core/res/res/anim/lock_screen_behind_enter.xml +++ b/core/res/res/anim/lock_screen_behind_enter.xml @@ -17,8 +17,7 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:detachWallpaper="true" - android:shareInterpolator="false" - android:startOffset="100"> + android:shareInterpolator="false"> <translate android:fromYDelta="110%p" android:toYDelta="0" android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" diff --git a/core/res/res/anim/lock_screen_behind_enter_fade_in.xml b/core/res/res/anim/lock_screen_behind_enter_fade_in.xml index 94e40a868ed3..e9475f52d22a 100644 --- a/core/res/res/anim/lock_screen_behind_enter_fade_in.xml +++ b/core/res/res/anim/lock_screen_behind_enter_fade_in.xml @@ -22,6 +22,5 @@ android:interpolator="@interpolator/linear" android:fromAlpha="0" android:toAlpha="1" android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:duration="250" - android:startOffset="100"> + android:duration="250"> </alpha>
\ No newline at end of file diff --git a/core/res/res/anim/lock_screen_behind_enter_wallpaper.xml b/core/res/res/anim/lock_screen_behind_enter_wallpaper.xml index 660b66258fed..50156fbf7a02 100644 --- a/core/res/res/anim/lock_screen_behind_enter_wallpaper.xml +++ b/core/res/res/anim/lock_screen_behind_enter_wallpaper.xml @@ -16,12 +16,12 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:detachWallpaper="true" android:shareInterpolator="false" android:startOffset="100"> + android:detachWallpaper="true" android:shareInterpolator="false" > <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:fillEnabled="true" android:fillBefore="true" android:interpolator="@interpolator/decelerate_quint" - android:duration="400"/> + android:duration="300"/> <translate android:fromYDelta="11%p" android:toYDelta="0" android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" diff --git a/core/res/res/anim/lock_screen_wallpaper_exit.xml b/core/res/res/anim/lock_screen_wallpaper_exit.xml index 49d0327b662f..ba8741a25704 100644 --- a/core/res/res/anim/lock_screen_wallpaper_exit.xml +++ b/core/res/res/anim/lock_screen_wallpaper_exit.xml @@ -16,12 +16,12 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false" android:startOffset="100"> + android:shareInterpolator="false"> <alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" android:interpolator="@interpolator/fast_out_linear_in" - android:duration="150"/> + android:duration="200"/> <!-- Empty animation so the animation has same duration as lock_screen_behind_enter animation --> diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index f4d4a9ff327d..0cf8ff05932f 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -264,6 +264,8 @@ public class Dependency extends SystemUI { mProviders.put(AccessibilityManagerWrapper.class, () -> new AccessibilityManagerWrapper(mContext)); + mProviders.put(UiOffloadThread.class, UiOffloadThread::new); + // Put all dependencies above here so the factory can override them if it wants. SystemUIFactory.getInstance().injectDependencies(mProviders, mContext); } diff --git a/packages/SystemUI/src/com/android/systemui/UiOffloadThread.java b/packages/SystemUI/src/com/android/systemui/UiOffloadThread.java new file mode 100644 index 000000000000..82fd9b304195 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/UiOffloadThread.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +/** + * Thread that offloads work from the UI thread but that is still perceptible to the user, so the + * priority is the same as the main thread. + */ +public class UiOffloadThread { + + private final ExecutorService mExecutorService = Executors.newSingleThreadExecutor(); + + public Future<?> submit(Runnable runnable) { + return mExecutorService.submit(runnable); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java index 1abea37519e6..a129acea40b0 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java @@ -30,7 +30,10 @@ import android.provider.Settings; import android.view.MotionEvent; import android.view.accessibility.AccessibilityManager; +import com.android.systemui.Dependency; +import com.android.systemui.UiOffloadThread; import com.android.systemui.analytics.DataCollector; +import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.statusbar.StatusBarState; import java.io.PrintWriter; @@ -63,6 +66,7 @@ public class FalsingManager implements SensorEventListener { private final DataCollector mDataCollector; private final HumanInteractionClassifier mHumanInteractionClassifier; private final AccessibilityManager mAccessibilityManager; + private final UiOffloadThread mUiOffloadThread; private static FalsingManager sInstance = null; @@ -86,6 +90,7 @@ public class FalsingManager implements SensorEventListener { mAccessibilityManager = context.getSystemService(AccessibilityManager.class); mDataCollector = DataCollector.getInstance(mContext); mHumanInteractionClassifier = HumanInteractionClassifier.getInstance(mContext); + mUiOffloadThread = Dependency.get(UiOffloadThread.class); mScreenOn = context.getSystemService(PowerManager.class).isInteractive(); mContext.getContentResolver().registerContentObserver( @@ -130,7 +135,11 @@ public class FalsingManager implements SensorEventListener { private void sessionExitpoint(boolean force) { if (mSessionActive && (force || !shouldSessionBeActive())) { mSessionActive = false; - mSensorManager.unregisterListener(this); + + // This can be expensive, and doesn't need to happen on the main thread. + mUiOffloadThread.submit(() -> { + mSensorManager.unregisterListener(this); + }); } } @@ -154,7 +163,11 @@ public class FalsingManager implements SensorEventListener { for (int sensorType : sensors) { Sensor s = mSensorManager.getDefaultSensor(sensorType); if (s != null) { - mSensorManager.registerListener(this, s, SensorManager.SENSOR_DELAY_GAME); + + // This can be expensive, and doesn't need to happen on the main thread. + mUiOffloadThread.submit(() -> { + mSensorManager.registerListener(this, s, SensorManager.SENSOR_DELAY_GAME); + }); } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java b/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java index 262d29d1acd1..745f312a29b4 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java @@ -17,6 +17,10 @@ package com.android.systemui.keyguard; import com.android.internal.policy.IKeyguardDismissCallback; +import com.android.systemui.Dependency; +import com.android.systemui.UiOffloadThread; +import com.android.systemui.recents.Recents; +import com.android.systemui.recents.misc.SystemServicesProxy; import java.util.ArrayList; @@ -26,6 +30,7 @@ import java.util.ArrayList; public class DismissCallbackRegistry { private final ArrayList<DismissCallbackWrapper> mDismissCallbacks = new ArrayList<>(); + private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class); public void addCallback(IKeyguardDismissCallback callback) { mDismissCallbacks.add(new DismissCallbackWrapper(callback)); @@ -33,14 +38,16 @@ public class DismissCallbackRegistry { public void notifyDismissCancelled() { for (int i = mDismissCallbacks.size() - 1; i >= 0; i--) { - mDismissCallbacks.get(i).notifyDismissCancelled(); + DismissCallbackWrapper callback = mDismissCallbacks.get(i); + mUiOffloadThread.submit(callback::notifyDismissCancelled); } mDismissCallbacks.clear(); } public void notifyDismissSucceeded() { for (int i = mDismissCallbacks.size() - 1; i >= 0; i--) { - mDismissCallbacks.get(i).notifyDismissSucceeded(); + DismissCallbackWrapper callback = mDismissCallbacks.get(i); + mUiOffloadThread.submit(callback::notifyDismissSucceeded); } mDismissCallbacks.clear(); } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index f618a2c55e7d..2d7521d09a4a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -51,6 +51,7 @@ import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; +import android.provider.Settings.System; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.util.EventLog; @@ -76,9 +77,13 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.LatencyTracker; import com.android.keyguard.ViewMediatorCallback; +import com.android.systemui.Dependency; import com.android.systemui.SystemUI; import com.android.systemui.SystemUIFactory; +import com.android.systemui.UiOffloadThread; import com.android.systemui.classifier.FalsingManager; +import com.android.systemui.recents.Recents; +import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.statusbar.phone.FingerprintUnlockController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.ScrimController; @@ -195,6 +200,7 @@ public class KeyguardViewMediator extends SystemUI { private AlarmManager mAlarmManager; private AudioManager mAudioManager; private StatusBarManager mStatusBarManager; + private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class); private boolean mSystemReady; private boolean mBootCompleted; @@ -1199,18 +1205,20 @@ public class KeyguardViewMediator extends SystemUI { updateInputRestrictedLocked(); } } + private void updateInputRestrictedLocked() { boolean inputRestricted = isInputRestricted(); if (mInputRestricted != inputRestricted) { mInputRestricted = inputRestricted; int size = mKeyguardStateCallbacks.size(); for (int i = size - 1; i >= 0; i--) { + final IKeyguardStateCallback callback = mKeyguardStateCallbacks.get(i); try { - mKeyguardStateCallbacks.get(i).onInputRestrictedStateChanged(inputRestricted); + callback.onInputRestrictedStateChanged(inputRestricted); } catch (RemoteException e) { Slog.w(TAG, "Failed to call onDeviceProvisioned", e); if (e instanceof DeadObjectException) { - mKeyguardStateCallbacks.remove(i); + mKeyguardStateCallbacks.remove(callback); } } } @@ -1569,9 +1577,11 @@ public class KeyguardViewMediator extends SystemUI { private void handleKeyguardDone() { Trace.beginSection("KeyguardViewMediator#handleKeyguardDone"); final int currentUser = KeyguardUpdateMonitor.getCurrentUser(); - if (mLockPatternUtils.isSecure(currentUser)) { - mLockPatternUtils.getDevicePolicyManager().reportKeyguardDismissed(currentUser); - } + mUiOffloadThread.submit(() -> { + if (mLockPatternUtils.isSecure(currentUser)) { + mLockPatternUtils.getDevicePolicyManager().reportKeyguardDismissed(currentUser); + } + }); if (DEBUG) Log.d(TAG, "handleKeyguardDone"); synchronized (this) { resetKeyguardDonePendingLocked(); @@ -1611,10 +1621,12 @@ public class KeyguardViewMediator extends SystemUI { final UserHandle currentUser = new UserHandle(currentUserId); final UserManager um = (UserManager) mContext.getSystemService( Context.USER_SERVICE); - for (int profileId : um.getProfileIdsWithDisabled(currentUser.getIdentifier())) { - mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, UserHandle.of(profileId)); - } - getLockPatternUtils().userPresent(currentUserId); + mUiOffloadThread.submit(() -> { + for (int profileId : um.getProfileIdsWithDisabled(currentUser.getIdentifier())) { + mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, UserHandle.of(profileId)); + } + getLockPatternUtils().userPresent(currentUserId); + }); } else { mBootSendUserPresent = true; } @@ -1659,11 +1671,18 @@ public class KeyguardViewMediator extends SystemUI { if (mAudioManager == null) return; mUiSoundsStreamType = mAudioManager.getUiSoundsStreamType(); } - // If the stream is muted, don't play the sound - if (mAudioManager.isStreamMute(mUiSoundsStreamType)) return; - mLockSoundStreamId = mLockSounds.play(soundId, - mLockSoundVolume, mLockSoundVolume, 1/*priortiy*/, 0/*loop*/, 1.0f/*rate*/); + mUiOffloadThread.submit(() -> { + // If the stream is muted, don't play the sound + if (mAudioManager.isStreamMute(mUiSoundsStreamType)) return; + + int id = mLockSounds.play(soundId, + mLockSoundVolume, mLockSoundVolume, 1/*priortiy*/, 0/*loop*/, 1.0f/*rate*/); + synchronized (this) { + mLockSoundStreamId = id; + } + }); + } } @@ -1671,13 +1690,13 @@ public class KeyguardViewMediator extends SystemUI { playSound(mTrustedSoundId); } - private void updateActivityLockScreenState() { - Trace.beginSection("KeyguardViewMediator#updateActivityLockScreenState"); - try { - ActivityManager.getService().setLockScreenShown(mShowing); - } catch (RemoteException e) { - } - Trace.endSection(); + private void updateActivityLockScreenState(boolean showing) { + mUiOffloadThread.submit(() -> { + try { + ActivityManager.getService().setLockScreenShown(showing); + } catch (RemoteException e) { + } + }); } /** @@ -1846,7 +1865,10 @@ public class KeyguardViewMediator extends SystemUI { } if (!(mContext instanceof Activity)) { - mStatusBarManager.disable(flags); + final int finalFlags = flags; + mUiOffloadThread.submit(() -> { + mStatusBarManager.disable(finalFlags); + }); } } } @@ -2044,18 +2066,21 @@ public class KeyguardViewMediator extends SystemUI { mShowing = showing; int size = mKeyguardStateCallbacks.size(); for (int i = size - 1; i >= 0; i--) { + IKeyguardStateCallback callback = mKeyguardStateCallbacks.get(i); try { - mKeyguardStateCallbacks.get(i).onShowingStateChanged(showing); + callback.onShowingStateChanged(showing); } catch (RemoteException e) { Slog.w(TAG, "Failed to call onShowingStateChanged", e); if (e instanceof DeadObjectException) { - mKeyguardStateCallbacks.remove(i); + mKeyguardStateCallbacks.remove(callback); } } } updateInputRestrictedLocked(); - mTrustManager.reportKeyguardShowingChanged(); - updateActivityLockScreenState(); + mUiOffloadThread.submit(() -> { + mTrustManager.reportKeyguardShowingChanged(); + }); + updateActivityLockScreenState(showing); } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java index 6707c15ce84a..a155a71d442c 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java @@ -86,7 +86,9 @@ import android.view.accessibility.AccessibilityManager; import com.android.internal.app.AssistUtils; import com.android.internal.os.BackgroundThread; import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.UiOffloadThread; import com.android.systemui.pip.tv.PipMenuActivity; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsDebugFlags; @@ -152,7 +154,8 @@ public class SystemServicesProxy { Canvas mBgProtectionCanvas; private final Handler mHandler = new H(); - private final ExecutorService mOnewayExecutor = Executors.newSingleThreadExecutor(); + + private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class); /** * An abstract class to track task stack changes. @@ -784,7 +787,7 @@ public class SystemServicesProxy { * Sends a message to close other system windows. */ public void sendCloseSystemWindows(String reason) { - mOnewayExecutor.submit(() -> { + mUiOffloadThread.submit(() -> { try { mIam.closeSystemDialogs(reason); } catch (RemoteException e) { @@ -1139,7 +1142,7 @@ public class SystemServicesProxy { } public void startActivityAsUserAsync(Intent intent, ActivityOptions opts) { - mOnewayExecutor.submit(() -> mContext.startActivityAsUser(intent, + mUiOffloadThread.submit(() -> mContext.startActivityAsUser(intent, opts != null ? opts.toBundle() : null, UserHandle.CURRENT)); } @@ -1167,7 +1170,7 @@ public class SystemServicesProxy { // Execute this from another thread such that we can do other things (like caching the // bitmap for the thumbnail) while AM is busy starting our activity. - mOnewayExecutor.submit(() -> { + mUiOffloadThread.submit(() -> { try { mIam.startActivityFromRecents( taskKey.id, finalOptions == null ? null : finalOptions.toBundle()); @@ -1309,7 +1312,7 @@ public class SystemServicesProxy { } public void awakenDreamsAsync() { - mOnewayExecutor.submit(() -> { + mUiOffloadThread.submit(() -> { try { mDreamManager.awaken(); } catch (RemoteException e) { @@ -1320,7 +1323,7 @@ public class SystemServicesProxy { public void updateOverviewLastStackActiveTimeAsync(long newLastStackActiveTime, int currentUserId) { - mOnewayExecutor.submit(() -> { + mUiOffloadThread.submit(() -> { Settings.Secure.putLongForUser(mContext.getContentResolver(), Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME, newLastStackActiveTime, currentUserId); }); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 092408961eab..1691e135ae32 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -270,7 +270,7 @@ public class KeyguardIndicationController { return; } - if (!mUserManager.isUserUnlocked(ActivityManager.getCurrentUser())) { + if (!mUserManager.isUserUnlocked(KeyguardUpdateMonitor.getCurrentUser())) { mTextView.switchIndication(com.android.internal.R.string.lockscreen_storage_locked); mTextView.setTextColor(Color.WHITE); @@ -365,6 +365,9 @@ public class KeyguardIndicationController { }; public void setDozing(boolean dozing) { + if (mDozing == dozing) { + return; + } mDozing = dozing; updateIndication(); updateDisclosure(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index 21240118e5c6..95f32bb1d07b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone; import android.app.ActivityManager; import android.content.Context; +import android.os.Handler; import android.os.UserHandle; import android.os.UserManager; import android.util.Slog; @@ -55,6 +56,7 @@ public class KeyguardBouncer { protected final ViewGroup mContainer; private final FalsingManager mFalsingManager; private final DismissCallbackRegistry mDismissCallbackRegistry; + private final Handler mHandler; protected KeyguardHostView mKeyguardView; protected ViewGroup mRoot; private boolean mShowingSoon; @@ -66,6 +68,7 @@ public class KeyguardBouncer { mBouncerPromptReason = mCallback.getBouncerPromptReason(); } }; + private final Runnable mRemoveViewRunnable = this::removeView; public KeyguardBouncer(Context context, ViewMediatorCallback callback, LockPatternUtils lockPatternUtils, ViewGroup container, @@ -77,6 +80,7 @@ public class KeyguardBouncer { KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback); mFalsingManager = FalsingManager.getInstance(mContext); mDismissCallbackRegistry = dismissCallbackRegistry; + mHandler = new Handler(); } public void show(boolean resetSecuritySelection) { @@ -179,10 +183,14 @@ public class KeyguardBouncer { mKeyguardView.cancelDismissAction(); mKeyguardView.cleanUp(); } - if (destroyView) { - removeView(); - } else if (mRoot != null) { + if (mRoot != null) { mRoot.setVisibility(View.INVISIBLE); + if (destroyView) { + + // We have a ViewFlipper that unregisters a broadcast when being detached, which may + // be slow because of AM lock contention during unlocking. We can delay it a bit. + mHandler.postDelayed(mRemoveViewRunnable, 50); + } } } @@ -226,6 +234,7 @@ public class KeyguardBouncer { } protected void ensureView() { + mHandler.removeCallbacks(mRemoveViewRunnable); if (mRoot == null) { inflateView(); } @@ -233,6 +242,7 @@ public class KeyguardBouncer { protected void inflateView() { removeView(); + mHandler.removeCallbacks(mRemoveViewRunnable); mRoot = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.keyguard_bouncer, null); mKeyguardView = (KeyguardHostView) mRoot.findViewById(R.id.keyguard_host_view); mKeyguardView.setLockPatternUtils(mLockPatternUtils); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java index 45812042412c..52838b052bd4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java @@ -128,8 +128,7 @@ public class NotificationIconAreaController implements DarkReceiver { protected boolean shouldShowNotificationIcon(NotificationData.Entry entry, NotificationData notificationData, boolean showAmbient) { - if (notificationData.isAmbient(entry.key) && !showAmbient - && !NotificationData.showNotificationEvenIfUnprovisioned(entry.notification)) { + if (notificationData.isAmbient(entry.key) && !showAmbient) { return false; } if (!StatusBar.isTopLevelChild(entry)) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index 41fb5f7c220c..f3ba5aaf887d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -58,6 +58,7 @@ import com.android.systemui.Dependency; import com.android.systemui.DockedStackExistsListener; import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.UiOffloadThread; import com.android.systemui.qs.tiles.DndTile; import com.android.systemui.qs.tiles.RotationLockTile; import com.android.systemui.recents.misc.SystemServicesProxy; @@ -128,6 +129,7 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks, private final KeyguardMonitor mKeyguardMonitor; private final LocationController mLocationController; private final ArraySet<Pair<String, Integer>> mCurrentNotifs = new ArraySet<>(); + private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class); // Assume it's all good unless we hear otherwise. We don't always seem // to get broadcasts that it *is* there. @@ -472,30 +474,38 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks, } private void updateManagedProfile() { - try { - final boolean showIcon; - final int userId = ActivityManager.getService().getLastResumedActivityUserId(); - if (mUserManager.isManagedProfile(userId) && !mKeyguardMonitor.isShowing()) { - showIcon = true; - mIconController.setIcon(mSlotManagedProfile, - R.drawable.stat_sys_managed_profile_status, - mContext.getString(R.string.accessibility_managed_profile)); - } else if (mManagedProfileInQuietMode) { - showIcon = true; - mIconController.setIcon(mSlotManagedProfile, - R.drawable.stat_sys_managed_profile_status_off, - mContext.getString(R.string.accessibility_managed_profile)); - } else { - showIcon = false; - } - if (mManagedProfileIconVisible != showIcon) { - mIconController.setIconVisibility(mSlotManagedProfile, showIcon); - mManagedProfileIconVisible = showIcon; + // getLastResumedActivityUserId needds to acquire the AM lock, which may be contended in + // some cases. Since it doesn't really matter here whether it's updated in this frame + // or in the next one, we call this method from our UI offload thread. + mUiOffloadThread.submit(() -> { + final int userId; + try { + userId = ActivityManager.getService().getLastResumedActivityUserId(); + boolean isManagedProfile = mUserManager.isManagedProfile(userId); + mHandler.post(() -> { + final boolean showIcon; + if (isManagedProfile && !mKeyguardMonitor.isShowing()) { + showIcon = true; + mIconController.setIcon(mSlotManagedProfile, + R.drawable.stat_sys_managed_profile_status, + mContext.getString(R.string.accessibility_managed_profile)); + } else if (mManagedProfileInQuietMode) { + showIcon = true; + mIconController.setIcon(mSlotManagedProfile, + R.drawable.stat_sys_managed_profile_status_off, + mContext.getString(R.string.accessibility_managed_profile)); + } else { + showIcon = false; + } + if (mManagedProfileIconVisible != showIcon) { + mIconController.setIconVisibility(mSlotManagedProfile, showIcon); + mManagedProfileIconVisible = showIcon; + } + }); + } catch (RemoteException e) { + Log.w(TAG, "updateManagedProfile: ", e); } - } catch (RemoteException ex) { - Log.w(TAG, "updateManagedProfile: ", ex); - // ignore - } + }); } private void updateForegroundInstantApps() { @@ -503,26 +513,22 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks, ArraySet<Pair<String, Integer>> notifs = new ArraySet<>(mCurrentNotifs); IPackageManager pm = AppGlobals.getPackageManager(); mCurrentNotifs.clear(); - try { - ArraySet<Integer> stacksToCheck = new ArraySet<>(); - int[] STACKS_TO_CHECK = new int[]{ - StackId.FULLSCREEN_WORKSPACE_STACK_ID, - StackId.DOCKED_STACK_ID, - }; - int focusedId = ActivityManager.getService().getFocusedStackId(); - if (focusedId == StackId.FULLSCREEN_WORKSPACE_STACK_ID - || focusedId == StackId.FULLSCREEN_WORKSPACE_STACK_ID) { - checkStack(StackId.FULLSCREEN_WORKSPACE_STACK_ID, notifs, noMan, pm); - } - if (mDockedStackExists) { - checkStack(StackId.DOCKED_STACK_ID, notifs, noMan, pm); + mUiOffloadThread.submit(() -> { + try { + int focusedId = ActivityManager.getService().getFocusedStackId(); + if (focusedId == StackId.FULLSCREEN_WORKSPACE_STACK_ID) { + checkStack(StackId.FULLSCREEN_WORKSPACE_STACK_ID, notifs, noMan, pm); + } + if (mDockedStackExists) { + checkStack(StackId.DOCKED_STACK_ID, notifs, noMan, pm); + } + } catch (RemoteException e) { + e.rethrowFromSystemServer(); } - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - // Cancel all the leftover notifications that don't have a foreground process anymore. - notifs.forEach(v -> noMan.cancelAsUser(v.first, SystemMessage.NOTE_INSTANT_APPS, - new UserHandle(v.second))); + // Cancel all the leftover notifications that don't have a foreground process anymore. + notifs.forEach(v -> noMan.cancelAsUser(v.first, SystemMessage.NOTE_INSTANT_APPS, + new UserHandle(v.second))); + }); } private void checkStack(int stackId, ArraySet<Pair<String, Integer>> notifs, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 01bcd61952ff..d798fbf416df 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -83,6 +83,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.SystemService; import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; @@ -131,6 +132,7 @@ import com.android.systemui.Interpolators; import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.SystemUIFactory; +import com.android.systemui.UiOffloadThread; import com.android.systemui.assist.AssistManager; import com.android.systemui.classifier.FalsingLog; import com.android.systemui.classifier.FalsingManager; @@ -537,6 +539,7 @@ public class StatusBar extends SystemUI implements DemoMode, private ViewMediatorCallback mKeyguardViewMediatorCallback; protected ScrimController mScrimController; protected DozeScrimController mDozeScrimController; + private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class); private final Runnable mAutohide = new Runnable() { @Override @@ -4339,7 +4342,7 @@ public class StatusBar extends SystemUI implements DemoMode, checkBarModes(); updateMediaMetaData(false, mState != StatusBarState.KEYGUARD); mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(), - mStatusBarKeyguardViewManager.isSecure(), + mUnlockMethodCache.isMethodSecure(), mStatusBarKeyguardViewManager.isOccluded()); Trace.endSection(); } @@ -6884,11 +6887,13 @@ public class StatusBar extends SystemUI implements DemoMode, @Override public void logNotificationExpansion(String key, boolean userAction, boolean expanded) { - try { - mBarService.onNotificationExpansionChanged(key, userAction, expanded); - } catch (RemoteException e) { - // Ignore. - } + mUiOffloadThread.submit(() -> { + try { + mBarService.onNotificationExpansionChanged(key, userAction, expanded); + } catch (RemoteException e) { + // Ignore. + } + }); } public boolean isKeyguardSecure() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java index d6c080ad1f44..7bce33a2950d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java @@ -124,13 +124,11 @@ public class KeyguardMonitorImpl extends KeyguardUpdateMonitorCallback mKeyguardFadingAway = true; mKeyguardFadingAwayDelay = delay; mKeyguardFadingAwayDuration = fadeoutDuration; - notifyKeyguardChanged(); } public void notifyKeyguardDoneFading() { mKeyguardFadingAway = false; mKeyguardGoingAway = false; - notifyKeyguardChanged(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java index 53671a19a846..e1acc9b256d6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -872,7 +872,14 @@ public class UserSwitcherController { private final KeyguardMonitor.Callback mCallback = new KeyguardMonitor.Callback() { @Override public void onKeyguardShowingChanged() { - notifyAdapters(); + + // When Keyguard is going away, we don't need to update our items immediately which + // helps making the transition faster. + if (!mKeyguardMonitor.isShowing()) { + mHandler.post(UserSwitcherController.this::notifyAdapters); + } else { + notifyAdapters(); + } } }; diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java index aadae0f22c17..0aac1c01e175 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java +++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java @@ -21,15 +21,21 @@ import android.os.Looper; import android.os.MessageQueue; import android.support.test.InstrumentationRegistry; import android.testing.LeakCheck; +import android.util.Log; import org.junit.Before; import org.junit.Rule; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + /** * Base class that does System UI specific setup. */ public abstract class SysuiTestCase { + private static final String TAG = "SysuiTestCase"; + private Handler mHandler; @Rule public SysuiTestableContext mContext = new SysuiTestableContext( @@ -57,6 +63,15 @@ public abstract class SysuiTestCase { waitForIdleSync(mHandler); } + protected void waitForUiOffloadThread() { + Future<?> future = Dependency.get(UiOffloadThread.class).submit(() -> {}); + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + Log.e(TAG, "Failed to wait for ui offload thread.", e); + } + } + public static void waitForIdleSync(Handler h) { validateThread(h.getLooper()); Idler idler = new Idler(null); diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/DismissCallbackRegistryTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/DismissCallbackRegistryTest.java index 131a70b2c109..308670dc7cfb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/DismissCallbackRegistryTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/DismissCallbackRegistryTest.java @@ -23,6 +23,8 @@ import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import com.android.internal.policy.IKeyguardDismissCallback; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.UiOffloadThread; import org.junit.Before; import org.junit.Test; @@ -35,7 +37,7 @@ import org.mockito.MockitoAnnotations; */ @SmallTest @RunWith(AndroidJUnit4.class) -public class DismissCallbackRegistryTest { +public class DismissCallbackRegistryTest extends SysuiTestCase { private final DismissCallbackRegistry mDismissCallbackRegistry = new DismissCallbackRegistry(); private @Mock IKeyguardDismissCallback mMockCallback; @@ -50,6 +52,7 @@ public class DismissCallbackRegistryTest { public void testCancelled() throws Exception { mDismissCallbackRegistry.addCallback(mMockCallback); mDismissCallbackRegistry.notifyDismissCancelled(); + waitForUiOffloadThread(); verify(mMockCallback).onDismissCancelled(); } @@ -58,6 +61,7 @@ public class DismissCallbackRegistryTest { mDismissCallbackRegistry.addCallback(mMockCallback); mDismissCallbackRegistry.addCallback(mMockCallback2); mDismissCallbackRegistry.notifyDismissCancelled(); + waitForUiOffloadThread(); verify(mMockCallback).onDismissCancelled(); verify(mMockCallback2).onDismissCancelled(); } @@ -66,6 +70,7 @@ public class DismissCallbackRegistryTest { public void testSucceeded() throws Exception { mDismissCallbackRegistry.addCallback(mMockCallback); mDismissCallbackRegistry.notifyDismissSucceeded(); + waitForUiOffloadThread(); verify(mMockCallback).onDismissSucceeded(); } @@ -74,6 +79,7 @@ public class DismissCallbackRegistryTest { mDismissCallbackRegistry.addCallback(mMockCallback); mDismissCallbackRegistry.addCallback(mMockCallback2); mDismissCallbackRegistry.notifyDismissSucceeded(); + waitForUiOffloadThread(); verify(mMockCallback).onDismissSucceeded(); verify(mMockCallback2).onDismissSucceeded(); } @@ -83,6 +89,7 @@ public class DismissCallbackRegistryTest { mDismissCallbackRegistry.addCallback(mMockCallback); mDismissCallbackRegistry.notifyDismissSucceeded(); mDismissCallbackRegistry.notifyDismissSucceeded(); + waitForUiOffloadThread(); verify(mMockCallback, times(1)).onDismissSucceeded(); } } |