Merge "Removing the debug header bar icon."
diff --git a/core/res/res/drawable/ic_corp_badge_off.xml b/core/res/res/drawable/ic_corp_badge_off.xml
new file mode 100644
index 0000000..6799bf7
--- /dev/null
+++ b/core/res/res/drawable/ic_corp_badge_off.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+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="20dp"
+    android:height="20dp"
+    android:viewportWidth="20"
+    android:viewportHeight="20">
+
+    <path
+        android:fillColor="#607D8B"
+        android:pathData="M10,0 C15.5228,0,20,4.47715,20,10 C20,15.5228,15.5228,20,10,20
+C4.47715,20,0,15.5228,0,10 C0,4.47715,4.47715,0,10,0 Z" />
+    <path
+        android:pathData="M1.91667,1.91667 L18.0833,1.91667 L18.0833,18.0833 L1.91667,18.0833
+L1.91667,1.91667 Z" />
+    <path
+        android:fillColor="#ffffff"
+        android:pathData="M11.9167,11.9167 L11.4167,11.9167 L11.4167,12.8333 L8.5,12.8333 L8.5,11.9167
+L4.16667,11.9167 L4.16667,14.3333 C4.16667,14.8333,4.58333,15.25,5.08333,15.25
+L14.75,15.25 C14.9167,15.25,15,15.25,15.1667,15.1667 L11.9167,11.9167 Z" />
+    <path
+        android:fillColor="#ffffff"
+        android:pathData="M15.8333,13.75 L15.8333,11.9167 L14,11.9167
+C14.6667,12.6667,15.3333,13.3333,15.8333,13.75 Z" />
+    <path
+        android:fillColor="#ffffff"
+        android:pathData="M6.16667,6.16667 L4.66667,6.16667 C4.16667,6.16667,3.75,6.58333,3.75,7.08333
+L3.75,10 C3.75,10.5,4.16667,10.9167,4.66667,10.9167 L8.5,10.9167 L8.5,10 L10,10
+L6.16667,6.16667 Z" />
+    <path
+        android:fillColor="#ffffff"
+        android:pathData="M8.08333,6 L8.08333,5.16667 L11.9167,5.16667 L11.9167,6.08333 L8.16667,6.08333
+C9.66667,7.58333,11.4167,9.33333,12.9167,10.8333 L15.25,10.8333
+C15.75,10.8333,16.1667,10.4167,16.1667,9.91667 L16.1667,7.08333
+C16.1667,6.58333,15.75,6.16667,15.25,6.16667 L12.8333,6.16667 L12.8333,5.25
+L11.9167,4.33333 L8.08333,4.33333 L7.16667,5.16667
+C7.41667,5.41667,7.75,5.75,8.08333,6 Z" />
+    <path
+        android:fillColor="#ffffff"
+        android:pathData="M15.6824,15.676 L14.6807,16.6777 L3.24921,5.24624 L4.25093,4.24452
+L15.6824,15.676 Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/work_widget_mask_view_background.xml b/core/res/res/drawable/work_widget_mask_view_background.xml
new file mode 100644
index 0000000..17f0dbc
--- /dev/null
+++ b/core/res/res/drawable/work_widget_mask_view_background.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+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.
+-->
+ <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
+   <padding android:left="5dp" android:right="5dp" android:top="5dp" android:bottom="5dp"/>
+   <stroke android:width="1dp" android:color="#CCCCCC" />
+ </shape>
diff --git a/core/res/res/layout/work_widget_mask_view.xml b/core/res/res/layout/work_widget_mask_view.xml
new file mode 100644
index 0000000..ce86ddc
--- /dev/null
+++ b/core/res/res/layout/work_widget_mask_view.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#F3374248" >
+
+    <ImageView android:id="@+id/work_widget_app_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"/>
+
+    <ImageView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom|right"
+        android:layout_marginBottom="4dp"
+        android:layout_marginRight="4dp"
+        android:src="@drawable/ic_corp_badge_off" />
+</FrameLayout>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 36ba306..832984e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1243,6 +1243,7 @@
   <java-symbol type="drawable" name="cling_arrow_up" />
   <java-symbol type="drawable" name="cling_bg" />
   <java-symbol type="drawable" name="ic_corp_badge" />
+  <java-symbol type="drawable" name="ic_corp_badge_off" />
   <java-symbol type="drawable" name="ic_corp_icon_badge" />
   <java-symbol type="drawable" name="ic_corp_icon" />
   <java-symbol type="drawable" name="ic_corp_statusbar_icon" />
@@ -2384,4 +2385,8 @@
   <java-symbol type="dimen" name="notification_content_margin_top" />
   <java-symbol type="string" name="importance_from_topic" />
   <java-symbol type="string" name="importance_from_person" />
+
+  <java-symbol type="layout" name="work_widget_mask_view" />
+  <java-symbol type="id" name="work_widget_app_icon" />
+  <java-symbol type="drawable" name="work_widget_mask_view_background" />
 </resources>
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 25fef18..df18d3e 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -37,6 +37,7 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
@@ -44,7 +45,10 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.Point;
+import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
@@ -79,6 +83,7 @@
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.widget.IRemoteViewsAdapterConnection;
 import com.android.internal.widget.IRemoteViewsFactory;
+import com.android.internal.R;
 import com.android.server.LocalServices;
 import com.android.server.WidgetBackupProvider;
 
@@ -149,6 +154,14 @@
             } else if (Intent.ACTION_USER_STOPPED.equals(action)) {
                 onUserStopped(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
                         UserHandle.USER_NULL));
