Introduce a result class for IStatusBarService#registerStatusBar()

This is a preparation to fix an issue that IME cannot enable light
navigation bar on direct-reply.

The initial state of StatusBar client is provided as return values of
IStatusBarService#registerStatusBar().  However, the way for the
client to receive the return values is to rely on "out" parameters in
the Binder method as follows.

    void registerStatusBar(IStatusBar callbacks,
            out List<String> iconSlots,
            out List<StatusBarIcon> iconList,
            out int[] switches,
            out List<IBinder> binders,
            out Rect fullscreenStackBounds,
            out Rect dockedStackBounds);

The issue is that if I want to add a new parameter into
StatusBarManagerService to fix Bug 122439339, then it needs to be
notified back to the client via one of these out values, e.g. a new
element in "switches", which is hard to understand and maintain.

It'd be better to introduce a dedicated return object as follows.

    RegisterStatusBarResult registerStatusBar(IStatusBar callbacks);

This is a purely mechanical code clean-up.  Hence there should be no
behavior change.

Bug: 122439339
Test: presubmit
Change-Id: Ib1c0ae8f591ca09d0bce7a39f85ba57aad386e47
diff --git a/Android.bp b/Android.bp
index 5b8e6e1..7cc2f30 100644
--- a/Android.bp
+++ b/Android.bp
@@ -436,6 +436,7 @@
         "core/java/com/android/internal/os/IShellCallback.aidl",
         "core/java/com/android/internal/statusbar/IStatusBar.aidl",
         "core/java/com/android/internal/statusbar/IStatusBarService.aidl",
+        "core/java/com/android/internal/statusbar/RegisterStatusBarResult.aidl",
         "core/java/com/android/internal/textservice/ISpellCheckerService.aidl",
         "core/java/com/android/internal/textservice/ISpellCheckerServiceCallback.aidl",
         "core/java/com/android/internal/textservice/ISpellCheckerSession.aidl",
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 3437614..5fee2c9 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -24,6 +24,7 @@
 import android.hardware.biometrics.IBiometricServiceReceiverInternal;
 
 import com.android.internal.statusbar.IStatusBar;
+import com.android.internal.statusbar.RegisterStatusBarResult;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.statusbar.StatusBarIconList;
 import com.android.internal.statusbar.NotificationVisibility;
@@ -54,10 +55,7 @@
 
     // ---- Methods below are for use by the status bar policy services ----
     // You need the STATUS_BAR_SERVICE permission
-    void registerStatusBar(IStatusBar callbacks, out List<String> iconSlots,
-            out List<StatusBarIcon> iconList,
-            out int[] switches, out List<IBinder> binders, out Rect fullscreenStackBounds,
-            out Rect dockedStackBounds);
+    RegisterStatusBarResult registerStatusBar(IStatusBar callbacks);
     void onPanelRevealed(boolean clearNotificationEffects, int numItems);
     void onPanelHidden();
     // Mark current notifications as "seen" and stop ringing, vibrating, blinking.
