diff --git a/packages/SystemUI/plugin/Android.mk b/packages/SystemUI/plugin/Android.mk index 86527db878c63..05ee6b23c4b72 100644 --- a/packages/SystemUI/plugin/Android.mk +++ b/packages/SystemUI/plugin/Android.mk @@ -27,3 +27,13 @@ LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res LOCAL_JAR_EXCLUDE_FILES := none include $(BUILD_STATIC_JAVA_LIBRARY) + +include $(CLEAR_VARS) + +# Dummy to generate .toc files. +LOCAL_PACKAGE_NAME := PluginDummyLib +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_JAVA_LIBRARIES := SystemUIPluginLib + +include $(BUILD_PACKAGE) diff --git a/packages/SystemUI/plugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/SampleOverlayPlugin.java b/packages/SystemUI/plugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/SampleOverlayPlugin.java index a2f84dc7af2a4..13fc76c5da495 100644 --- a/packages/SystemUI/plugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/SampleOverlayPlugin.java +++ b/packages/SystemUI/plugin/ExamplePlugin/src/com/android/systemui/plugin/testoverlayplugin/SampleOverlayPlugin.java @@ -15,11 +15,14 @@ package com.android.systemui.plugin.testoverlayplugin; import android.content.Context; +import android.graphics.Rect; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.ViewTreeObserver.InternalInsetsInfo; +import android.view.ViewTreeObserver.OnComputeInternalInsetsListener; import com.android.systemui.plugins.OverlayPlugin; public class SampleOverlayPlugin implements OverlayPlugin { @@ -28,6 +31,9 @@ public class SampleOverlayPlugin implements OverlayPlugin { private View mStatusBarView; private View mNavBarView; + private boolean mInputSetup; + private boolean mCollapseDesired; + private float mStatusBarHeight; @Override public int getVersion() { @@ -43,6 +49,10 @@ public class SampleOverlayPlugin implements OverlayPlugin { @Override public void onDestroy() { + if (mInputSetup) { + mStatusBarView.getViewTreeObserver().removeOnComputeInternalInsetsListener( + onComputeInternalInsetsListener); + } Log.d(TAG, "onDestroy"); if (mStatusBarView != null) { mStatusBarView.post( @@ -57,6 +67,9 @@ public class SampleOverlayPlugin implements OverlayPlugin { public void setup(View statusBar, View navBar) { Log.d(TAG, "Setup"); + int id = mPluginContext.getResources().getIdentifier("status_bar_height", "dimen", + "android"); + mStatusBarHeight = mPluginContext.getResources().getDimension(id); if (statusBar instanceof ViewGroup) { mStatusBarView = LayoutInflater.from(mPluginContext) .inflate(R.layout.colored_overlay, (ViewGroup) statusBar, false); @@ -68,4 +81,28 @@ public class SampleOverlayPlugin implements OverlayPlugin { ((ViewGroup) navBar).addView(mNavBarView); } } + + @Override + public void setCollapseDesired(boolean collapseDesired) { + mCollapseDesired = collapseDesired; + } + + @Override + public boolean holdStatusBarOpen() { + if (!mInputSetup) { + mInputSetup = true; + mStatusBarView.getViewTreeObserver().addOnComputeInternalInsetsListener( + onComputeInternalInsetsListener); + } + return true; + } + + final OnComputeInternalInsetsListener onComputeInternalInsetsListener = inoutInfo -> { + inoutInfo.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_REGION); + if (mCollapseDesired) { + inoutInfo.touchableRegion.set(new Rect(0, 0, 50000, (int) mStatusBarHeight)); + } else { + inoutInfo.touchableRegion.set(new Rect(0, 0, 50000, 50000)); + } + }; } diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/OverlayPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/OverlayPlugin.java index 91a260435eaa9..f5074f75b7a49 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/OverlayPlugin.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/OverlayPlugin.java @@ -21,4 +21,14 @@ public interface OverlayPlugin extends Plugin { int VERSION = 1; void setup(View statusBar, View navBar); + + default boolean holdStatusBarOpen() { + return false; + } + + /** + * Only called if the plugin has returned true to holdStatusBarOpen(). + */ + default void setCollapseDesired(boolean collapseDesired) { + } } diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index e1f3176d808e6..7066a1b7ca255 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -27,6 +27,7 @@ import com.android.systemui.assist.AssistManager; import com.android.systemui.plugins.PluginManager; import com.android.systemui.statusbar.phone.ManagedProfileController; import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl; +import com.android.systemui.statusbar.phone.StatusBarWindowManager; import com.android.systemui.statusbar.policy.AccessibilityController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BatteryControllerImpl; @@ -183,6 +184,9 @@ public class Dependency extends SystemUI { mProviders.put(TunerService.class.getName(), () -> new TunerService(mContext)); + mProviders.put(StatusBarWindowManager.class.getName(), () -> + new StatusBarWindowManager(mContext)); + // 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/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index 27070edc73e59..e5bda7edfc589 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -27,6 +27,7 @@ import android.content.res.Configuration; import android.os.Process; import android.os.SystemProperties; import android.os.UserHandle; +import android.util.ArraySet; import android.util.Log; import com.android.systemui.fragments.FragmentService; @@ -43,6 +44,7 @@ import com.android.systemui.shortcut.ShortcutKeyDispatcher; import com.android.systemui.stackdivider.Divider; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.phone.StatusBar; +import com.android.systemui.statusbar.phone.StatusBarWindowManager; import com.android.systemui.tuner.TunerService; import com.android.systemui.usb.StorageNotification; import com.android.systemui.util.NotificationChannels; @@ -149,7 +151,6 @@ public class SystemUIApplication extends Application implements SysUiServiceProv * Makes sure that all the SystemUI services are running. If they are already running, this is a * no-op. This is needed to conditinally start all the services, as we only need to have it in * the main process. - * *

