From ff05f4375dd47242d7e4864287e0d5af8ac8ba8f Mon Sep 17 00:00:00 2001 From: Kenny Guy Date: Fri, 22 Jan 2016 17:48:29 +0000 Subject: [PATCH] Respond to managed profile availabilty Intents. Grey out applications when managed profile is not available. Change-Id: I9bb9442cd0b3d0d207062716bfd6b179e3ba8489 --- src/com/android/launcher3/AppInfo.java | 10 ++++ src/com/android/launcher3/Launcher.java | 3 +- src/com/android/launcher3/LauncherAppState.java | 1 + src/com/android/launcher3/LauncherModel.java | 15 ++++-- src/com/android/launcher3/ShortcutInfo.java | 5 ++ .../launcher3/compat/LauncherAppsCompat.java | 2 + .../launcher3/compat/UserManagerCompat.java | 5 +- .../launcher3/compat/UserManagerCompatV16.java | 5 ++ .../launcher3/compat/UserManagerCompatVN.java | 55 ++++++++++++++++++++++ 9 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 src/com/android/launcher3/compat/UserManagerCompatVN.java diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java index 32be12f01..b5b6897cc 100644 --- a/src/com/android/launcher3/AppInfo.java +++ b/src/com/android/launcher3/AppInfo.java @@ -78,12 +78,22 @@ public class AppInfo extends ItemInfo { */ 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 6a548c38d..02579a2e2 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -2652,7 +2652,8 @@ public class Launcher extends Activity 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 b70c3aa47..e58652b8e 100644 --- a/src/com/android/launcher3/LauncherAppState.java +++ b/src/com/android/launcher3/LauncherAppState.java @@ -107,6 +107,7 @@ public class LauncherAppState { // 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 52d2dca65..be745202b 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -1230,7 +1230,8 @@ public class LauncherModel extends BroadcastReceiver 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 @@ public class LauncherModel extends BroadcastReceiver final CursorIconInfo cursorIconInfo = new CursorIconInfo(c); final LongSparseArray allUsers = new LongSparseArray<>(); + final LongSparseArray 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 @@ public class LauncherModel extends BroadcastReceiver 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 @@ public class LauncherModel extends BroadcastReceiver 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 0d6708bfc..a70a395ae 100644 --- a/src/com/android/launcher3/ShortcutInfo.java +++ b/src/com/android/launcher3/ShortcutInfo.java @@ -117,6 +117,11 @@ public class ShortcutInfo extends ItemInfo { 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 da3eb8fee..db5b89e81 100644 --- a/src/com/android/launcher3/compat/LauncherAppsCompat.java +++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java @@ -35,6 +35,8 @@ public abstract class LauncherAppsCompat { "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 6b7cba840..978f9229d 100644 --- a/src/com/android/launcher3/compat/UserManagerCompat.java +++ b/src/com/android/launcher3/compat/UserManagerCompat.java @@ -32,7 +32,9 @@ public abstract class UserManagerCompat { 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 class UserManagerCompat { 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 fcd755521..a006efd50 100644 --- a/src/com/android/launcher3/compat/UserManagerCompatV16.java +++ b/src/com/android/launcher3/compat/UserManagerCompatV16.java @@ -50,4 +50,9 @@ public class UserManagerCompatV16 extends UserManagerCompat { @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 000000000..ae41e68a3 --- /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; + } +} + -- 2.11.0