From 945864c70443c1c6515da9c250e5dc3b9ff98c56 Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Thu, 22 Mar 2018 21:49:10 -0700 Subject: [PATCH] Notify all running users for global settings change Test: pass: atest android.provider.cts.SettingsTest pass: atest android.provider.cts.Settings_SystemTest pass: atest android.provider.cts.Settings_SecureTest pass: adb shell am instrument -w com.android.providers.setting.test /android.support.test.runner.AndroidJUnitRunner Bug: 74547258 Change-Id: Ic8c76467248d5bea64eeb8c7321f552664b6a2a6 --- .../providers/settings/SettingsProvider.java | 76 +++++++++++-------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index b37071bf24cf3..4054d5ed9c6c0 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -2750,31 +2750,34 @@ public class SettingsProvider extends ContentProvider { } private void notifyForSettingsChange(int key, String name) { - final int userId = getUserIdFromKey(key); - Uri uri = getNotificationUriFor(key, name); - + // Increment the generation first, so observers always see the new value mGenerationRegistry.incrementGeneration(key); - mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED, - userId, 0, uri).sendToTarget(); - - if (isSecureSettingsKey(key)) { - maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name, - sSecureCloneToManagedSettings); - maybeNotifyProfiles(SETTINGS_TYPE_SYSTEM, userId, uri, name, - sSystemCloneFromParentOnDependency.values()); - } else if (isSystemSettingsKey(key)) { - maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name, - sSystemCloneToManagedSettings); + if (isGlobalSettingsKey(key)) { + if (Global.LOCATION_GLOBAL_KILL_SWITCH.equals(name)) { + // When the global kill switch is updated, send the + // change notification for the location setting. + notifyLocationChangeForRunningUsers(); + } + notifyGlobalSettingChangeForRunningUsers(key, name); + } else { + final int userId = getUserIdFromKey(key); + final Uri uri = getNotificationUriFor(key, name); + mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED, + userId, 0, uri).sendToTarget(); + if (isSecureSettingsKey(key)) { + maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name, + sSecureCloneToManagedSettings); + maybeNotifyProfiles(SETTINGS_TYPE_SYSTEM, userId, uri, name, + sSystemCloneFromParentOnDependency.values()); + } else if (isSystemSettingsKey(key)) { + maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name, + sSystemCloneToManagedSettings); + } } + // Always notify that our data changed mHandler.obtainMessage(MyHandler.MSG_NOTIFY_DATA_CHANGED).sendToTarget(); - - // When the global kill switch is updated, send the change notification for - // the location setting. - if (isGlobalSettingsKey(key) && Global.LOCATION_GLOBAL_KILL_SWITCH.equals(name)) { - notifyLocationChangeForRunningUsers(); - } } private void maybeNotifyProfiles(int type, int userId, Uri uri, String name, @@ -2783,33 +2786,46 @@ public class SettingsProvider extends ContentProvider { for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) { // the notification for userId has already been sent. if (profileId != userId) { + final int key = makeKey(type, profileId); + // Increment the generation first, so observers always see the new value + mGenerationRegistry.incrementGeneration(key); mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED, profileId, 0, uri).sendToTarget(); - final int key = makeKey(type, profileId); - mGenerationRegistry.incrementGeneration(key); - - mHandler.obtainMessage(MyHandler.MSG_NOTIFY_DATA_CHANGED).sendToTarget(); } } } } + private void notifyGlobalSettingChangeForRunningUsers(int key, String name) { + // Important: No need to update generation for each user as there + // is a singleton generation entry for the global settings which + // is already incremented be the caller. + final Uri uri = getNotificationUriFor(key, name); + final List users = mUserManager.getUsers(/*excludeDying*/ true); + for (int i = 0; i < users.size(); i++) { + final int userId = users.get(i).id; + if (mUserManager.isUserRunning(UserHandle.of(userId))) { + mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED, + userId, 0, uri).sendToTarget(); + } + } + } + private void notifyLocationChangeForRunningUsers() { final List users = mUserManager.getUsers(/*excludeDying=*/ true); for (int i = 0; i < users.size(); i++) { final int userId = users.get(i).id; - // Do we have to increment the generation for users that are not running? - // Yeah let's assume so... - final int key = makeKey(SETTINGS_TYPE_SECURE, userId); - mGenerationRegistry.incrementGeneration(key); - if (!mUserManager.isUserRunning(UserHandle.of(userId))) { continue; } - final Uri uri = getNotificationUriFor(key, Secure.LOCATION_PROVIDERS_ALLOWED); + // Increment the generation first, so observers always see the new value + final int key = makeKey(SETTINGS_TYPE_SECURE, userId); + mGenerationRegistry.incrementGeneration(key); + + final Uri uri = getNotificationUriFor(key, Secure.LOCATION_PROVIDERS_ALLOWED); mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED, userId, 0, uri).sendToTarget(); }