Merge "Allow widget hosts to see widgets from locked profiles." into nyc-dev

This commit is contained in:
Kenny Guy
2016-02-19 14:40:06 +00:00
committed by Android (Google) Code Review

View File

@@ -159,7 +159,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
reloadWidgetsMaskedStateForUser(userId); reloadWidgetsMaskedStateForUser(userId);
} else if (Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED.equals(action)) { } else if (Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED.equals(action)) {
synchronized (mLock) { synchronized (mLock) {
reloadWidgetQuietModeMaskedStateLocked(userId); reloadWidgetProfileUnavailableMaskedStateLocked(userId);
} }
} else if (Intent.ACTION_PACKAGES_SUSPENDED.equals(action)) { } else if (Intent.ACTION_PACKAGES_SUSPENDED.equals(action)) {
String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
@@ -432,7 +432,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
/** /**
* Reload all widgets' masked state for the given user and its associated profiles, including * Reload all widgets' masked state for the given user and its associated profiles, including
* due to quiet mode and package suspension. * due to user not being available and package suspension.
*/ */
private void reloadWidgetsMaskedStateForUser(int userId) { private void reloadWidgetsMaskedStateForUser(int userId) {
if (!mUserManager.isUserUnlocked(userId)) return; if (!mUserManager.isUserUnlocked(userId)) return;
@@ -442,7 +442,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
if (profiles != null) { if (profiles != null) {
for (int i = 0; i < profiles.size(); i++) { for (int i = 0; i < profiles.size(); i++) {
UserInfo user = profiles.get(i); UserInfo user = profiles.get(i);
reloadWidgetQuietModeMaskedStateLocked(user.id); reloadWidgetProfileUnavailableMaskedStateLocked(user.id);
reloadWidgetPackageSuspensionMaskedStateLocked(user.id); reloadWidgetPackageSuspensionMaskedStateLocked(user.id);
} }
} }
@@ -450,17 +450,18 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
} }
/** /**
* Mask/unmask widgets in the given profile, depending on the quiet state of the profile. * Mask/unmask widgets in the given profile, depending on the quiet state
* or locked state of the profile.
*/ */
private void reloadWidgetQuietModeMaskedStateLocked(int profileId) { private void reloadWidgetProfileUnavailableMaskedStateLocked(int profileId) {
if (!mUserManager.isUserUnlocked(profileId)) return;
final long identity = Binder.clearCallingIdentity(); final long identity = Binder.clearCallingIdentity();
try { try {
UserInfo user = mUserManager.getUserInfo(profileId); if (!isProfileWithUnlockedParent(profileId)) {
if (!user.isManagedProfile()) {
return; return;
} }
boolean shouldMask = user.isQuietModeEnabled(); UserInfo user = mUserManager.getUserInfo(profileId);
boolean shouldMask = user.isQuietModeEnabled() ||
!mUserManager.isUserUnlocked(user.getUserHandle());
final int N = mProviders.size(); final int N = mProviders.size();
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
Provider provider = mProviders.get(i); Provider provider = mProviders.get(i);
@@ -468,7 +469,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
if (providerUserId != profileId) { if (providerUserId != profileId) {
continue; continue;
} }
if (provider.setMaskedByQuietProfileLocked(shouldMask)) { if (provider.setMaskedByProfileUnavailabledLocked(shouldMask)) {
if (provider.isMaskedLocked()) { if (provider.isMaskedLocked()) {
maskWidgetsViewsLocked(provider); maskWidgetsViewsLocked(provider);
} else { } else {
@@ -537,8 +538,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
} }
} }
private void maskWidgetsViewsLocked(Provider provider) { private Bitmap createMaskedWidgetBitmap(Provider provider) {
Bitmap iconBitmap = null; final long identity = Binder.clearCallingIdentity();
try { try {
// Load the unbadged application icon and pass it to the widget to appear on // Load the unbadged application icon and pass it to the widget to appear on
// the masked view. // the masked view.
@@ -548,11 +549,20 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
PackageManager pm = userContext.getPackageManager(); PackageManager pm = userContext.getPackageManager();
Drawable icon = pm.getApplicationInfo(providerPackage, 0).loadUnbadgedIcon(pm); Drawable icon = pm.getApplicationInfo(providerPackage, 0).loadUnbadgedIcon(pm);
// Create a bitmap of the icon which is what the widget's remoteview requires. // Create a bitmap of the icon which is what the widget's remoteview requires.
iconBitmap = mIconUtilities.createIconBitmap(icon); return mIconUtilities.createIconBitmap(icon);
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
Slog.e(TAG, "Fail to get application icon", e); Slog.e(TAG, "Fail to get application icon", e);
// Provider package removed, no need to mask its views as its state will be // Provider package removed, no need to mask its views as its state will be
// purged very soon. // purged very soon.
return null;
} finally {
Binder.restoreCallingIdentity(identity);
}
}
private void maskWidgetsViewsLocked(Provider provider) {
Bitmap iconBitmap = createMaskedWidgetBitmap(provider);
if (iconBitmap == null) {
return; return;
} }
@@ -2320,7 +2330,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
final PackageManager pm = mContext.getPackageManager(); final PackageManager pm = mContext.getPackageManager();
final int userId = UserHandle.getUserId(providerId.uid); final int userId = UserHandle.getUserId(providerId.uid);
final ApplicationInfo app = pm.getApplicationInfoAsUser(activityInfo.packageName, final ApplicationInfo app = pm.getApplicationInfoAsUser(activityInfo.packageName,
PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId); 0, userId);
resources = pm.getResourcesForApplication(app); resources = pm.getResourcesForApplication(app);
} finally { } finally {
Binder.restoreCallingIdentity(identity); Binder.restoreCallingIdentity(identity);
@@ -2423,9 +2433,16 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
int flags = PackageManager.GET_META_DATA; int flags = PackageManager.GET_META_DATA;
// We really need packages to be around and parsed to know if they // We really need packages to be around and parsed to know if they
// provide widgets, and we only load widgets after user is unlocked. // provide widgets.
flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING; flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
// Widget hosts that are non-crypto aware may be hosting widgets
// from a profile that is still locked, so let them see those
// widgets.
if (isProfileWithUnlockedParent(userId)) {
flags |= PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE;
}
// Widgets referencing shared libraries need to have their // Widgets referencing shared libraries need to have their
// dependencies loaded. // dependencies loaded.
flags |= PackageManager.GET_SHARED_LIBRARY_FILES; flags |= PackageManager.GET_SHARED_LIBRARY_FILES;
@@ -2443,6 +2460,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
private void onUserUnlocked(int userId) { private void onUserUnlocked(int userId) {
synchronized (mLock) { synchronized (mLock) {
ensureGroupStateLoadedLocked(userId); ensureGroupStateLoadedLocked(userId);
reloadWidgetsMaskedStateForUser(userId);
final int N = mProviders.size(); final int N = mProviders.size();
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
@@ -2580,6 +2598,17 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
mWidgetPackages.put(userId, packages = new ArraySet<String>()); mWidgetPackages.put(userId, packages = new ArraySet<String>());
} }
packages.add(widget.provider.info.provider.getPackageName()); packages.add(widget.provider.info.provider.getPackageName());
// If we are adding a widget it might be for a provider that
// is currently masked, if so mask the widget.
if (widget.provider.isMaskedLocked()) {
Bitmap bitmap = createMaskedWidgetBitmap(widget.provider);
if (bitmap != null) {
widget.replaceWithMaskedViewsLocked(mContext, bitmap);
}
} else {
widget.clearMaskedViewsLocked();
}
} }
/** /**
@@ -3277,6 +3306,18 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
} }
} }
private boolean isProfileWithUnlockedParent(int userId) {
UserInfo userInfo = mUserManager.getUserInfo(userId);
if (userInfo != null && userInfo.isManagedProfile()) {
UserInfo parentInfo = mUserManager.getProfileParent(userId);
if (parentInfo != null
&& mUserManager.isUserUnlocked(parentInfo.getUserHandle())) {
return true;
}
}
return false;
}
private final class CallbackHandler extends Handler { private final class CallbackHandler extends Handler {
public static final int MSG_NOTIFY_UPDATE_APP_WIDGET = 1; public static final int MSG_NOTIFY_UPDATE_APP_WIDGET = 1;
public static final int MSG_NOTIFY_PROVIDER_CHANGED = 2; public static final int MSG_NOTIFY_PROVIDER_CHANGED = 2;
@@ -3554,7 +3595,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
PendingIntent broadcast; PendingIntent broadcast;
boolean zombie; // if we're in safe mode, don't prune this just because nobody references it boolean zombie; // if we're in safe mode, don't prune this just because nobody references it
boolean maskedByQuietProfile; boolean maskedByProfileUnavailable;
boolean maskedBySuspendedPackage; boolean maskedBySuspendedPackage;
int tag = TAG_UNDEFINED; // for use while saving state (the index) int tag = TAG_UNDEFINED; // for use while saving state (the index)
@@ -3587,9 +3628,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
} }
// returns true if the provider's masked state is changed as a result // returns true if the provider's masked state is changed as a result
public boolean setMaskedByQuietProfileLocked(boolean masked) { public boolean setMaskedByProfileUnavailabledLocked(boolean masked) {
boolean oldMaskedState = isMaskedLocked(); boolean oldMaskedState = isMaskedLocked();
maskedByQuietProfile = masked; maskedByProfileUnavailable = masked;
return isMaskedLocked() != oldMaskedState; return isMaskedLocked() != oldMaskedState;
} }
@@ -3601,7 +3642,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
} }
public boolean isMaskedLocked() { public boolean isMaskedLocked() {
return maskedByQuietProfile || maskedBySuspendedPackage; return maskedByProfileUnavailable || maskedBySuspendedPackage;
} }
} }