Respond to managed profile availabilty Intents.

Grey out applications when managed profile is
not available.

Change-Id: I9bb9442cd0b3d0d207062716bfd6b179e3ba8489
diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java
index 32be12f..b5b6897 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -78,12 +78,22 @@
      */
     public AppInfo(Context context, LauncherActivityInfoCompat info, UserHandleCompat user,
             IconCache iconCache) {
+        this(context, info, user, iconCache,
+                UserManagerCompat.getInstance(context).isQuietModeEnabled(user));
+    }
+
+    public AppInfo(Context context, LauncherActivityInfoCompat info, UserHandleCompat user,
+            IconCache iconCache, boolean quietModeEnabled) {
         this.componentName = info.getComponentName();
         this.container = ItemInfo.NO_ID;
         flags = initFlags(info);
         if ((info.getApplicationInfo().flags & LauncherActivityInfoCompat.FLAG_SUSPENDED) != 0) {
             isDisabled |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
         }
+        if (quietModeEnabled) {
+            isDisabled |= ShortcutInfo.FLAG_DISABLED_QUIET_USER;
+        }
+
         iconCache.getTitleAndIcon(this, info, true /* useLowResIcon */);
         intent = makeLaunchIntent(context, info, user);
         this.user = user;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 6a548c3..02579a2 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2652,7 +2652,8 @@
         final ShortcutInfo shortcut = (ShortcutInfo) tag;
 
         if (shortcut.isDisabled != 0) {
-            if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SUSPENDED) != 0) {
+            if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SUSPENDED) != 0
+                || (shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_QUIET_USER) != 0) {
                 // Launch activity anyway, framework will tell the user why the app is suspended.
             } else {
                 int error = R.string.activity_not_available;
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index b70c3aa..e58652b 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -107,6 +107,7 @@
         // For handling managed profiles
         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);
         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);
+        filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED);
 
         sContext.registerReceiver(mModel, filter);
         UserManagerCompat.getInstance(sContext).enableAndResetCache();
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 52d2dca..be74520 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -1230,7 +1230,8 @@
                 callbacks.bindSearchProviderChanged();
             }
         } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)
-                || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {
+                || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)
+                || LauncherAppsCompat.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED.equals(action)) {
             UserManagerCompat.getInstance(context).enableAndResetCache();
             forceReload();
         }
@@ -1741,8 +1742,11 @@
                     final CursorIconInfo cursorIconInfo = new CursorIconInfo(c);
 
                     final LongSparseArray<UserHandleCompat> allUsers = new LongSparseArray<>();
+                    final LongSparseArray<Boolean> quietMode = new LongSparseArray<>();
                     for (UserHandleCompat user : mUserManager.getUserProfiles()) {
-                        allUsers.put(mUserManager.getSerialNumberForUser(user), user);
+                        long serialNo = mUserManager.getSerialNumberForUser(user);
+                        allUsers.put(serialNo, user);
+                        quietMode.put(serialNo, mUserManager.isQuietModeEnabled(user));
                     }
 
                     ShortcutInfo info;
@@ -1796,6 +1800,9 @@
                                             if (isSuspended) {
                                                 disabledState = ShortcutInfo.FLAG_DISABLED_SUSPENDED;
                                             }
