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);
+ }
}