Hide notifications until the device is provisioned.

During Setup (0 == Settings.Secure.DEVICE_PROVISIONED)
there's no reason to show notifications, unless they're
coming from the platform (and therefore essential to the
setup process), like the IME switcher.

We also disable the settings button and ticker while the
device is not provisioned.

Bug: 6355011
Change-Id: I1522f0c0fed3f2f95a36bd71d051248e12f0a1f8
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index f088e0e..cf2690b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -26,6 +26,7 @@
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.ContentObserver;
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Build;
@@ -123,7 +124,7 @@
 
     protected Display mDisplay;
     private IWindowManager mWindowManager;
-
+    private boolean mDeviceProvisioned = false;
 
     public IWindowManager getWindowManager() {
         return mWindowManager;
@@ -137,10 +138,31 @@
         return mBarService;
     }
 
+    protected boolean isDeviceProvisioned() {
+        return mDeviceProvisioned;
+    }
+
+    private ContentObserver mProvisioningObserver = new ContentObserver(new Handler()) {
+        @Override
+        public void onChange(boolean selfChange) {
+            final boolean provisioned = 0 != Settings.Secure.getInt(
+                    mContext.getContentResolver(), Settings.Secure.DEVICE_PROVISIONED, 0);
+            if (provisioned != mDeviceProvisioned) {
+                mDeviceProvisioned = provisioned;
+                updateNotificationIcons();
+            }
+        }
+    };
+
     public void start() {
         mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
                 .getDefaultDisplay();
 
+        mProvisioningObserver.onChange(false); // set up
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.DEVICE_PROVISIONED), true,
+                mProvisioningObserver);
+
         mWindowManager = IWindowManager.Stub.asInterface(
                 ServiceManager.getService(Context.WINDOW_SERVICE));
 
@@ -754,7 +776,7 @@
     protected abstract boolean shouldDisableNavbarGestures();
 
     protected boolean isTopNotification(ViewGroup parent, NotificationData.Entry entry) {
-        return parent.indexOfChild(entry.row) == 0;
+        return parent != null && parent.indexOfChild(entry.row) == 0;
     }
 
     public void updateNotification(IBinder key, StatusBarNotification notification) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index ecdaa39..7ee7e62 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -745,13 +745,19 @@
     }
 
     private void loadNotificationShade() {
+        if (mPile == null) return;
+
         int N = mNotificationData.size();
 
         ArrayList<View> toShow = new ArrayList<View>();
 
+        final boolean provisioned = isDeviceProvisioned();
+        // If the device hasn't been through Setup, we only show system notifications
         for (int i=0; i<N; i++) {
-            View row = mNotificationData.get(N-i-1).row;
-            toShow.add(row);
+            Entry ent = mNotificationData.get(N-i-1);
+            if (provisioned || "android".equals(ent.notification.pkg)) {
+                toShow.add(ent.row);
+            }
         }
 
         ArrayList<View> toRemove = new ArrayList<View>();
@@ -772,6 +778,8 @@
                 mPile.addView(v, i);
             }
         }
+
+        mSettingsButton.setEnabled(isDeviceProvisioned());
     }
 
     private void reloadAllNotificationIcons() {
@@ -782,6 +790,8 @@
 
     @Override
     protected void updateNotificationIcons() {
+        if (mNotificationIcons == null) return;
+
         loadNotificationShade();
 
         final LinearLayout.LayoutParams params
@@ -795,9 +805,12 @@
 
         ArrayList<View> toShow = new ArrayList<View>();
 
+        final boolean provisioned = isDeviceProvisioned();
+        // If the device hasn't been through Setup, we only show system notifications
         for (int i=0; i<N; i++) {
             Entry ent = mNotificationData.get(N-i-1);
-            if (ent.notification.score >= HIDE_ICONS_BELOW_SCORE) {
+            if ((provisioned && ent.notification.score >= HIDE_ICONS_BELOW_SCORE)
+                    || "android".equals(ent.notification.pkg)) {
                 toShow.add(ent.icon);
             }
         }
@@ -1657,6 +1670,9 @@
         // no ticking in lights-out mode
         if (!areLightsOn()) return;
 
+        // no ticking in Setup
+        if (!isDeviceProvisioned()) return;
+
         // Show the ticker if one is requested. Also don't do this
         // until status bar window is attached to the window manager,
         // because...  well, what's the point otherwise?  And trying to
@@ -2025,6 +2041,9 @@
 
     private View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
         public void onClick(View v) {
+            // We take this as a good indicator that Setup is running and we shouldn't
+            // allow you to go somewhere else
+            if (!isDeviceProvisioned()) return;
             try {
                 // Dismiss the lock screen when Settings starts.
                 ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();