+            } else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+                refreshProfileWidgetsMaskedState(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+                        UserHandle.USER_NULL));
+            } else if (Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED.equals(action)) {
+                UserHandle profile = (UserHandle)intent.getParcelableExtra(Intent.EXTRA_USER);
+                if (profile != null) {
+                    refreshWidgetMaskedState(profile.getIdentifier());
+                }
             } else {
                 onPackageBroadcastReceived(intent, intent.getIntExtra(
                         Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL));
@@ -208,6 +221,7 @@
         mCallbackHandler = new CallbackHandler(mContext.getMainLooper());
         mBackupRestoreController = new BackupRestoreController();
         mSecurityPolicy = new SecurityPolicy();
+
         computeMaximumWidgetBitmapMemory();
         registerBroadcastReceiver();
         registerOnCrossProfileProvidersChangedListener();
@@ -251,8 +265,14 @@
         IntentFilter userFilter = new IntentFilter();
         userFilter.addAction(Intent.ACTION_USER_STARTED);
         userFilter.addAction(Intent.ACTION_USER_STOPPED);
+        userFilter.addAction(Intent.ACTION_USER_SWITCHED);
         mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
                 userFilter, null, null);
+
+        IntentFilter offModeFilter = new IntentFilter();
+        offModeFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED);
+        mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
+                offModeFilter, null, null);
     }
 
     private void registerOnCrossProfileProvidersChangedListener() {
@@ -395,6 +415,60 @@
         }
     }
 
+    /**
+     * Refresh the masked state for all profiles under the given user.
+     */
+    private void refreshProfileWidgetsMaskedState(int userId) {
+        if (userId == UserHandle.USER_NULL) {
+            return;
+        }
+        List<UserInfo> profiles = mUserManager.getEnabledProfiles(userId);
+        if (profiles != null) {
+            for (int i = 0; i < profiles.size(); i++) {
+                UserInfo user  = profiles.get(i);
+                refreshWidgetMaskedState(user.id);
+            }
+        }
+    }
+
+    /**
+     * Mask/unmask widgets in the given profile, depending on the quiet state of the profile.
+     */
+    private void refreshWidgetMaskedState(int profileId) {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            UserInfo user  = mUserManager.getUserInfo(profileId);
+            if (!user.isManagedProfile()) {
+                return;
+            }
+            boolean shouldMask = user.isQuietModeEnabled();
+            final int iconSize = (int) mContext.getResources().getDimension(
+                    android.R.dimen.app_icon_size);
+            synchronized (mLock) {
+                final int N = mProviders.size();
+                for (int i = 0; i < N; i++) {
+                    Provider provider = mProviders.get(i);
+                    int providerUserId = provider.getUserId();
+                    if (providerUserId == profileId) {
+                        final int widgetCount = provider.widgets.size();
+                        for (int j = 0; j < widgetCount; j++) {
+                            Widget widget = provider.widgets.get(j);
+                            if (shouldMask) {
+                                widget.replaceWithMaskedViewsLocked(mContext, iconSize);
+                            } else {
+                                widget.clearMaskedViewsLocked();
+                            }
+                            scheduleNotifyUpdateAppWidgetLocked(widget,
+                                    widget.getEffectiveViewsLocked());
+                        }
+                    }
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     private void resolveHostUidLocked(String pkg, int uid) {
         final int N = mHosts.size();
         for (int i = 0; i < N; i++) {
@@ -516,7 +590,7 @@
             for (int i = 0; i < N; i++) {
                 Widget widget = instances.get(i);
                 updatedIds[i] = widget.appWidgetId;
-                updatedViews.add(cloneIfLocalBinder(widget.views));
+                updatedViews.add(cloneIfLocalBinder(widget.getEffectiveViewsLocked()));
             }
 
             return updatedIds;
@@ -1128,7 +1202,7 @@
                     Binder.getCallingUid(), callingPackage);
 
             if (widget != null) {
-                return cloneIfLocalBinder(widget.views);
+                return cloneIfLocalBinder(widget.getEffectiveViewsLocked());
             }
 
             return null;
@@ -1554,8 +1628,7 @@
                 // For a full update we replace the RemoteViews completely.
                 widget.views = views;
             }
-
-            scheduleNotifyUpdateAppWidgetLocked(widget, views);
+            scheduleNotifyUpdateAppWidgetLocked(widget, widget.getEffectiveViewsLocked());
         }
     }
 
@@ -3536,6 +3609,7 @@
         int restoredId;  // tracking & remapping any restored state
         Provider provider;
         RemoteViews views;
+        RemoteViews maskedViews;
         Bundle options;
         Host host;
 
@@ -3543,6 +3617,34 @@
         public String toString() {
             return "AppWidgetId{" + appWidgetId + ':' + host + ':' + provider + '}';
         }
+
+        public void replaceWithMaskedViewsLocked(Context context, int iconSize) {
+            if (maskedViews != null) {
+                return;
+            }
+            maskedViews = new RemoteViews(context.getPackageName(), R.layout.work_widget_mask_view);
+            try {
+                Drawable icon = context.getPackageManager().getApplicationIcon(
+                        provider.info.provider.getPackageName());
+                final int width = iconSize;
+                final int height = iconSize;
+                Bitmap iconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+                Canvas canvas = new Canvas(iconBitmap);
+                icon.setBounds(0, 0, width, height);
+                icon.draw(canvas);
+                maskedViews.setImageViewBitmap(R.id.work_widget_app_icon, iconBitmap);
+            } catch (NameNotFoundException e) {
+                Slog.e(TAG, "Fail to get application icon", e);
+            }
+        }
+
+        public void clearMaskedViewsLocked() {
+            maskedViews = null;
+        }
+
+        public RemoteViews getEffectiveViewsLocked() {
+            return maskedViews != null ? maskedViews : views;
+        }
     }
 
     /**