summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Dave Mankoff <mankoff@google.com> 2021-05-07 15:39:00 -0400
committer Dave Mankoff <mankoff@google.com> 2021-05-07 16:45:46 -0400
commit047161d25c9780d9bcbfe4d44aa7319cec0c8e2c (patch)
treee35d349fd9e2d4e3ff6e4a68687a16e7cd908da2
parent4b419f08d512fcad4df030c8833d162523f4f5a2 (diff)
Add more utitlities to ThreadFactory.
Add the ability to create Handlers in TheadFactory, as well as the ability to create Executors from Handlers. Use these in ScreenDecorations. Also, use the executor rather than then handler in ScreenDecorations where possible. Bug: 177323724 Test: atest SystemUITests Change-Id: Icaedbfe3dc89f5bbc00c780533cb46279c2d2088
-rw-r--r--packages/SystemUI/src/com/android/systemui/ScreenDecorations.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactory.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/concurrency/ThreadFactoryImpl.java18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java25
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/concurrency/FakeThreadFactory.java16
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;
}