+                                            if (quietMode.get(serialNumber)) {
+                                                disabledState |= ShortcutInfo.FLAG_DISABLED_QUIET_USER;
+                                            }
                                         } else if (validPkg) {
                                             intent = null;
                                             if ((promiseType & ShortcutInfo.FLAG_AUTOINTALL_ICON) != 0) {
@@ -2728,12 +2735,12 @@
                 if (apps == null || apps.isEmpty()) {
                     return;
                 }
-
+                boolean quietMode = mUserManager.isQuietModeEnabled(user);
                 // Create the ApplicationInfos
                 for (int i = 0; i < apps.size(); i++) {
                     LauncherActivityInfoCompat app = apps.get(i);
                     // This builds the icon bitmaps.
-                    mBgAllAppsList.add(new AppInfo(mContext, app, user, mIconCache));
+                    mBgAllAppsList.add(new AppInfo(mContext, app, user, mIconCache, quietMode));
                 }
 
                 final ManagedProfileHeuristic heuristic = ManagedProfileHeuristic.get(mContext, user);
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 0d6708b..a70a395 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -117,6 +117,11 @@
     public static final int FLAG_DISABLED_SUSPENDED = 4;
 
     /**
+     * Indicates that the icon is disabled as the user is in quiet mode.
+     */
+    public static final int FLAG_DISABLED_QUIET_USER = 8;
+
+    /**
      * Could be disabled, if the the app is installed but unavailable (eg. in safe mode or when
      * sd-card is not available).
      */
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index da3eb8f..db5b89e 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -35,6 +35,8 @@
             "android.intent.action.MANAGED_PROFILE_ADDED";
     public static final String ACTION_MANAGED_PROFILE_REMOVED =
             "android.intent.action.MANAGED_PROFILE_REMOVED";
+    public static final String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED =
+            "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED";
 
     public interface OnAppsChangedCallbackCompat {
         void onPackageRemoved(String packageName, UserHandleCompat user);
diff --git a/src/com/android/launcher3/compat/UserManagerCompat.java b/src/com/android/launcher3/compat/UserManagerCompat.java
index 6b7cba8..978f922 100644
--- a/src/com/android/launcher3/compat/UserManagerCompat.java
+++ b/src/com/android/launcher3/compat/UserManagerCompat.java
@@ -32,7 +32,9 @@
     public static UserManagerCompat getInstance(Context context) {
         synchronized (sInstanceLock) {
             if (sInstance == null) {
-                if (Utilities.ATLEAST_LOLLIPOP) {
+                if (Utilities.isNycOrAbove()) {
+                    sInstance = new UserManagerCompatVN(context.getApplicationContext());
+                } else if (Utilities.ATLEAST_LOLLIPOP) {
                     sInstance = new UserManagerCompatVL(context.getApplicationContext());
                 } else if (Utilities.ATLEAST_JB_MR1) {
                     sInstance = new UserManagerCompatV17(context.getApplicationContext());
@@ -54,4 +56,5 @@
     public abstract UserHandleCompat getUserForSerialNumber(long serialNumber);
     public abstract CharSequence getBadgedLabelForUser(CharSequence label, UserHandleCompat user);
     public abstract long getUserCreationTime(UserHandleCompat user);
+    public abstract boolean isQuietModeEnabled(UserHandleCompat user);
 }
diff --git a/src/com/android/launcher3/compat/UserManagerCompatV16.java b/src/com/android/launcher3/compat/UserManagerCompatV16.java
index fcd7555..a006efd 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatV16.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatV16.java
@@ -50,4 +50,9 @@
     @Override
     public void enableAndResetCache() {
     }
+
+    @Override
+    public boolean isQuietModeEnabled(UserHandleCompat user) {
+        return false;
+    }
 }
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVN.java b/src/com/android/launcher3/compat/UserManagerCompatVN.java
new file mode 100644
index 0000000..ae41e68
--- /dev/null
+++ b/src/com/android/launcher3/compat/UserManagerCompatVN.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 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.launcher3.compat;
+
+import android.content.Context;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+//TODO: Once gogole3 SDK is updated to N, add @TargetApi(Build.VERSION_CODES.N)
+public class UserManagerCompatVN extends UserManagerCompatVL {
+
+    private static final String TAG = "UserManagerCompatVN";
+
+    UserManagerCompatVN(Context context) {
+        super(context);
+    }
+
+    @Override
+    public boolean isQuietModeEnabled(UserHandleCompat user) {
+        if (user != null) {
+            try {
+                //TODO: Replace with proper API call once google3 SDK is updated.
+                Method isQuietModeEnabledMethod = UserManager.class.getMethod("isQuietModeEnabled",
+                        UserHandle.class);
+                return (boolean) isQuietModeEnabledMethod.invoke(mUserManager, user.getUser());
+            } catch (NoSuchMethodError | NoSuchMethodException | IllegalAccessException
+                    | InvocationTargetException e) {
+                Log.e(TAG, "Running on N without isQuietModeEnabled", e);
+            } catch (IllegalArgumentException e) {
+                // TODO remove this when API is fixed to not throw this
+                // when called on user that isn't a managed profile.
+            }
+        }
+        return false;
+    }
+}
+