diff options
author | Dianne Hackborn <hackbod@google.com> | 2012-06-29 15:00:21 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2012-06-29 15:00:21 -0700 |
commit | 183ce028f10442dd6ada59de8fa531d690134663 (patch) | |
tree | bb826af501467e58f564c7bf0675fa4868aba77d | |
parent | 074b54fbc0b6254c0ba308e0cf2e86c1cc929348 (diff) | |
download | frameworks_base-183ce028f10442dd6ada59de8fa531d690134663.zip frameworks_base-183ce028f10442dd6ada59de8fa531d690134663.tar.gz frameworks_base-183ce028f10442dd6ada59de8fa531d690134663.tar.bz2 |
Fix issue #6761130: Clearing app data in settings does not clear app's USB storage
The package manager calls to clear data / clear cache were not also
having default container service clear the data on external storage. Now
they do.
Change-Id: Ib5e5eb6adf2cac5a4cc094cc1a02ac8cfb6a2edf
3 files changed, 87 insertions, 0 deletions
diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl index c9f7a58..c82834f7 100755 --- a/core/java/com/android/internal/app/IMediaContainerService.aidl +++ b/core/java/com/android/internal/app/IMediaContainerService.aidl @@ -35,4 +35,5 @@ interface IMediaContainerService { long calculateDirectorySize(in String directory); /** Return file system stats: [0] is total bytes, [1] is available bytes */ long[] getFileSystemStats(in String path); + void clearDirectory(in String directory); } diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index f09c010..a28b8a4 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -246,6 +246,16 @@ public class DefaultContainerService extends IntentService { throw new IllegalStateException(e); } } + + @Override + public void clearDirectory(String path) throws RemoteException { + Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); + + final File directory = new File(path); + if (directory.exists() && directory.isDirectory()) { + eraseFiles(directory); + } + } }; public DefaultContainerService() { diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index e20cd02..3501e47 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -7728,6 +7728,80 @@ public class PackageManagerService extends IPackageManager.Stub { return ret; } + private final class ClearStorageConnection implements ServiceConnection { + IMediaContainerService mContainerService; + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + synchronized (this) { + mContainerService = IMediaContainerService.Stub.asInterface(service); + notifyAll(); + } + } + + @Override + public void onServiceDisconnected(ComponentName name) { + } + } + + private void clearExternalStorageDataSync(String packageName, boolean allData) { + final boolean mounted; + if (Environment.isExternalStorageEmulated()) { + mounted = true; + } else { + final String status = Environment.getExternalStorageState(); + + mounted = status.equals(Environment.MEDIA_MOUNTED) + || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); + } + + if (!mounted) { + return; + } + + final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); + ClearStorageConnection conn = new ClearStorageConnection(); + if (mContext.bindService(containerIntent, conn, Context.BIND_AUTO_CREATE)) { + try { + long timeout = SystemClock.uptimeMillis() + 5000; + synchronized (conn) { + long now = SystemClock.uptimeMillis(); + while (conn.mContainerService == null && now < timeout) { + try { + conn.wait(timeout - now); + } catch (InterruptedException e) { + } + } + } + if (conn.mContainerService == null) { + return; + } + final File externalCacheDir = Environment + .getExternalStorageAppCacheDirectory(packageName); + try { + conn.mContainerService.clearDirectory(externalCacheDir.toString()); + } catch (RemoteException e) { + } + if (allData) { + final File externalDataDir = Environment + .getExternalStorageAppDataDirectory(packageName); + try { + conn.mContainerService.clearDirectory(externalDataDir.toString()); + } catch (RemoteException e) { + } + final File externalMediaDir = Environment + .getExternalStorageAppMediaDirectory(packageName); + try { + conn.mContainerService.clearDirectory(externalMediaDir.toString()); + } catch (RemoteException e) { + } + } + } finally { + mContext.unbindService(conn); + } + } + } + @Override public void clearApplicationUserData(final String packageName, final IPackageDataObserver observer, final int userId) { @@ -7742,6 +7816,7 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mInstallLock) { succeeded = clearApplicationUserDataLI(packageName, userId); } + clearExternalStorageDataSync(packageName, true); if (succeeded) { // invoke DeviceStorageMonitor's update method to clear any notifications DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) @@ -7815,6 +7890,7 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mInstallLock) { succeded = deleteApplicationCacheFilesLI(packageName, userId); } + clearExternalStorageDataSync(packageName, false); if(observer != null) { try { observer.onRemoveCompleted(packageName, succeded); |