diff --git a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.aidl b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.aidl
new file mode 100644
index 0000000..ec2e604
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.statusbar;
+
+parcelable RegisterStatusBarResult;
diff --git a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
new file mode 100644
index 0000000..b47ef12
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.statusbar;
+
+import android.graphics.Rect;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.ArrayMap;
+
+/**
+ * An immutable data object to return a set of values from StatusBarManagerService to its clients.
+ */
+public final class RegisterStatusBarResult implements Parcelable {
+    public final ArrayMap<String, StatusBarIcon> mIcons;
+    public final int mDisabledFlags1;                  // switch[0]
+    public final int mSystemUiVisibility;              // switch[1]
+    public final boolean mMenuVisible;                 // switch[2]
+    public final int mImeWindowVis;                    // switch[3]
+    public final int mImeBackDisposition;              // switch[4]
+    public final boolean mShowImeSwitcher;             // switch[5]
+    public final int mDisabledFlags2;                  // switch[6]
+    public final int mFullscreenStackSysUiVisibility;  // switch[7]
+    public final int mDockedStackSysUiVisibility;      // switch[8]
+    public final IBinder mImeToken;
+    public final Rect mFullscreenStackBounds;
+    public final Rect mDockedStackBounds;
+
+    public RegisterStatusBarResult(ArrayMap<String, StatusBarIcon> icons, int disabledFlags1,
+            int systemUiVisibility, boolean menuVisible, int imeWindowVis, int imeBackDisposition,
+            boolean showImeSwitcher, int disabledFlags2, int fullscreenStackSysUiVisibility,
+            int dockedStackSysUiVisibility, IBinder imeToken, Rect fullscreenStackBounds,
+            Rect dockedStackBounds) {
+        mIcons = new ArrayMap<>(icons);
+        mDisabledFlags1 = disabledFlags1;
+        mSystemUiVisibility = systemUiVisibility;
+        mMenuVisible = menuVisible;
+        mImeWindowVis = imeWindowVis;
+        mImeBackDisposition = imeBackDisposition;
+        mShowImeSwitcher = showImeSwitcher;
+        mDisabledFlags2 = disabledFlags2;
+        mFullscreenStackSysUiVisibility = fullscreenStackSysUiVisibility;
+        mDockedStackSysUiVisibility = dockedStackSysUiVisibility;
+        mImeToken = imeToken;
+        mFullscreenStackBounds = fullscreenStackBounds;
+        mDockedStackBounds = dockedStackBounds;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeTypedArrayMap(mIcons, flags);
+        dest.writeInt(mDisabledFlags1);
+        dest.writeInt(mSystemUiVisibility);
+        dest.writeBoolean(mMenuVisible);
+        dest.writeInt(mImeWindowVis);
+        dest.writeInt(mImeBackDisposition);
+        dest.writeBoolean(mShowImeSwitcher);
+        dest.writeInt(mDisabledFlags2);
+        dest.writeInt(mFullscreenStackSysUiVisibility);
+        dest.writeInt(mDockedStackSysUiVisibility);
+        dest.writeStrongBinder(mImeToken);
+        dest.writeParcelable(mFullscreenStackBounds, flags);
+        dest.writeParcelable(mDockedStackBounds, flags);
+    }
+
+    /**
+     * Used to make this class parcelable.
+     */
+    public static final Parcelable.Creator<RegisterStatusBarResult> CREATOR =
+            new Parcelable.Creator<RegisterStatusBarResult>() {
+                @Override
+                public RegisterStatusBarResult createFromParcel(Parcel source) {
+                    final ArrayMap<String, StatusBarIcon> icons =
+                            source.createTypedArrayMap(StatusBarIcon.CREATOR);
+                    final int disabledFlags1 = source.readInt();
+                    final int systemUiVisibility = source.readInt();
+                    final boolean menuVisible = source.readBoolean();
+                    final int imeWindowVis = source.readInt();
+                    final int imeBackDisposition = source.readInt();
+                    final boolean showImeSwitcher = source.readBoolean();
+                    final int disabledFlags2 = source.readInt();
+                    final int fullscreenStackSysUiVisibility = source.readInt();
+                    final int dockedStackSysUiVisibility = source.readInt();
+                    final IBinder imeToken = source.readStrongBinder();
+                    final Rect fullscreenStackBounds = Rect.CREATOR.createFromParcel(source);
+                    final Rect dockedStackBounds = Rect.CREATOR.createFromParcel(source);
+                    return new RegisterStatusBarResult(icons, disabledFlags1, systemUiVisibility,
+                            menuVisible, imeWindowVis, imeBackDisposition, showImeSwitcher,
+                            disabledFlags2, fullscreenStackSysUiVisibility,
+                            dockedStackSysUiVisibility, imeToken, fullscreenStackBounds,
+                            dockedStackBounds);
+                }
+
+                @Override
+                public RegisterStatusBarResult[] newArray(int size) {
+                    return new RegisterStatusBarResult[size];
+                }
+            };
+}
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 e5defae1..b34e24e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -81,7 +81,6 @@
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
@@ -123,7 +122,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.statusbar.RegisterStatusBarResult;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
@@ -690,17 +689,11 @@
         mCommandQueue = getComponent(CommandQueue.class);
         mCommandQueue.addCallback(this);
 
