Loading core/java/android/app/admin/DevicePolicyManagerInternal.java +25 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,22 @@ import java.util.List; */ public abstract class DevicePolicyManagerInternal { /** * Listener for changes in the white-listed packages to show cross-profile * widgets. */ public interface OnCrossProfileWidgetProvidersChangeListener { /** * Called when the white-listed packages to show cross-profile widgets * have changed for a given user. * * @param profileId The profile for which the white-listed packages changed. * @param packages The white-listed packages. */ public void onCrossProfileWidgetProvidersChanged(int profileId, List<String> packages); } /** * Gets the packages whose widget providers are white-listed to be * available in the parent user. Loading @@ -35,4 +51,13 @@ public abstract class DevicePolicyManagerInternal { * profile. */ public abstract List<String> getCrossProfileWidgetProviders(int profileId); /** * Adds a listener for changes in the white-listed packages to show * cross-profile app widgets. * * @param listener The listener to add. */ public abstract void addOnCrossProfileWidgetProvidersChangeListener( OnCrossProfileWidgetProvidersChangeListener listener); } services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +73 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.app.AlarmManager; import android.app.AppGlobals; import android.app.PendingIntent; import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.DevicePolicyManagerInternal.OnCrossProfileWidgetProvidersChangeListener; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.BroadcastReceiver; Loading Loading @@ -102,7 +103,8 @@ import java.util.Locale; import java.util.Map; import java.util.Set; class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBackupProvider { class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBackupProvider, OnCrossProfileWidgetProvidersChangeListener { private static final String TAG = "AppWidgetServiceImpl"; private static boolean DEBUG = false; Loading Loading @@ -199,6 +201,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku mSecurityPolicy = new SecurityPolicy(); computeMaximumWidgetBitmapMemory(); registerBroadcastReceiver(); registerOnCrossProfileProvidersChangedListener(); } private void computeMaximumWidgetBitmapMemory() { Loading Loading @@ -243,6 +246,15 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku userFilter, null, null); } private void registerOnCrossProfileProvidersChangedListener() { DevicePolicyManagerInternal devicePolicyManager = LocalServices.getService( DevicePolicyManagerInternal.class); // The device policy is an optional component. if (devicePolicyManager != null) { devicePolicyManager.addOnCrossProfileWidgetProvidersChangeListener(this); } } public void setSafeMode(boolean safeMode) { mSafeMode = safeMode; } Loading Loading @@ -368,7 +380,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku saveGroupStateAsync(userId); // If the set of providers has been modified, notify each active AppWidgetHost scheduleNotifyHostsForProvidersChangedLocked(); scheduleNotifyGroupHostsForProvidersChangedLocked(userId); } } } Loading Loading @@ -1657,11 +1669,27 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } } private void scheduleNotifyHostsForProvidersChangedLocked() { private void scheduleNotifyGroupHostsForProvidersChangedLocked(int userId) { final int[] profileIds = mSecurityPolicy.getEnabledGroupProfileIds(userId); final int N = mHosts.size(); for (int i = N - 1; i >= 0; i--) { Host host = mHosts.get(i); boolean hostInGroup = false; final int M = profileIds.length; for (int j = 0; j < M; j++) { final int profileId = profileIds[j]; if (host.getUserId() == profileId) { hostInGroup = true; break; } } if (!hostInGroup) { continue; } if (host == null || host.zombie || host.callbacks == null) { continue; } Loading Loading @@ -2617,6 +2645,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku private void onUserStopped(int userId) { synchronized (mLock) { boolean providersChanged = false; boolean crossProfileWidgetsChanged = false; // Remove widgets that have both host and provider in the user. final int widgetCount = mWidgets.size(); for (int i = widgetCount - 1; i >= 0; i--) { Loading Loading @@ -2645,6 +2676,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku for (int i = hostCount - 1; i >= 0; i--) { Host host = mHosts.get(i); if (host.getUserId() == userId) { crossProfileWidgetsChanged |= !host.widgets.isEmpty(); deleteHostLocked(host); } } Loading @@ -2654,6 +2686,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku for (int i = providerCount - 1; i >= 0; i--) { Provider provider = mProviders.get(i); if (provider.getUserId() == userId) { crossProfileWidgetsChanged |= !provider.widgets.isEmpty(); providersChanged = true; deleteProviderLocked(provider); } } Loading @@ -2678,6 +2712,17 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku if (nextIdIndex >= 0) { mNextAppWidgetIds.removeAt(nextIdIndex); } // Announce removed provider changes to all hosts in the group. if (providersChanged) { scheduleNotifyGroupHostsForProvidersChangedLocked(userId); } // Save state if removing a profile changed the group state. // Nothing will be saved if the group parent was removed. if (crossProfileWidgetsChanged) { saveGroupStateAsync(userId); } } } Loading Loading @@ -2843,6 +2888,31 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } } @Override public void onCrossProfileWidgetProvidersChanged(int userId, List<String> packages) { final int parentId = mSecurityPolicy.getProfileParent(userId); // We care only if the white-listed package is in a profile of // the group parent as only the parent can add widgets from the // profile and not the other way around. if (parentId != userId) { synchronized (mLock) { boolean providersChanged = false; final int packageCount = packages.size(); for (int i = 0; i < packageCount; i++) { String packageName = packages.get(i); providersChanged |= updateProvidersForPackageLocked(packageName, userId, null); } if (providersChanged) { saveGroupStateAsync(userId); scheduleNotifyGroupHostsForProvidersChangedLocked(userId); } } } } private final class CallbackHandler extends Handler { public static final int MSG_NOTIFY_UPDATE_APP_WIDGET = 1; public static final int MSG_NOTIFY_PROVIDER_CHANGED = 2; Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +90 −35 Original line number Diff line number Diff line Loading @@ -165,6 +165,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final UserManager mUserManager; final PowerManager.WakeLock mWakeLock; final LocalService mLocalService; IPowerManager mIPowerManager; IWindowManager mIWindowManager; NotificationManager mNotificationManager; Loading Loading @@ -790,6 +792,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { PackageManager.FEATURE_DEVICE_ADMIN); mWakeLock = ((PowerManager)context.getSystemService(Context.POWER_SERVICE)) .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DPM"); mLocalService = new LocalService(); if (!mHasFeature) { // Skip the rest of the initialization return; Loading @@ -810,7 +813,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { filter.addDataScheme("package"); context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler); LocalServices.addService(DevicePolicyManagerInternal.class, new LocalService()); LocalServices.addService(DevicePolicyManagerInternal.class, mLocalService); } /** Loading Loading @@ -1899,34 +1902,60 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean addCrossProfileWidgetProvider(ComponentName admin, String packageName) { final int userId = UserHandle.getCallingUserId(); List<String> changedProviders = null; synchronized (this) { ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (activeAdmin.crossProfileWidgetProviders == null) { activeAdmin.crossProfileWidgetProviders = new ArrayList<>(); } if (activeAdmin.crossProfileWidgetProviders.add(packageName)) { saveSettingsLocked(UserHandle.getCallingUserId()); List<String> providers = activeAdmin.crossProfileWidgetProviders; if (!providers.contains(packageName)) { providers.add(packageName); changedProviders = new ArrayList<>(providers); saveSettingsLocked(userId); } } if (changedProviders != null) { mLocalService.notifyCrossProfileProvidersChanged(userId, changedProviders); return true; } return false; } @Override public boolean removeCrossProfileWidgetProvider(ComponentName admin, String packageName) { final int userId = UserHandle.getCallingUserId(); List<String> changedProviders = null; synchronized (this) { ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (activeAdmin.crossProfileWidgetProviders == null) { return false; } if (activeAdmin.crossProfileWidgetProviders.remove(packageName)) { saveSettingsLocked(UserHandle.getCallingUserId()); List<String> providers = activeAdmin.crossProfileWidgetProviders; if (providers.remove(packageName)) { changedProviders = new ArrayList<>(providers); saveSettingsLocked(userId); } } if (changedProviders != null) { mLocalService.notifyCrossProfileProvidersChanged(userId, changedProviders); return true; } return false; } @Override public List<String> getCrossProfileWidgetProviders(ComponentName admin) { synchronized (this) { ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (activeAdmin.crossProfileWidgetProviders == null Loading @@ -1939,6 +1968,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return activeAdmin.crossProfileWidgetProviders; } } } /** * Return a single admin's expiration date/time, or the min (soonest) for all admins. Loading Loading @@ -4674,8 +4704,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } private final class LocalService extends DevicePolicyManagerInternal { private List<OnCrossProfileWidgetProvidersChangeListener> mWidgetProviderListeners; @Override public List<String> getCrossProfileWidgetProviders(int profileId) { synchronized (DevicePolicyManagerService.this) { ComponentName ownerComponent = mDeviceOwner.getProfileOwnerComponent(profileId); if (ownerComponent == null) { return Collections.emptyList(); Loading @@ -4684,11 +4717,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { DevicePolicyData policy = getUserData(profileId); ActiveAdmin admin = policy.mAdminMap.get(ownerComponent); if (admin == null) { return Collections.emptyList(); } if (admin.crossProfileWidgetProviders == null if (admin == null || admin.crossProfileWidgetProviders == null || admin.crossProfileWidgetProviders.isEmpty()) { return Collections.emptyList(); } Loading @@ -4696,4 +4725,30 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return admin.crossProfileWidgetProviders; } } @Override public void addOnCrossProfileWidgetProvidersChangeListener( OnCrossProfileWidgetProvidersChangeListener listener) { synchronized (DevicePolicyManagerService.this) { if (mWidgetProviderListeners == null) { mWidgetProviderListeners = new ArrayList<>(); } if (!mWidgetProviderListeners.contains(listener)) { mWidgetProviderListeners.add(listener); } } } private void notifyCrossProfileProvidersChanged(int userId, List<String> packages) { final List<OnCrossProfileWidgetProvidersChangeListener> listeners; synchronized (DevicePolicyManagerService.this) { listeners = new ArrayList<>(mWidgetProviderListeners); } final int listenerCount = listeners.size(); for (int i = 0; i < listenerCount; i++) { OnCrossProfileWidgetProvidersChangeListener listener = listeners.get(i); listener.onCrossProfileWidgetProvidersChanged(userId, packages); } } } } Loading
core/java/android/app/admin/DevicePolicyManagerInternal.java +25 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,22 @@ import java.util.List; */ public abstract class DevicePolicyManagerInternal { /** * Listener for changes in the white-listed packages to show cross-profile * widgets. */ public interface OnCrossProfileWidgetProvidersChangeListener { /** * Called when the white-listed packages to show cross-profile widgets * have changed for a given user. * * @param profileId The profile for which the white-listed packages changed. * @param packages The white-listed packages. */ public void onCrossProfileWidgetProvidersChanged(int profileId, List<String> packages); } /** * Gets the packages whose widget providers are white-listed to be * available in the parent user. Loading @@ -35,4 +51,13 @@ public abstract class DevicePolicyManagerInternal { * profile. */ public abstract List<String> getCrossProfileWidgetProviders(int profileId); /** * Adds a listener for changes in the white-listed packages to show * cross-profile app widgets. * * @param listener The listener to add. */ public abstract void addOnCrossProfileWidgetProvidersChangeListener( OnCrossProfileWidgetProvidersChangeListener listener); }
services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +73 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.app.AlarmManager; import android.app.AppGlobals; import android.app.PendingIntent; import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.DevicePolicyManagerInternal.OnCrossProfileWidgetProvidersChangeListener; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.BroadcastReceiver; Loading Loading @@ -102,7 +103,8 @@ import java.util.Locale; import java.util.Map; import java.util.Set; class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBackupProvider { class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBackupProvider, OnCrossProfileWidgetProvidersChangeListener { private static final String TAG = "AppWidgetServiceImpl"; private static boolean DEBUG = false; Loading Loading @@ -199,6 +201,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku mSecurityPolicy = new SecurityPolicy(); computeMaximumWidgetBitmapMemory(); registerBroadcastReceiver(); registerOnCrossProfileProvidersChangedListener(); } private void computeMaximumWidgetBitmapMemory() { Loading Loading @@ -243,6 +246,15 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku userFilter, null, null); } private void registerOnCrossProfileProvidersChangedListener() { DevicePolicyManagerInternal devicePolicyManager = LocalServices.getService( DevicePolicyManagerInternal.class); // The device policy is an optional component. if (devicePolicyManager != null) { devicePolicyManager.addOnCrossProfileWidgetProvidersChangeListener(this); } } public void setSafeMode(boolean safeMode) { mSafeMode = safeMode; } Loading Loading @@ -368,7 +380,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku saveGroupStateAsync(userId); // If the set of providers has been modified, notify each active AppWidgetHost scheduleNotifyHostsForProvidersChangedLocked(); scheduleNotifyGroupHostsForProvidersChangedLocked(userId); } } } Loading Loading @@ -1657,11 +1669,27 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } } private void scheduleNotifyHostsForProvidersChangedLocked() { private void scheduleNotifyGroupHostsForProvidersChangedLocked(int userId) { final int[] profileIds = mSecurityPolicy.getEnabledGroupProfileIds(userId); final int N = mHosts.size(); for (int i = N - 1; i >= 0; i--) { Host host = mHosts.get(i); boolean hostInGroup = false; final int M = profileIds.length; for (int j = 0; j < M; j++) { final int profileId = profileIds[j]; if (host.getUserId() == profileId) { hostInGroup = true; break; } } if (!hostInGroup) { continue; } if (host == null || host.zombie || host.callbacks == null) { continue; } Loading Loading @@ -2617,6 +2645,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku private void onUserStopped(int userId) { synchronized (mLock) { boolean providersChanged = false; boolean crossProfileWidgetsChanged = false; // Remove widgets that have both host and provider in the user. final int widgetCount = mWidgets.size(); for (int i = widgetCount - 1; i >= 0; i--) { Loading Loading @@ -2645,6 +2676,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku for (int i = hostCount - 1; i >= 0; i--) { Host host = mHosts.get(i); if (host.getUserId() == userId) { crossProfileWidgetsChanged |= !host.widgets.isEmpty(); deleteHostLocked(host); } } Loading @@ -2654,6 +2686,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku for (int i = providerCount - 1; i >= 0; i--) { Provider provider = mProviders.get(i); if (provider.getUserId() == userId) { crossProfileWidgetsChanged |= !provider.widgets.isEmpty(); providersChanged = true; deleteProviderLocked(provider); } } Loading @@ -2678,6 +2712,17 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku if (nextIdIndex >= 0) { mNextAppWidgetIds.removeAt(nextIdIndex); } // Announce removed provider changes to all hosts in the group. if (providersChanged) { scheduleNotifyGroupHostsForProvidersChangedLocked(userId); } // Save state if removing a profile changed the group state. // Nothing will be saved if the group parent was removed. if (crossProfileWidgetsChanged) { saveGroupStateAsync(userId); } } } Loading Loading @@ -2843,6 +2888,31 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } } @Override public void onCrossProfileWidgetProvidersChanged(int userId, List<String> packages) { final int parentId = mSecurityPolicy.getProfileParent(userId); // We care only if the white-listed package is in a profile of // the group parent as only the parent can add widgets from the // profile and not the other way around. if (parentId != userId) { synchronized (mLock) { boolean providersChanged = false; final int packageCount = packages.size(); for (int i = 0; i < packageCount; i++) { String packageName = packages.get(i); providersChanged |= updateProvidersForPackageLocked(packageName, userId, null); } if (providersChanged) { saveGroupStateAsync(userId); scheduleNotifyGroupHostsForProvidersChangedLocked(userId); } } } } private final class CallbackHandler extends Handler { public static final int MSG_NOTIFY_UPDATE_APP_WIDGET = 1; public static final int MSG_NOTIFY_PROVIDER_CHANGED = 2; Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +90 −35 Original line number Diff line number Diff line Loading @@ -165,6 +165,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final UserManager mUserManager; final PowerManager.WakeLock mWakeLock; final LocalService mLocalService; IPowerManager mIPowerManager; IWindowManager mIWindowManager; NotificationManager mNotificationManager; Loading Loading @@ -790,6 +792,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { PackageManager.FEATURE_DEVICE_ADMIN); mWakeLock = ((PowerManager)context.getSystemService(Context.POWER_SERVICE)) .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DPM"); mLocalService = new LocalService(); if (!mHasFeature) { // Skip the rest of the initialization return; Loading @@ -810,7 +813,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { filter.addDataScheme("package"); context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler); LocalServices.addService(DevicePolicyManagerInternal.class, new LocalService()); LocalServices.addService(DevicePolicyManagerInternal.class, mLocalService); } /** Loading Loading @@ -1899,34 +1902,60 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean addCrossProfileWidgetProvider(ComponentName admin, String packageName) { final int userId = UserHandle.getCallingUserId(); List<String> changedProviders = null; synchronized (this) { ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (activeAdmin.crossProfileWidgetProviders == null) { activeAdmin.crossProfileWidgetProviders = new ArrayList<>(); } if (activeAdmin.crossProfileWidgetProviders.add(packageName)) { saveSettingsLocked(UserHandle.getCallingUserId()); List<String> providers = activeAdmin.crossProfileWidgetProviders; if (!providers.contains(packageName)) { providers.add(packageName); changedProviders = new ArrayList<>(providers); saveSettingsLocked(userId); } } if (changedProviders != null) { mLocalService.notifyCrossProfileProvidersChanged(userId, changedProviders); return true; } return false; } @Override public boolean removeCrossProfileWidgetProvider(ComponentName admin, String packageName) { final int userId = UserHandle.getCallingUserId(); List<String> changedProviders = null; synchronized (this) { ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (activeAdmin.crossProfileWidgetProviders == null) { return false; } if (activeAdmin.crossProfileWidgetProviders.remove(packageName)) { saveSettingsLocked(UserHandle.getCallingUserId()); List<String> providers = activeAdmin.crossProfileWidgetProviders; if (providers.remove(packageName)) { changedProviders = new ArrayList<>(providers); saveSettingsLocked(userId); } } if (changedProviders != null) { mLocalService.notifyCrossProfileProvidersChanged(userId, changedProviders); return true; } return false; } @Override public List<String> getCrossProfileWidgetProviders(ComponentName admin) { synchronized (this) { ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (activeAdmin.crossProfileWidgetProviders == null Loading @@ -1939,6 +1968,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return activeAdmin.crossProfileWidgetProviders; } } } /** * Return a single admin's expiration date/time, or the min (soonest) for all admins. Loading Loading @@ -4674,8 +4704,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } private final class LocalService extends DevicePolicyManagerInternal { private List<OnCrossProfileWidgetProvidersChangeListener> mWidgetProviderListeners; @Override public List<String> getCrossProfileWidgetProviders(int profileId) { synchronized (DevicePolicyManagerService.this) { ComponentName ownerComponent = mDeviceOwner.getProfileOwnerComponent(profileId); if (ownerComponent == null) { return Collections.emptyList(); Loading @@ -4684,11 +4717,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { DevicePolicyData policy = getUserData(profileId); ActiveAdmin admin = policy.mAdminMap.get(ownerComponent); if (admin == null) { return Collections.emptyList(); } if (admin.crossProfileWidgetProviders == null if (admin == null || admin.crossProfileWidgetProviders == null || admin.crossProfileWidgetProviders.isEmpty()) { return Collections.emptyList(); } Loading @@ -4696,4 +4725,30 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return admin.crossProfileWidgetProviders; } } @Override public void addOnCrossProfileWidgetProvidersChangeListener( OnCrossProfileWidgetProvidersChangeListener listener) { synchronized (DevicePolicyManagerService.this) { if (mWidgetProviderListeners == null) { mWidgetProviderListeners = new ArrayList<>(); } if (!mWidgetProviderListeners.contains(listener)) { mWidgetProviderListeners.add(listener); } } } private void notifyCrossProfileProvidersChanged(int userId, List<String> packages) { final List<OnCrossProfileWidgetProvidersChangeListener> listeners; synchronized (DevicePolicyManagerService.this) { listeners = new ArrayList<>(mWidgetProviderListeners); } final int listenerCount = listeners.size(); for (int i = 0; i < listenerCount; i++) { OnCrossProfileWidgetProvidersChangeListener listener = listeners.get(i); listener.onCrossProfileWidgetProvidersChanged(userId, packages); } } } }