Show a status bar icon for managed profile activities.

Show a work icon in the status bar when the foreground
activity is from an app in the managed profile.

Bug: 19532434
Change-Id: Ie96935c089d26f44bc5b1b8fcf60c83a32283a0f
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6d9bbae..8c78e74 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -23,6 +23,7 @@
     <!-- Do not translate. Defines the slots for the right-hand side icons.  That is to say, the
          icons in the status bar that are not notifications. -->
     <string-array name="config_statusBarIcons">
+       <item><xliff:g id="id">managed_profile</xliff:g></item>
        <item><xliff:g id="id">ime</xliff:g></item>
        <item><xliff:g id="id">sync_failing</xliff:g></item>
        <item><xliff:g id="id">sync_active</xliff:g></item>
diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
new file mode 100644
index 0000000..3c4c646
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
@@ -0,0 +1,29 @@
+<!--
+Copyright (C) 2015 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="23.0dp"
+        android:height="18.0dp"
+        android:viewportWidth="21.0"
+        android:viewportHeight="17.0">
+    <group android:translateX="2.0">
+        <path
+            android:fillColor="#FF000000"
+            android:pathData="M9.9,11.6H7v-1.1H2.1v2.8c0,0.8,0.6,1.4,1.4,1.4h9.9c0.8,0,1.4,-0.6,1.4,-1.4v-2.8H9.9V11.6z"/>
+        <path
+            android:fillColor="#FF000000"
+            android:pathData="M14.1,4.2h-2.5V3.2l-1.1,-1.1H6.3L5.3,3.2v1H2.8C2,4.2,1.4,4.9,1.4,5.6v2.8c0,0.8,0.6,1.4,1.4,1.4H7V8.8h2.8v1.1h4.2     c0.8,0,1.4,-0.6,1.4,-1.4V5.6C15.5,4.9,14.8,4.2,14.1,4.2z M10.6,4.2H6.3V3.2h4.2V4.2z"/>
+    </group>
+</vector>
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 7c199cd..b0d6178 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -3288,8 +3288,10 @@
         }
         if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
             mScrimController.setKeyguardShowing(true);
+            mIconPolicy.setKeyguardShowing(true);
         } else {
             mScrimController.setKeyguardShowing(false);
+            mIconPolicy.setKeyguardShowing(false);
         }
         mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
         updateDozingState();
@@ -3724,6 +3726,9 @@
         if (!mKeyguardFadingAway) {
             mIconController.appTransitionStarting(startTime, duration);
         }
+        if (mIconPolicy != null) {
+            mIconPolicy.appTransitionStarting(startTime, duration);
+        }
     }
 
     private final class ShadeUpdates {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index ac93ced..fb42ba1d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -16,16 +16,22 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
+import android.app.IUserSwitchObserver;
 import android.app.StatusBarManager;
 import android.bluetooth.BluetoothAdapter;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.UserInfo;
 import android.media.AudioManager;
 import android.os.Handler;
+import android.os.IRemoteCallback;
+import android.os.RemoteException;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings.Global;
 import android.telecom.TelecomManager;
 import android.util.Log;
@@ -54,6 +60,7 @@
     private static final String SLOT_ZEN = "zen";
     private static final String SLOT_VOLUME = "volume";
     private static final String SLOT_ALARM_CLOCK = "alarm_clock";
+    private static final String SLOT_MANAGED_PROFILE = "managed_profile";
 
     private final Context mContext;
     private final StatusBarManager mService;
@@ -72,6 +79,10 @@
 
     private boolean mBluetoothEnabled = false;
 
+    private boolean mManagedProfileFocused = false;
+    private boolean mManagedProfileIconVisible = true;
+
+    private boolean mKeyguardVisible = true;
 
     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
         @Override
@@ -94,9 +105,6 @@
             else if (action.equals(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED)) {
                 updateTTY(intent);
             }
-            else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
-                updateAlarm();
-            }
         }
     };
 
@@ -115,9 +123,15 @@
         filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
         filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
         filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
-        filter.addAction(Intent.ACTION_USER_SWITCHED);
         mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
 
+        // listen for user / profile change.
+        try {
+            ActivityManagerNative.getDefault().registerUserSwitchObserver(mUserSwitchListener);
+        } catch (RemoteException e) {
+            // Ignore
+        }
+
         // TTY status
         mService.setIcon(SLOT_TTY,  R.drawable.stat_sys_tty_mode, 0, null);
         mService.setIconVisibility(SLOT_TTY, false);
@@ -147,6 +161,10 @@
         mService.setIcon(SLOT_HOTSPOT, R.drawable.stat_sys_hotspot, 0, null);
         mService.setIconVisibility(SLOT_HOTSPOT, mHotspot.isHotspotEnabled());
         mHotspot.addCallback(mHotspotCallback);
+
+        // managed profile
+        mService.setIcon(SLOT_MANAGED_PROFILE, R.drawable.stat_sys_managed_profile_status, 0, null);
+        mService.setIconVisibility(SLOT_MANAGED_PROFILE, false);
     }
 
     public void setZenMode(int zen) {
@@ -298,6 +316,53 @@
         mService.setIconVisibility(SLOT_CAST, isCasting);
     }
 
+    private void profileChanged(int userId) {
+        UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        UserInfo user = null;
+        if (userId == UserHandle.USER_CURRENT) {
+            try {
+                user = ActivityManagerNative.getDefault().getCurrentUser();
+            } catch (RemoteException e) {
+                // Ignore
+            }
+        } else {
+            user = userManager.getUserInfo(userId);
+        }
+
+        mManagedProfileFocused = user != null && user.isManagedProfile();
+        if (DEBUG) Log.v(TAG, "profileChanged: mManagedProfileFocused: " + mManagedProfileFocused);
+        // Actually update the icon later when transition starts.
+    }
+
+    private void updateManagedProfile() {
+        if (DEBUG) Log.v(TAG, "updateManagedProfile: mManagedProfileFocused: "
+                + mManagedProfileFocused
+                + " mKeyguardVisible: " + mKeyguardVisible);
+        boolean showIcon = mManagedProfileFocused && !mKeyguardVisible;
+        if (mManagedProfileIconVisible != showIcon) {
+            mService.setIconVisibility(SLOT_MANAGED_PROFILE, showIcon);
+            mManagedProfileIconVisible = showIcon;
+        }
+    }
+
+    private final IUserSwitchObserver.Stub mUserSwitchListener =
+            new IUserSwitchObserver.Stub() {
+                @Override
+                public void onUserSwitching(int newUserId, IRemoteCallback reply) {
+                }
+
+                @Override
+                public void onUserSwitchComplete(int newUserId) throws RemoteException {
+                    updateAlarm();
+                    profileChanged(newUserId);
+                }
+
+                @Override
+                public void onForegroundProfileSwitch(int newProfileId) {
+                    profileChanged(newProfileId);
+                }
+            };
+
     private final HotspotController.Callback mHotspotCallback = new HotspotController.Callback() {
         @Override
         public void onHotspotChanged(boolean enabled) {
@@ -311,4 +376,13 @@
             updateCast();
         }
     };
+
+    public void appTransitionStarting(long startTime, long duration) {
+        updateManagedProfile();
+    }
+
+    public void setKeyguardShowing(boolean visible) {
+        mKeyguardVisible = visible;
+        updateManagedProfile();
+    }
 }