Send broadcast when a device policy resource is updated
Bug: 188410712 Bug: 203548565 Test: manual Change-Id: Icad44019c3fd2691969eaaf6b518d2ddfb91d133
This commit is contained in:
@@ -7501,6 +7501,7 @@ package android.app.admin {
|
||||
field public static final String ACTION_CHECK_POLICY_COMPLIANCE = "android.app.action.CHECK_POLICY_COMPLIANCE";
|
||||
field public static final String ACTION_DEVICE_ADMIN_SERVICE = "android.app.action.DEVICE_ADMIN_SERVICE";
|
||||
field public static final String ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED";
|
||||
field public static final String ACTION_DEVICE_POLICY_RESOURCE_UPDATED = "android.app.action.DEVICE_POLICY_RESOURCE_UPDATED";
|
||||
field public static final String ACTION_GET_PROVISIONING_MODE = "android.app.action.GET_PROVISIONING_MODE";
|
||||
field public static final String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED";
|
||||
field public static final String ACTION_PROFILE_OWNER_CHANGED = "android.app.action.PROFILE_OWNER_CHANGED";
|
||||
@@ -7576,6 +7577,8 @@ package android.app.admin {
|
||||
field public static final String EXTRA_PROVISIONING_WIFI_SECURITY_TYPE = "android.app.extra.PROVISIONING_WIFI_SECURITY_TYPE";
|
||||
field public static final String EXTRA_PROVISIONING_WIFI_SSID = "android.app.extra.PROVISIONING_WIFI_SSID";
|
||||
field public static final String EXTRA_PROVISIONING_WIFI_USER_CERTIFICATE = "android.app.extra.PROVISIONING_WIFI_USER_CERTIFICATE";
|
||||
field public static final String EXTRA_RESOURCE_ID = "android.app.extra.RESOURCE_ID";
|
||||
field public static final String EXTRA_RESOURCE_TYPE_DRAWABLE = "android.app.extra.RESOURCE_TYPE_DRAWABLE";
|
||||
field public static final int FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY = 1; // 0x1
|
||||
field public static final int FLAG_MANAGED_CAN_ACCESS_PARENT = 2; // 0x2
|
||||
field public static final int FLAG_PARENT_CAN_ACCESS_MANAGED = 1; // 0x1
|
||||
|
||||
@@ -3188,6 +3188,36 @@ public class DevicePolicyManager {
|
||||
*/
|
||||
public static final int OPERATION_SAFETY_REASON_DRIVING_DISTRACTION = 1;
|
||||
|
||||
/**
|
||||
* Broadcast action: notify system apps (e.g. settings, SysUI, etc) that the device management
|
||||
* resources with IDs {@link #EXTRA_RESOURCE_ID} has been updated using, the updated resources
|
||||
* can be retrieved using {@link #getDrawable}.
|
||||
*
|
||||
* <p>This broadcast is sent to registered receivers only.
|
||||
*
|
||||
* <p> The following extras will be included to identify the type of resource being updated:
|
||||
* <ul>
|
||||
* <li>{@link #EXTRA_RESOURCE_TYPE_DRAWABLE} for drawable resources</li>
|
||||
* </ul>
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||||
public static final String ACTION_DEVICE_POLICY_RESOURCE_UPDATED =
|
||||
"android.app.action.DEVICE_POLICY_RESOURCE_UPDATED";
|
||||
|
||||
/**
|
||||
* A boolean extra for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to indicate that a
|
||||
* resource of type {@link Drawable} is being updated.
|
||||
*/
|
||||
public static final String EXTRA_RESOURCE_TYPE_DRAWABLE =
|
||||
"android.app.extra.RESOURCE_TYPE_DRAWABLE";
|
||||
|
||||
/**
|
||||
* An integer array extra for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to indicate which
|
||||
* drawable IDs (see {@link DevicePolicyResources.UpdatableDrawableId}) have been updated.
|
||||
*/
|
||||
public static final String EXTRA_RESOURCE_ID =
|
||||
"android.app.extra.RESOURCE_ID";
|
||||
|
||||
/** @hide */
|
||||
@NonNull
|
||||
@TestApi
|
||||
@@ -14396,13 +14426,16 @@ public class DevicePolicyManager {
|
||||
* {@link DevicePolicyResources.Drawable.Source}, it overrides any drawables that was set for
|
||||
* the same {@code drawableId} and {@code drawableStyle} for the provided source.
|
||||
*
|
||||
* <p>Sends a broadcast with action {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to
|
||||
* registered receivers when a resource has been updated successfully.
|
||||
*
|
||||
* <p>Important notes to consider when using this API:
|
||||
* <ul>
|
||||
* <li> {@link #getDrawable} references the resource
|
||||
* <li>{@link #getDrawable} references the resource
|
||||
* {@link DevicePolicyDrawableResource#getCallingPackageResourceId()} in the
|
||||
* calling package each time it gets called. You have to ensure that the resource is always
|
||||
* available in the calling package as long as it is used as an updated resource.
|
||||
* <li> You still have to re-call {@code setDrawables} even if you only make changes to the
|
||||
* <li>You still have to re-call {@code setDrawables} even if you only make changes to the
|
||||
* content of the resource with ID
|
||||
* {@link DevicePolicyDrawableResource#getCallingPackageResourceId()} as the content might be
|
||||
* cached and would need updating.
|
||||
@@ -14437,8 +14470,10 @@ public class DevicePolicyManager {
|
||||
* {@link DevicePolicyResources.Drawable.Source} will return the default drawable from
|
||||
* {@code defaultDrawableLoader}.
|
||||
*
|
||||
* @param drawableIds The list of IDs to remove
|
||||
* the updated resources for.
|
||||
* <p>Sends a broadcast with action {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to
|
||||
* registered receivers when a resource has been reset successfully.
|
||||
*
|
||||
* @param drawableIds The list of IDs to remove.
|
||||
*
|
||||
* @throws IllegalArgumentException if IDs are not defined in
|
||||
* {@link DevicePolicyResources.Drawable}
|
||||
@@ -14470,6 +14505,9 @@ public class DevicePolicyManager {
|
||||
* set a different value use
|
||||
* {@link #getDrawableForDensity(int, int, int, Callable)}.
|
||||
*
|
||||
* <p>Callers should register for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to get
|
||||
* notified when a resource has been updated.
|
||||
*
|
||||
* <p>Note that each call to this API loads the resource from the package that called
|
||||
* {@code setDrawables} to set the updated resource.
|
||||
*
|
||||
@@ -14492,6 +14530,9 @@ public class DevicePolicyManager {
|
||||
* could result in returning a different drawable than {@link #getDrawable(int, int, Callable)}
|
||||
* if an override was set for that specific source.
|
||||
*
|
||||
* <p>Callers should register for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to get
|
||||
* notified when a resource has been updated.
|
||||
*
|
||||
* @param drawableId The drawable ID to get the updated resource for.
|
||||
* @param drawableStyle The drawable style to use.
|
||||
* @param drawableSource The source for the caller.
|
||||
@@ -14536,6 +14577,9 @@ public class DevicePolicyManager {
|
||||
* Similar to {@link #getDrawable(int, int, Callable)}, but also accepts
|
||||
* {@code density}. See {@link Resources#getDrawableForDensity(int, int, Resources.Theme)}.
|
||||
*
|
||||
* <p>Callers should register for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to get
|
||||
* notified when a resource has been updated.
|
||||
*
|
||||
* @param drawableId The drawable ID to get the updated resource for.
|
||||
* @param drawableStyle The drawable style to use.
|
||||
* @param density The desired screen density indicated by the resource as
|
||||
@@ -14562,6 +14606,9 @@ public class DevicePolicyManager {
|
||||
* Similar to {@link #getDrawable(int, int, int, Callable)}, but also accepts
|
||||
* {@code density}. See {@link Resources#getDrawableForDensity(int, int, Resources.Theme)}.
|
||||
*
|
||||
* <p>Callers should register for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to get
|
||||
* notified when a resource has been updated.
|
||||
*
|
||||
* @param drawableId The drawable ID to get the updated resource for.
|
||||
* @param drawableStyle The drawable style to use.
|
||||
* @param drawableSource The source for the caller.
|
||||
|
||||
@@ -716,6 +716,7 @@
|
||||
|
||||
<!-- Added in T -->
|
||||
<protected-broadcast android:name="android.intent.action.REFRESH_SAFETY_SOURCES" />
|
||||
<protected-broadcast android:name="android.app.action.DEVICE_POLICY_RESOURCE_UPDATED" />
|
||||
|
||||
<!-- ====================================================================== -->
|
||||
<!-- RUNTIME PERMISSIONS -->
|
||||
|
||||
@@ -83,7 +83,11 @@ class DeviceManagementResourcesProvider {
|
||||
mInjector = requireNonNull(injector);
|
||||
}
|
||||
|
||||
void updateDrawables(@NonNull List<DevicePolicyDrawableResource> drawables) {
|
||||
/**
|
||||
* Returns {@code false} if no resources were updated.
|
||||
*/
|
||||
boolean updateDrawables(@NonNull List<DevicePolicyDrawableResource> drawables) {
|
||||
boolean updated = false;
|
||||
for (int i = 0; i < drawables.size(); i++) {
|
||||
int drawableId = drawables.get(i).getDrawableId();
|
||||
int drawableStyle = drawables.get(i).getDrawableStyle();
|
||||
@@ -93,40 +97,46 @@ class DeviceManagementResourcesProvider {
|
||||
Objects.requireNonNull(resource, "ParcelableResource must be provided.");
|
||||
|
||||
if (drawableSource == DevicePolicyResources.Drawable.Source.UNDEFINED) {
|
||||
updateDrawable(drawableId, drawableStyle, resource);
|
||||
updated |= updateDrawable(drawableId, drawableStyle, resource);
|
||||
} else {
|
||||
updateDrawableForSource(drawableId, drawableSource, resource);
|
||||
updated |= updateDrawableForSource(drawableId, drawableSource, resource);
|
||||
}
|
||||
}
|
||||
if (!drawables.isEmpty()) {
|
||||
synchronized (mLock) {
|
||||
write();
|
||||
}
|
||||
if (!updated) {
|
||||
return false;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
write();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDrawable(
|
||||
private boolean updateDrawable(
|
||||
int drawableId, int drawableStyle, ParcelableResource updatableResource) {
|
||||
if (!UPDATABLE_DRAWABLE_IDS.contains(drawableId)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't update drawable resource, invalid drawable "
|
||||
+ "id " + drawableId);
|
||||
"Can't update drawable resource, invalid drawable " + "id " + drawableId);
|
||||
}
|
||||
if (!UPDATABLE_DRAWABLE_STYLES.contains(drawableStyle)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't update drawable resource, invalid style id "
|
||||
+ drawableStyle);
|
||||
"Can't update drawable resource, invalid style id " + drawableStyle);
|
||||
}
|
||||
synchronized (mLock) {
|
||||
if (!mUpdatedDrawablesForStyle.containsKey(drawableId)) {
|
||||
mUpdatedDrawablesForStyle.put(drawableId, new HashMap<>());
|
||||
}
|
||||
ParcelableResource current = mUpdatedDrawablesForStyle.get(drawableId).get(
|
||||
drawableStyle);
|
||||
if (updatableResource.equals(current)) {
|
||||
return false;
|
||||
}
|
||||
mUpdatedDrawablesForStyle.get(drawableId).put(drawableStyle, updatableResource);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(b/214576716): change this to respect style
|
||||
private void updateDrawableForSource(
|
||||
private boolean updateDrawableForSource(
|
||||
int drawableId, int drawableSource, ParcelableResource updatableResource) {
|
||||
if (!UPDATABLE_DRAWABLE_IDS.contains(drawableId)) {
|
||||
throw new IllegalArgumentException("Can't update drawable resource, invalid drawable "
|
||||
@@ -140,21 +150,32 @@ class DeviceManagementResourcesProvider {
|
||||
if (!mUpdatedDrawablesForSource.containsKey(drawableId)) {
|
||||
mUpdatedDrawablesForSource.put(drawableId, new HashMap<>());
|
||||
}
|
||||
mUpdatedDrawablesForSource.get(drawableId).put(
|
||||
drawableSource, updatableResource);
|
||||
ParcelableResource current = mUpdatedDrawablesForSource.get(drawableId).get(
|
||||
drawableSource);
|
||||
if (updatableResource.equals(current)) {
|
||||
return false;
|
||||
}
|
||||
mUpdatedDrawablesForSource.get(drawableId).put(drawableSource, updatableResource);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void removeDrawables(@NonNull int[] drawableIds) {
|
||||
/**
|
||||
* Returns {@code false} if no resources were removed.
|
||||
*/
|
||||
boolean removeDrawables(@NonNull int[] drawableIds) {
|
||||
synchronized (mLock) {
|
||||
boolean removed = false;
|
||||
for (int i = 0; i < drawableIds.length; i++) {
|
||||
int drawableId = drawableIds[i];
|
||||
mUpdatedDrawablesForStyle.remove(drawableId);
|
||||
mUpdatedDrawablesForSource.remove(drawableId);
|
||||
removed |= mUpdatedDrawablesForStyle.remove(drawableId) != null
|
||||
|| mUpdatedDrawablesForSource.remove(drawableId) != null;
|
||||
}
|
||||
if (drawableIds.length != 0) {
|
||||
write();
|
||||
if (!removed) {
|
||||
return false;
|
||||
}
|
||||
write();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import static android.app.AppOpsManager.MODE_DEFAULT;
|
||||
import static android.app.admin.DeviceAdminReceiver.ACTION_COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED;
|
||||
import static android.app.admin.DeviceAdminReceiver.EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE;
|
||||
import static android.app.admin.DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE;
|
||||
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
|
||||
import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE;
|
||||
import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
|
||||
import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER;
|
||||
@@ -56,6 +57,8 @@ import static android.app.admin.DevicePolicyManager.DELEGATION_PACKAGE_ACCESS;
|
||||
import static android.app.admin.DevicePolicyManager.DELEGATION_PERMISSION_GRANT;
|
||||
import static android.app.admin.DevicePolicyManager.DELEGATION_SECURITY_LOGGING;
|
||||
import static android.app.admin.DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER;
|
||||
import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_ID;
|
||||
import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_TYPE_DRAWABLE;
|
||||
import static android.app.admin.DevicePolicyManager.ID_TYPE_BASE_INFO;
|
||||
import static android.app.admin.DevicePolicyManager.ID_TYPE_IMEI;
|
||||
import static android.app.admin.DevicePolicyManager.ID_TYPE_INDIVIDUAL_ATTESTATION;
|
||||
@@ -17976,12 +17979,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
|
||||
Objects.requireNonNull(drawables, "drawables must be provided.");
|
||||
|
||||
// TODO(b/203548565): add new broadcast to indicate a resource has changed
|
||||
mInjector.binderWithCleanCallingIdentity(() ->
|
||||
mDeviceManagementResourcesProvider.updateDrawables(drawables));
|
||||
mInjector.binderWithCleanCallingIdentity(() -> {
|
||||
if (mDeviceManagementResourcesProvider.updateDrawables(drawables)) {
|
||||
sendDrawableUpdatedBroadcast(
|
||||
drawables.stream().mapToInt(d -> d.getDrawableId()).toArray());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void resetDrawables(@NonNull int[] drawableIds) {
|
||||
Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
|
||||
@@ -17989,16 +17994,31 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
|
||||
Objects.requireNonNull(drawableIds, "drawableIds must be provided.");
|
||||
|
||||
// TODO(b/203548565): add new broadcast to indicate a resource has changed
|
||||
mInjector.binderWithCleanCallingIdentity(() ->
|
||||
mDeviceManagementResourcesProvider.removeDrawables(drawableIds));
|
||||
mInjector.binderWithCleanCallingIdentity(() -> {
|
||||
if (mDeviceManagementResourcesProvider.removeDrawables(drawableIds)) {
|
||||
sendDrawableUpdatedBroadcast(drawableIds);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableResource getDrawable(
|
||||
int drawableId, int drawableStyle, int drawableSource) {
|
||||
public ParcelableResource getDrawable(int drawableId, int drawableStyle, int drawableSource) {
|
||||
return mInjector.binderWithCleanCallingIdentity(() ->
|
||||
mDeviceManagementResourcesProvider.getDrawable(
|
||||
drawableId, drawableStyle, drawableSource));
|
||||
}
|
||||
|
||||
private void sendDrawableUpdatedBroadcast(int[] drawableIds) {
|
||||
final Intent intent = new Intent(ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
|
||||
intent.putExtra(EXTRA_RESOURCE_ID, drawableIds);
|
||||
intent.putExtra(EXTRA_RESOURCE_TYPE_DRAWABLE, /* value= */ true);
|
||||
intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
|
||||
intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
|
||||
|
||||
List<UserInfo> users = mUserManager.getAliveUsers();
|
||||
for (int i = 0; i < users.size(); i++) {
|
||||
UserHandle user = users.get(i).getUserHandle();
|
||||
mContext.sendBroadcastAsUser(intent, user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user