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
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.util.concurrency;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -28,6 +29,14 @@ import java.util.concurrent.Executor;
|
||||
* threads; there are no singletons here. Use responsibly.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@@ -44,6 +53,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
|
||||
**/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
@@ -40,6 +51,11 @@ public class FakeThreadFactory implements ThreadFactory {
|
||||
return mFakeExecutor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DelayableExecutor buildDelayableExecutorOnHandler(Handler handler) {
|
||||
return mFakeExecutor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DelayableExecutor buildDelayableExecutorOnLooper(Looper looper) {
|
||||
return mFakeExecutor;
|
||||
|
||||
Reference in New Issue
Block a user