Move global actions to sysui and add plugin interface
- Move default global actions ui to sysui
- Add fallback legacy interface in case sysui breaks
- Switch to fallback if sysui dies or isn't responding
Test: Long-press power
Change-Id: I943522611de5dbbee61e66c67cf3a56379091e97
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index b4467af..135b20d 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -76,4 +76,26 @@
void toggleRecentApps();
void setCurrentUser(int newUserId);
+
+ void setGlobalActionsListener(GlobalActionsListener listener);
+ void showGlobalActions();
+
+ public interface GlobalActionsListener {
+ /**
+ * Called when sysui starts and connects its status bar, or when the status bar binder
+ * dies indicating sysui is no longer alive.
+ */
+ void onStatusBarConnectedChanged(boolean connected);
+
+ /**
+ * Callback from sysui to notify system that global actions has been successfully shown.
+ */
+ void onGlobalActionsShown();
+
+ /**
+ * Callback from sysui to notify system that the user has dismissed global actions and
+ * it no longer needs to be displayed (even if sysui dies).
+ */
+ void onGlobalActionsDismissed();
+ }
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 2dfe20a8..aaaa080 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -25,6 +25,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
@@ -40,6 +41,8 @@
import com.android.internal.statusbar.StatusBarIcon;
import com.android.server.LocalServices;
import com.android.server.notification.NotificationDelegate;
+import com.android.server.power.ShutdownThread;
+import com.android.server.statusbar.StatusBarManagerInternal.GlobalActionsListener;
import com.android.server.wm.WindowManagerService;
import java.io.FileDescriptor;
@@ -65,6 +68,7 @@
// for disabling the status bar
private final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
+ private GlobalActionsListener mGlobalActionListener;
private IBinder mSysUiVisToken = new Binder();
private int mDisabled1 = 0;
private int mDisabled2 = 0;
@@ -307,6 +311,21 @@
} catch (RemoteException ex) {}
}
}
+
+ @Override
+ public void setGlobalActionsListener(GlobalActionsListener listener) {
+ mGlobalActionListener = listener;
+ mGlobalActionListener.onStatusBarConnectedChanged(mBar != null);
+ }
+
+ @Override
+ public void showGlobalActions() {
+ if (mBar != null) {
+ try {
+ mBar.showGlobalActionsMenu();
+ } catch (RemoteException ex) {}
+ }
+ }
};
// ================================================================================
@@ -656,6 +675,17 @@
Slog.i(TAG, "registerStatusBar bar=" + bar);
mBar = bar;
+ try {
+ mBar.asBinder().linkToDeath(new DeathRecipient() {
+ @Override
+ public void binderDied() {
+ mBar = null;
+ notifyBarAttachChanged();
+ }
+ }, 0);
+ } catch (RemoteException e) {
+ }
+ notifyBarAttachChanged();
synchronized (mIcons) {
for (String slot : mIcons.keySet()) {
iconSlots.add(slot);
@@ -678,6 +708,13 @@
}
}
+ private void notifyBarAttachChanged() {
+ mHandler.post(() -> {
+ if (mGlobalActionListener == null) return;
+ mGlobalActionListener.onStatusBarConnectedChanged(mBar != null);
+ });
+ }
+
/**
* @param clearNotificationEffects whether to consider notifications as "shown" and stop
* LED, vibration, and ringing
@@ -715,6 +752,65 @@
}
}
+ /**
+ * Allows the status bar to shutdown the device.
+ */
+ @Override
+ public void shutdown() {
+ enforceStatusBarService();
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mHandler.post(() ->
+ ShutdownThread.shutdown(mContext, PowerManager.SHUTDOWN_USER_REQUESTED, false));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
+ * Allows the status bar to reboot the device.
+ */
+ @Override
+ public void reboot(boolean safeMode) {
+ enforceStatusBarService();
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mHandler.post(() -> {
+ if (safeMode) {
+ ShutdownThread.rebootSafeMode(mContext, false);
+ } else {
+ ShutdownThread.reboot(mContext, PowerManager.SHUTDOWN_USER_REQUESTED, false);
+ }
+ });
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void onGlobalActionsShown() {
+ enforceStatusBarService();
+ long identity = Binder.clearCallingIdentity();
+ try {
+ if (mGlobalActionListener == null) return;
+ mGlobalActionListener.onGlobalActionsShown();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void onGlobalActionsHidden() {
+ enforceStatusBarService();
+ long identity = Binder.clearCallingIdentity();
+ try {
+ if (mGlobalActionListener == null) return;
+ mGlobalActionListener.onGlobalActionsDismissed();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
@Override
public void onNotificationClick(String key) {
enforceStatusBarService();