diff options
5 files changed, 72 insertions, 39 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index be50eb1934ad..afda2a406e00 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -55,8 +55,6 @@ import android.graphics.Region; import android.graphics.drawable.Drawable; import android.hardware.display.DisplayManager; import android.os.Handler; -import android.os.HandlerExecutor; -import android.os.HandlerThread; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings.Secure; @@ -91,11 +89,13 @@ import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.events.PrivacyDotViewController; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; +import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.concurrency.ThreadFactory; import com.android.systemui.util.settings.SecureSettings; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.Executor; import javax.inject.Inject; @@ -122,7 +122,7 @@ public class ScreenDecorations extends SystemUI implements Tunable { @VisibleForTesting protected boolean mIsRegistered; private final BroadcastDispatcher mBroadcastDispatcher; - private final Handler mMainHandler; + private final Executor mMainExecutor; private final TunerService mTunerService; private final SecureSettings mSecureSettings; private DisplayManager.DisplayListener mDisplayListener; @@ -153,6 +153,7 @@ public class ScreenDecorations extends SystemUI implements Tunable { private WindowManager mWindowManager; private int mRotation; private SecureSetting mColorInversionSetting; + private DelayableExecutor mExecutor; private Handler mHandler; private boolean mPendingRotationChange; private boolean mIsRoundedCornerMultipleRadius; @@ -212,7 +213,7 @@ public class ScreenDecorations extends SystemUI implements Tunable { @Inject public ScreenDecorations(Context context, - @Main Handler handler, + @Main Executor mainExecutor, SecureSettings secureSettings, BroadcastDispatcher broadcastDispatcher, TunerService tunerService, @@ -220,7 +221,7 @@ public class ScreenDecorations extends SystemUI implements Tunable { PrivacyDotViewController dotViewController, ThreadFactory threadFactory) { super(context); - mMainHandler = handler; + mMainExecutor = mainExecutor; mSecureSettings = secureSettings; mBroadcastDispatcher = broadcastDispatcher; mTunerService = tunerService; @@ -235,17 +236,10 @@ public class ScreenDecorations extends SystemUI implements Tunable { Log.i(TAG, "ScreenDecorations is disabled"); return; } - mHandler = startHandlerThread(); - mHandler.post(this::startOnScreenDecorationsThread); - mDotViewController.setUiExecutor( - mThreadFactory.buildDelayableExecutorOnLooper(mHandler.getLooper())); - } - - @VisibleForTesting - Handler startHandlerThread() { - HandlerThread thread = new HandlerThread("ScreenDecorations"); - thread.start(); - return thread.getThreadHandler(); + mHandler = mThreadFactory.builderHandlerOnNewThread("ScreenDecorations"); + mExecutor = mThreadFactory.buildDelayableExecutorOnHandler(mHandler); + mExecutor.execute(this::startOnScreenDecorationsThread); + mDotViewController.setUiExecutor(mExecutor); } private void startOnScreenDecorationsThread() { @@ -332,7 +326,7 @@ public class ScreenDecorations extends SystemUI implements Tunable { mDisplayManager.getDisplay(DEFAULT_DISPLAY).getMetrics(metrics); mDensity = metrics.density; - mMainHandler.post(() -> mTunerService.addTunable(this, SIZE)); + mExecutor.execute(() -> mTunerService.addTunable(this, SIZE)); // Watch color inversion and invert the overlay as needed. if (mColorInversionSetting == null) { @@ -351,10 +345,10 @@ public class ScreenDecorations extends SystemUI implements Tunable { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_USER_SWITCHED); mBroadcastDispatcher.registerReceiver(mUserSwitchIntentReceiver, filter, - new HandlerExecutor(mHandler), UserHandle.ALL); + mExecutor, UserHandle.ALL); mIsRegistered = true; } else { - mMainHandler.post(() -> mTunerService.removeTunable(this)); + mMainExecutor.execute(() -> mTunerService.removeTunable(this)); if (mColorInversionSetting != null) { mColorInversionSetting.setListening(false); @@ -567,7 +561,7 @@ public class ScreenDecorations extends SystemUI implements Tunable { Resources res = mContext.getResources(); boolean enabled = res.getBoolean(R.bool.config_enableDisplayCutoutProtection); if (enabled) { - mCameraListener = CameraAvailabilityListener.Factory.build(mContext, mHandler::post); + mCameraListener = CameraAvailabilityListener.Factory.build(mContext, mExecutor); mCameraListener.addTransitionCallback(mCameraTransitionCallback); mCameraListener.startListening(); } @@ -624,7 +618,7 @@ public class ScreenDecorations extends SystemUI implements Tunable { Log.i(TAG, "ScreenDecorations is disabled"); return; } - mHandler.post(() -> { + mExecutor.execute(() -> { int oldRotation = mRotation; mPendingRotationChange = false; updateOrientation(); @@ -825,7 +819,7 @@ public class ScreenDecorations extends SystemUI implements Tunable { Log.i(TAG, "ScreenDecorations is disabled"); return; } - mHandler.post(() -> { + mExecutor.execute(() -> { if (mOverlays == null) return; if (SIZE.equals(key)) { Point size = mRoundedDefault; diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactory.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactory.java index 2270f9631094..7a5ceb547d9e 100644 --- a/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactory.java +++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactory.java @@ -16,6 +16,7 @@ package com.android.systemui.util.concurrency; +import android.os.Handler; import android.os.Looper; import java.util.concurrent.Executor; @@ -29,6 +30,14 @@ import java.util.concurrent.Executor; */ public interface ThreadFactory { /** + * Returns a {@link Handler} running on a named thread. + * + * The thread is implicitly started and may be left running indefinitely, depending on the + * implementation. Assume this is the case and use responsibly. + */ + Handler builderHandlerOnNewThread(String threadName); + + /** * Return an {@link java.util.concurrent.Executor} running on a named thread. * * The thread is implicitly started and may be left running indefinitely, depending on the @@ -45,6 +54,11 @@ public interface ThreadFactory { DelayableExecutor buildDelayableExecutorOnNewThread(String threadName); /** + * Return an {@link DelayableExecutor} running on the given HandlerThread. + **/ + DelayableExecutor buildDelayableExecutorOnHandler(Handler handler); + + /** * Return an {@link DelayableExecutor} running the given Looper **/ DelayableExecutor buildDelayableExecutorOnLooper(Looper looper); diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactoryImpl.java index 2d9f2b424aae..184b83113d8d 100644 --- a/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactoryImpl.java +++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactoryImpl.java @@ -16,6 +16,7 @@ package com.android.systemui.util.concurrency; +import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -27,16 +28,31 @@ class ThreadFactoryImpl implements ThreadFactory { @Inject ThreadFactoryImpl() {} + @Override + public Handler builderHandlerOnNewThread(String threadName) { + HandlerThread handlerThread = new HandlerThread(threadName); + handlerThread.start(); + return new Handler(handlerThread.getLooper()); + } + + @Override public Executor buildExecutorOnNewThread(String threadName) { return buildDelayableExecutorOnNewThread(threadName); } + @Override public DelayableExecutor buildDelayableExecutorOnNewThread(String threadName) { HandlerThread handlerThread = new HandlerThread(threadName); handlerThread.start(); - return new ExecutorImpl(handlerThread.getLooper()); + return buildDelayableExecutorOnLooper(handlerThread.getLooper()); + } + + @Override + public DelayableExecutor buildDelayableExecutorOnHandler(Handler handler) { + return buildDelayableExecutorOnLooper(handler.getLooper()); } + @Override public DelayableExecutor buildDelayableExecutorOnLooper(Looper looper) { return new ExecutorImpl(looper); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java index b9ce20373755..ed5cbe20aa11 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java @@ -67,7 +67,6 @@ import com.android.systemui.statusbar.events.PrivacyDotViewController; import com.android.systemui.tuner.TunerService; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.concurrency.FakeThreadFactory; -import com.android.systemui.util.concurrency.ThreadFactory; import com.android.systemui.util.settings.FakeSettings; import com.android.systemui.util.settings.SecureSettings; import com.android.systemui.util.time.FakeSystemClock; @@ -87,13 +86,12 @@ public class ScreenDecorationsTest extends SysuiTestCase { private static final Rect ZERO_RECT = new Rect(); - private TestableLooper mTestableLooper; private ScreenDecorations mScreenDecorations; private WindowManager mWindowManager; private DisplayManager mDisplayManager; private SecureSettings mSecureSettings; - private Handler mMainHandler; - private ThreadFactory mThreadFactory; + private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock()); + private FakeThreadFactory mThreadFactory; @Mock private TunerService mTunerService; @Mock @@ -107,10 +105,10 @@ public class ScreenDecorationsTest extends SysuiTestCase { public void setup() { MockitoAnnotations.initMocks(this); - mTestableLooper = TestableLooper.get(this); - mMainHandler = new Handler(mTestableLooper.getLooper()); + Handler mainHandler = new Handler(TestableLooper.get(this).getLooper()); mSecureSettings = new FakeSettings(); - mThreadFactory = new FakeThreadFactory(new FakeExecutor(new FakeSystemClock())); + mThreadFactory = new FakeThreadFactory(mExecutor); + mThreadFactory.setHandler(mainHandler); mWindowManager = mock(WindowManager.class); WindowMetrics metrics = mContext.getSystemService(WindowManager.class) @@ -124,30 +122,25 @@ public class ScreenDecorationsTest extends SysuiTestCase { when(mDisplayManager.getDisplay(anyInt())).thenReturn(display); mContext.addMockSystemService(DisplayManager.class, mDisplayManager); - mScreenDecorations = spy(new ScreenDecorations(mContext, mMainHandler, mSecureSettings, + mScreenDecorations = spy(new ScreenDecorations(mContext, mExecutor, mSecureSettings, mBroadcastDispatcher, mTunerService, mUserTracker, mDotViewController, mThreadFactory) { @Override public void start() { super.start(); - mTestableLooper.processAllMessages(); - } - - @Override - Handler startHandlerThread() { - return new Handler(mTestableLooper.getLooper()); + mExecutor.runAllReady(); } @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); - mTestableLooper.processAllMessages(); + mExecutor.runAllReady(); } @Override public void onTuningChanged(String key, String newValue) { super.onTuningChanged(key, newValue); - mTestableLooper.processAllMessages(); + mExecutor.runAllReady(); } }); reset(mTunerService); diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeThreadFactory.java b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeThreadFactory.java index ce71ac880b07..570e1d86574e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeThreadFactory.java +++ b/packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeThreadFactory.java @@ -16,6 +16,7 @@ package com.android.systemui.util.concurrency; +import android.os.Handler; import android.os.Looper; import java.util.concurrent.Executor; @@ -25,11 +26,21 @@ import java.util.concurrent.Executor; */ public class FakeThreadFactory implements ThreadFactory { private final FakeExecutor mFakeExecutor; + private Handler mHandler; public FakeThreadFactory(FakeExecutor fakeExecutor) { mFakeExecutor = fakeExecutor; } + public void setHandler(Handler handler) { + mHandler = handler; + } + + @Override + public Handler builderHandlerOnNewThread(String threadName) { + return mHandler; + } + @Override public Executor buildExecutorOnNewThread(String threadName) { return mFakeExecutor; @@ -41,6 +52,11 @@ public class FakeThreadFactory implements ThreadFactory { } @Override + public DelayableExecutor buildDelayableExecutorOnHandler(Handler handler) { + return mFakeExecutor; + } + + @Override public DelayableExecutor buildDelayableExecutorOnLooper(Looper looper) { return mFakeExecutor; } |