This method must only be called from the main thread.

*/ public void startServicesIfNeeded() { @@ -160,7 +161,6 @@ public class SystemUIApplication extends Application implements SysUiServiceProv * Ensures that all the Secondary user SystemUI services are running. If they are already * running, this is a no-op. This is needed to conditinally start all the services, as we only * need to have it in the main process. - * *

This method must only be called from the main thread.

*/ void startSecondaryUserServicesIfNeeded() { @@ -184,7 +184,7 @@ public class SystemUIApplication extends Application implements SysUiServiceProv Log.v(TAG, "Starting SystemUI services for user " + Process.myUserHandle().getIdentifier() + "."); final int N = services.length; - for (int i=0; i cl = services[i]; if (DEBUG) Log.d(TAG, "loading: " + cl); try { @@ -207,15 +207,34 @@ public class SystemUIApplication extends Application implements SysUiServiceProv } Dependency.get(PluginManager.class).addPluginListener(OverlayPlugin.ACTION, new PluginListener() { - @Override - public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) { - StatusBar statusBar = getComponent(StatusBar.class); - if (statusBar != null) { - plugin.setup(statusBar.getStatusBarWindow(), - statusBar.getNavigationBarView()); - } - } - }, OverlayPlugin.VERSION, true /* Allow multiple plugins */); + private ArraySet mOverlays; + + @Override + public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) { + StatusBar statusBar = getComponent(StatusBar.class); + if (statusBar != null) { + plugin.setup(statusBar.getStatusBarWindow(), + statusBar.getNavigationBarView()); + } + // Lazy init. + if (mOverlays == null) mOverlays = new ArraySet<>(); + if (plugin.holdStatusBarOpen()) { + mOverlays.add(plugin); + Dependency.get(StatusBarWindowManager.class).setStateListener(b -> + mOverlays.forEach(o -> o.setCollapseDesired(b))); + Dependency.get(StatusBarWindowManager.class).setForcePluginOpen( + mOverlays.size() != 0); + + } + } + + @Override + public void onPluginDisconnected(OverlayPlugin plugin) { + mOverlays.remove(plugin); + Dependency.get(StatusBarWindowManager.class).setForcePluginOpen( + mOverlays.size() != 0); + } + }, OverlayPlugin.VERSION, true /* Allow multiple plugins */); mServicesStarted = true; } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 99c8c6bacc62f..cbe822f2205dc 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -1956,11 +1956,11 @@ public class KeyguardViewMediator extends SystemUI { } public StatusBarKeyguardViewManager registerStatusBar(StatusBar statusBar, - ViewGroup container, StatusBarWindowManager statusBarWindowManager, + ViewGroup container, ScrimController scrimController, FingerprintUnlockController fingerprintUnlockController) { mStatusBarKeyguardViewManager.registerStatusBar(statusBar, container, - statusBarWindowManager, scrimController, fingerprintUnlockController, + scrimController, fingerprintUnlockController, mDismissCallbackRegistry); return mStatusBarKeyguardViewManager; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java index 66cc15d7cc8f5..7f28c4c2e7a43 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar; import com.android.internal.util.Preconditions; +import com.android.systemui.Dependency; import com.android.systemui.statusbar.phone.StatusBarWindowManager; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.RemoteInputView; @@ -39,8 +40,8 @@ public class RemoteInputController { private final ArrayList mCallbacks = new ArrayList<>(3); private final HeadsUpManager mHeadsUpManager; - public RemoteInputController(StatusBarWindowManager sbwm, HeadsUpManager headsUpManager) { - addCallback(sbwm); + public RemoteInputController(HeadsUpManager headsUpManager) { + addCallback(Dependency.get(StatusBarWindowManager.class)); mHeadsUpManager = headsUpManager; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java index 0773108b3d600..2bb3cbc31cebb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java @@ -27,6 +27,7 @@ import com.android.keyguard.KeyguardConstants; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.LatencyTracker; +import com.android.systemui.Dependency; import com.android.systemui.keyguard.KeyguardViewMediator; /** @@ -101,7 +102,6 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback { private int mPendingAuthenticatedUserId = -1; public FingerprintUnlockController(Context context, - StatusBarWindowManager statusBarWindowManager, DozeScrimController dozeScrimController, KeyguardViewMediator keyguardViewMediator, ScrimController scrimController, @@ -111,7 +111,7 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback { mPowerManager = context.getSystemService(PowerManager.class); mUpdateMonitor = KeyguardUpdateMonitor.getInstance(context); mUpdateMonitor.registerCallback(this); - mStatusBarWindowManager = statusBarWindowManager; + mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class); mDozeScrimController = dozeScrimController; mKeyguardViewMediator = keyguardViewMediator; mScrimController = scrimController; 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 bffa14fb2296f..60503e767605f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -1434,10 +1434,10 @@ public class StatusBar extends SystemUI implements DemoMode, Trace.beginSection("StatusBar#startKeyguard"); KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class); mFingerprintUnlockController = new FingerprintUnlockController(mContext, - mStatusBarWindowManager, mDozeScrimController, keyguardViewMediator, + mDozeScrimController, keyguardViewMediator, mScrimController, this, UnlockMethodCache.getInstance(mContext)); mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this, - getBouncerContainer(), mStatusBarWindowManager, mScrimController, + getBouncerContainer(), mScrimController, mFingerprintUnlockController); mKeyguardIndicationController.setStatusBarKeyguardViewManager( mStatusBarKeyguardViewManager); @@ -3384,9 +3384,6 @@ public class StatusBar extends SystemUI implements DemoMode, pw.print(" status bar gestures: "); mGestureRec.dump(fd, pw, args); } - if (mStatusBarWindowManager != null) { - mStatusBarWindowManager.dump(fd, pw, args); - } if (mHeadsUpManager != null) { mHeadsUpManager.dump(fd, pw, args); @@ -3425,9 +3422,8 @@ public class StatusBar extends SystemUI implements DemoMode, private void addStatusBarWindow() { makeStatusBarView(); - mStatusBarWindowManager = new StatusBarWindowManager(mContext); - mRemoteInputController = new RemoteInputController(mStatusBarWindowManager, - mHeadsUpManager); + mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class); + mRemoteInputController = new RemoteInputController(mHeadsUpManager); mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight()); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 8d5d890b07adf..2a69c1e663bbc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -32,6 +32,7 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.DejankUtils; import com.android.keyguard.LatencyTracker; +import com.android.systemui.Dependency; import com.android.systemui.SystemUIFactory; import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.statusbar.CommandQueue; @@ -67,6 +68,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb private static String TAG = "StatusBarKeyguardViewManager"; protected final Context mContext; + private final StatusBarWindowManager mStatusBarWindowManager; protected LockPatternUtils mLockPatternUtils; protected ViewMediatorCallback mViewMediatorCallback; @@ -75,7 +77,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb private FingerprintUnlockController mFingerprintUnlockController; private ViewGroup mContainer; - private StatusBarWindowManager mStatusBarWindowManager; private boolean mDeviceInteractive = false; private boolean mScreenTurnedOn; @@ -101,16 +102,16 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mContext = context; mViewMediatorCallback = callback; mLockPatternUtils = lockPatternUtils; + mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class); } public void registerStatusBar(StatusBar statusBar, - ViewGroup container, StatusBarWindowManager statusBarWindowManager, + ViewGroup container, ScrimController scrimController, FingerprintUnlockController fingerprintUnlockController, DismissCallbackRegistry dismissCallbackRegistry) { mStatusBar = statusBar; mContainer = container; - mStatusBarWindowManager = statusBarWindowManager; mScrimController = scrimController; mFingerprintUnlockController = fingerprintUnlockController; mBouncer = SystemUIFactory.getInstance().createKeyguardBouncer(mContext, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java index 16999b2f454f9..deb0070ccbc01 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java @@ -32,6 +32,7 @@ import android.view.ViewGroup; import android.view.WindowManager; import com.android.keyguard.R; +import com.android.systemui.Dumpable; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.StatusBarState; @@ -43,7 +44,7 @@ import java.lang.reflect.Field; /** * Encapsulates all logic for the status bar window state management. */ -public class StatusBarWindowManager implements RemoteInputController.Callback { +public class StatusBarWindowManager implements RemoteInputController.Callback, Dumpable { private static final String TAG = "StatusBarWindowManager"; @@ -59,6 +60,7 @@ public class StatusBarWindowManager implements RemoteInputController.Callback { private final boolean mKeyguardScreenRotation; private final float mScreenBrightnessDoze; private final State mCurrentState = new State(); + private OtherwisedCollapsedListener mListener; public StatusBarWindowManager(Context context) { mContext = context; @@ -154,6 +156,10 @@ public class StatusBarWindowManager implements RemoteInputController.Callback { private void applyHeight(State state) { boolean expanded = isExpanded(state); + if (state.forcePluginOpen) { + mListener.setWouldOtherwiseCollapse(expanded); + expanded = true; + } if (expanded) { mLpChanged.height = ViewGroup.LayoutParams.MATCH_PARENT; } else { @@ -356,6 +362,15 @@ public class StatusBarWindowManager implements RemoteInputController.Callback { apply(mCurrentState); } + public void setForcePluginOpen(boolean forcePluginOpen) { + mCurrentState.forcePluginOpen = forcePluginOpen; + apply(mCurrentState); + } + + public void setStateListener(OtherwisedCollapsedListener listener) { + mListener = listener; + } + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("StatusBarWindowManager state:"); pw.println(mCurrentState); @@ -388,6 +403,7 @@ public class StatusBarWindowManager implements RemoteInputController.Callback { int statusBarState; boolean remoteInputActive; + boolean forcePluginOpen; private boolean isKeyguardShowingAndNotOccluded() { return keyguardShowing && !keyguardOccluded; @@ -419,4 +435,13 @@ public class StatusBarWindowManager implements RemoteInputController.Callback { return result.toString(); } } + + /** + * Custom listener to pipe data back to plugins about whether or not the status bar would be + * collapsed if not for the plugin. + * TODO: Find cleaner way to do this. + */ + public interface OtherwisedCollapsedListener { + void setWouldOtherwiseCollapse(boolean otherwiseCollapse); + } }