diff options
| author | 2018-12-10 18:28:56 -0700 | |
|---|---|---|
| committer | 2018-12-11 09:43:13 -0700 | |
| commit | dc50d4ca389743e6a20af3507b4fa442ed6d07be (patch) | |
| tree | 7c40b43bd7282b338ba8ce6226853ad29729b285 | |
| parent | 52fe5dd97fb749aad4f570914a22aebf8d0de1c1 (diff) | |
Iteration on contributed media APIs.
Offer an explicit DELETE_CONTRIBUTED_MEDIA flag that can be used when
uninstalling an app to indicate that any contributed media should be
deleted.
Adjust APIs to accept a specific UserHandle so we can pre-flight
check for valid UserManager state.
Bug: 116344240
Test: atest android.provider.cts.MediaStoreTest
Change-Id: Ief0ba27c913791d60f86a5d7252525c9c4539fc6
| -rw-r--r-- | api/system-current.txt | 5 | ||||
| -rw-r--r-- | api/test-current.txt | 4 | ||||
| -rw-r--r-- | core/java/android/content/pm/PackageManager.java | 10 | ||||
| -rw-r--r-- | core/java/android/provider/MediaStore.java | 52 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/PackageManagerService.java | 17 |
5 files changed, 57 insertions, 31 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index 29089b3e908a..36cffbd7c066 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4563,11 +4563,6 @@ package android.provider { field public static final int FLAG_REMOVABLE_USB = 524288; // 0x80000 } - public final class MediaStore { - method public static void deleteContributedMedia(android.content.Context, java.lang.String); - method public static long getContributedMediaSize(android.content.Context, java.lang.String); - } - public abstract class SearchIndexableData { ctor public SearchIndexableData(); ctor public SearchIndexableData(android.content.Context); diff --git a/api/test-current.txt b/api/test-current.txt index 5bedc7244430..cf0ccebb10bc 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -1006,8 +1006,8 @@ package android.provider { } public final class MediaStore { - method public static void deleteContributedMedia(android.content.Context, java.lang.String); - method public static long getContributedMediaSize(android.content.Context, java.lang.String); + method public static void deleteContributedMedia(android.content.Context, java.lang.String, android.os.UserHandle) throws java.io.IOException; + method public static long getContributedMediaSize(android.content.Context, java.lang.String, android.os.UserHandle) throws java.io.IOException; } public final class Settings { diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 0150f6a2765d..da39b6394f8f 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1399,6 +1399,16 @@ public abstract class PackageManager { public static final int DELETE_DONT_KILL_APP = 0x00000008; /** + * Flag parameter for {@link #deletePackage} to indicate that any + * contributed media should also be deleted during this uninstall. The + * meaning of "contributed" means it won't automatically be deleted when the + * app is uninstalled. + * + * @hide + */ + public static final int DELETE_CONTRIBUTED_MEDIA = 0x00000010; + + /** * Flag parameter for {@link #deletePackage} to indicate that package deletion * should be chatty. * diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index 14511657f4d0..7dfd4cd0389e 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -23,7 +23,6 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; -import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.app.Activity; @@ -50,6 +49,7 @@ import android.os.OperationCanceledException; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.UserHandle; +import android.os.UserManager; import android.os.storage.StorageManager; import android.os.storage.StorageVolume; import android.os.storage.VolumeInfo; @@ -2882,18 +2882,24 @@ public final class MediaStore { * * @hide */ - @SystemApi @TestApi @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA) - public static @BytesLong long getContributedMediaSize(Context context, String packageName) { - try (ContentProviderClient client = context.getContentResolver() - .acquireContentProviderClient(AUTHORITY)) { - final Bundle in = new Bundle(); - in.putString(Intent.EXTRA_PACKAGE_NAME, packageName); - final Bundle out = client.call(GET_CONTRIBUTED_MEDIA_CALL, null, in); - return out.getLong(Intent.EXTRA_INDEX); - } catch (RemoteException e) { - throw e.rethrowAsRuntimeException(); + public static @BytesLong long getContributedMediaSize(Context context, String packageName, + UserHandle user) throws IOException { + final UserManager um = context.getSystemService(UserManager.class); + if (um.isUserUnlocked(user) && um.isUserRunning(user)) { + try { + final ContentResolver resolver = context + .createPackageContextAsUser(packageName, 0, user).getContentResolver(); + final Bundle in = new Bundle(); + in.putString(Intent.EXTRA_PACKAGE_NAME, packageName); + final Bundle out = resolver.call(AUTHORITY, GET_CONTRIBUTED_MEDIA_CALL, null, in); + return out.getLong(Intent.EXTRA_INDEX); + } catch (Exception e) { + throw new IOException(e); + } + } else { + throw new IOException("User " + user + " must be unlocked and running"); } } @@ -2904,17 +2910,23 @@ public final class MediaStore { * * @hide */ - @SystemApi @TestApi @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA) - public static void deleteContributedMedia(Context context, String packageName) { - try (ContentProviderClient client = context.getContentResolver() - .acquireContentProviderClient(AUTHORITY)) { - final Bundle in = new Bundle(); - in.putString(Intent.EXTRA_PACKAGE_NAME, packageName); - client.call(DELETE_CONTRIBUTED_MEDIA_CALL, null, in); - } catch (RemoteException e) { - throw e.rethrowAsRuntimeException(); + public static void deleteContributedMedia(Context context, String packageName, + UserHandle user) throws IOException { + final UserManager um = context.getSystemService(UserManager.class); + if (um.isUserUnlocked(user) && um.isUserRunning(user)) { + try { + final ContentResolver resolver = context + .createPackageContextAsUser(packageName, 0, user).getContentResolver(); + final Bundle in = new Bundle(); + in.putString(Intent.EXTRA_PACKAGE_NAME, packageName); + resolver.call(AUTHORITY, DELETE_CONTRIBUTED_MEDIA_CALL, null, in); + } catch (Exception e) { + throw new IOException(e); + } + } else { + throw new IOException("User " + user + " must be unlocked and running"); } } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 888675c117e1..fde50a3aaa31 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -242,6 +242,7 @@ import android.os.storage.StorageManager; import android.os.storage.StorageManagerInternal; import android.os.storage.VolumeInfo; import android.os.storage.VolumeRecord; +import android.provider.MediaStore; import android.provider.Settings.Global; import android.provider.Settings.Secure; import android.security.KeyStore; @@ -17936,7 +17937,7 @@ public class PackageManagerService extends IPackageManager.Stub final int removedUserId = (user != null) ? user.getIdentifier() : UserHandle.USER_ALL; - clearPackageStateForUserLIF(ps, removedUserId, outInfo); + clearPackageStateForUserLIF(ps, removedUserId, outInfo, flags); markPackageUninstalledForUserLPw(ps, user); scheduleWritePackageRestrictionsLocked(user); return; @@ -17966,7 +17967,7 @@ public class PackageManagerService extends IPackageManager.Stub // we need to do is clear this user's data and save that // it is uninstalled. if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); - clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo); + clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo, flags); scheduleWritePackageRestrictionsLocked(user); return; } else { @@ -17982,7 +17983,7 @@ public class PackageManagerService extends IPackageManager.Stub // we need to do is clear this user's data and save that // it is uninstalled. if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); - clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo); + clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo, flags); scheduleWritePackageRestrictionsLocked(user); return; } @@ -18099,7 +18100,7 @@ public class PackageManagerService extends IPackageManager.Stub } private void clearPackageStateForUserLIF(PackageSetting ps, int userId, - PackageRemovedInfo outInfo) { + PackageRemovedInfo outInfo, int flags) { final PackageParser.Package pkg; synchronized (mPackages) { pkg = mPackages.get(ps.name); @@ -18124,6 +18125,14 @@ public class PackageManagerService extends IPackageManager.Stub } resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); } + // Also delete contributed media, when requested + if ((flags & PackageManager.DELETE_CONTRIBUTED_MEDIA) != 0) { + try { + MediaStore.deleteContributedMedia(mContext, ps.name, UserHandle.of(nextUserId)); + } catch (IOException e) { + Slog.w(TAG, "Failed to delete contributed media for " + ps.name, e); + } + } } if (outInfo != null) { |