-        int[] switches = new int[9];
-        ArrayList<IBinder> binders = new ArrayList<>();
-        ArrayList<String> iconSlots = new ArrayList<>();
-        ArrayList<StatusBarIcon> icons = new ArrayList<>();
-        Rect fullscreenStackBounds = new Rect();
-        Rect dockedStackBounds = new Rect();
+        RegisterStatusBarResult result = null;
         try {
-            mBarService.registerStatusBar(mCommandQueue, iconSlots, icons, switches, binders,
-                    fullscreenStackBounds, dockedStackBounds);
+            result = mBarService.registerStatusBar(mCommandQueue);
         } catch (RemoteException ex) {
-            // If the system process isn't there we're doomed anyway.
+            ex.rethrowFromSystemServer();
         }
 
         createAndAddWindows();
@@ -714,28 +707,29 @@
         // Set up the initial notification state. This needs to happen before CommandQueue.disable()
         setUpPresenter();
 
-        setSystemUiVisibility(mDisplayId, switches[1], switches[7], switches[8], 0xffffffff,
-                fullscreenStackBounds, dockedStackBounds);
-        topAppWindowChanged(mDisplayId, switches[2] != 0);
+        setSystemUiVisibility(mDisplayId, result.mSystemUiVisibility,
+                result.mFullscreenStackSysUiVisibility, result.mDockedStackSysUiVisibility,
+                0xffffffff, result.mFullscreenStackBounds, result.mDockedStackBounds);
+        topAppWindowChanged(mDisplayId, result.mMenuVisible);
         // StatusBarManagerService has a back up of IME token and it's restored here.
-        setImeWindowStatus(mDisplayId, binders.get(0), switches[3], switches[4], switches[5] != 0);
+        setImeWindowStatus(mDisplayId, result.mImeToken, result.mImeWindowVis,
+                result.mImeBackDisposition, result.mShowImeSwitcher);
 
         // Set up the initial icon state
-        int N = iconSlots.size();
-        for (int i=0; i < N; i++) {
-            mCommandQueue.setIcon(iconSlots.get(i), icons.get(i));
+        int numIcons = result.mIcons.size();
+        for (int i = 0; i < numIcons; i++) {
+            mCommandQueue.setIcon(result.mIcons.keyAt(i), result.mIcons.valueAt(i));
         }
 
 
         if (DEBUG) {
             Log.d(TAG, String.format(
                     "init: icons=%d disabled=0x%08x lights=0x%08x menu=0x%08x imeButton=0x%08x",
-                   icons.size(),
-                   switches[0],
-                   switches[1],
-                   switches[2],
-                   switches[3]
-                   ));
+                    numIcons,
+                    result.mDisabledFlags1,
+                    result.mSystemUiVisibility,
+                    result.mMenuVisible ? 1 : 0,
+                    result.mImeWindowVis));
         }
 
         IntentFilter internalFilter = new IntentFilter();
@@ -774,9 +768,10 @@
 
         // set the initial view visibility
         Dependency.get(InitController.class).addPostInitTask(this::updateAreThereNotifications);
-        Dependency.get(InitController.class).addPostInitTask(() -> {
-            setUpDisableFlags(switches[0], switches[6]);
-        });
+        int disabledFlags1 = result.mDisabledFlags1;
+        int disabledFlags2 = result.mDisabledFlags2;
+        Dependency.get(InitController.class).addPostInitTask(
+                () -> setUpDisableFlags(disabledFlags1, disabledFlags2));
 
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index 4a69cd7..17d9cbe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -17,19 +17,14 @@
 package com.android.systemui.statusbar.tv;
 
 import android.content.Context;
-import android.graphics.Rect;
-import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 
 import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.SystemUI;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CommandQueue.Callbacks;
 
-import java.util.ArrayList;
-
 /**
  * Status bar implementation for "large screen" products that mostly present no on-screen nav
  */
@@ -43,17 +38,10 @@
         putComponent(TvStatusBar.class, this);
         CommandQueue commandQueue = getComponent(CommandQueue.class);
         commandQueue.addCallback(this);
-        int[] switches = new int[9];
-        ArrayList<IBinder> binders = new ArrayList<>();
-        ArrayList<String> iconSlots = new ArrayList<>();
-        ArrayList<StatusBarIcon> icons = new ArrayList<>();
-        Rect fullscreenStackBounds = new Rect();
-        Rect dockedStackBounds = new Rect();
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
         try {
-            mBarService.registerStatusBar(commandQueue, iconSlots, icons, switches, binders,
-                    fullscreenStackBounds, dockedStackBounds);
+            mBarService.registerStatusBar(commandQueue);
         } catch (RemoteException ex) {
             // If the system process isn't there we're doomed anyway.
         }
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 0493ae90..aaf3df3 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -52,6 +52,7 @@
 import com.android.internal.statusbar.IStatusBar;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.NotificationVisibility;
+import com.android.internal.statusbar.RegisterStatusBarResult;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.DumpUtils;
 import com.android.server.LocalServices;
@@ -63,7 +64,6 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.List;
 
 /**
  * A note on locking:  We rely on the fact that calls onto mBar are oneway or
@@ -1037,37 +1037,27 @@
     // ================================================================================
     // TODO(b/118592525): refactor it as an IStatusBar API.
     @Override
-    public void registerStatusBar(IStatusBar bar, List<String> iconSlots,
-            List<StatusBarIcon> iconList, int switches[], List<IBinder> binders,
-            Rect fullscreenStackBounds, Rect dockedStackBounds) {
+    public RegisterStatusBarResult registerStatusBar(IStatusBar bar) {
         enforceStatusBarService();
 
         Slog.i(TAG, "registerStatusBar bar=" + bar);
         mBar = bar;
         mDeathRecipient.linkToDeath();
         notifyBarAttachChanged();
+        final ArrayMap<String, StatusBarIcon> icons;
         synchronized (mIcons) {
-            for (String slot : mIcons.keySet()) {
-                iconSlots.add(slot);
-                iconList.add(mIcons.get(slot));
-            }
+            icons = new ArrayMap<>(mIcons);
         }
         synchronized (mLock) {
             // TODO(b/118592525): Currently, status bar only works on the default display.
             // Make it aware of multi-display if needed.
             final UiState state = mDisplayUiState.get(DEFAULT_DISPLAY);
-            switches[0] = gatherDisableActionsLocked(mCurrentUserId, 1);
-            switches[1] = state.mSystemUiVisibility;
-            switches[2] = state.mMenuVisible ? 1 : 0;
-            switches[3] = state.mImeWindowVis;
-            switches[4] = state.mImeBackDisposition;
-            switches[5] = state.mShowImeSwitcher ? 1 : 0;
-            switches[6] = gatherDisableActionsLocked(mCurrentUserId, 2);
-            switches[7] = state.mFullscreenStackSysUiVisibility;
-            switches[8] = state.mDockedStackSysUiVisibility;
-            binders.add(state.mImeToken);
-            fullscreenStackBounds.set(state.mFullscreenStackBounds);
-            dockedStackBounds.set(state.mDockedStackBounds);
+            return new RegisterStatusBarResult(icons, gatherDisableActionsLocked(mCurrentUserId, 1),
+                    state.mSystemUiVisibility, state.mMenuVisible, state.mImeWindowVis,
+                    state.mImeBackDisposition, state.mShowImeSwitcher,
+                    gatherDisableActionsLocked(mCurrentUserId, 2),
+                    state.mFullscreenStackSysUiVisibility, state.mDockedStackSysUiVisibility,
+                    state.mImeToken, state.mFullscreenStackBounds, state.mDockedStackBounds);
         }
     }