packages\apps\TvSettings\Settings\src\com\android\tv\settings\device\apps\ClearDataPreference.java
- @Override
- public void onOk() {
- final AppManagementFragment fragment =
- (AppManagementFragment) getTargetFragment();
- fragment.clearData();
- }
packages\apps\TvSettings\Settings\src\com\android\tv\settings\device\apps\AppManagementFragment.java
- public void clearData() {
- if (!clearDataAllowed()) {
- Log.e(TAG, "Attempt to clear data failed. Clear data is disabled for " + mPackageName);
- return;
- }
-
- mClearDataPreference.setClearingData(true);
- String spaceManagementActivityName = mEntry.info.manageSpaceActivityName;
- if (spaceManagementActivityName != null) {
- if (!ActivityManager.isUserAMonkey()) {
- Intent intent = new Intent(Intent.ACTION_DEFAULT);
- intent.setClassName(mEntry.info.packageName, spaceManagementActivityName);
- startActivityForResult(intent, REQUEST_MANAGE_SPACE);
- }
- } else {
- // Disabling clear cache preference while clearing data is in progress. See b/77815256
- // for details.
- mClearCachePreference.setClearingCache(true);
- ActivityManager am = (ActivityManager) getActivity().getSystemService(
- Context.ACTIVITY_SERVICE);
- boolean success = am.clearApplicationUserData(
- mEntry.info.packageName, new IPackageDataObserver.Stub() {
- public void onRemoveCompleted(
- final String packageName, final boolean succeeded) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mClearDataPreference.setClearingData(false);
- mClearCachePreference.setClearingCache(false);
- if (succeeded) {
- dataCleared(true);
- } else {
- dataCleared(false);
- }
- }
- });
- }
- });
- if (!success) {
- mClearDataPreference.setClearingData(false);
- dataCleared(false);
- }
- }
- mClearDataPreference.refresh();
- }
frameworks\base\core\java\android\app\ActivityManager.java
- @RequiresPermission(anyOf={Manifest.permission.CLEAR_APP_USER_DATA,
- Manifest.permission.ACCESS_INSTANT_APPS})
- @UnsupportedAppUsage
- public boolean clearApplicationUserData(String packageName, IPackageDataObserver observer) {
- try {
- return getService().clearApplicationUserData(packageName, false,
- observer, mContext.getUserId());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- @UnsupportedAppUsage
- public static IActivityManager getService() {
- return (IActivityManager)IActivityManagerSingleton.get();
- }
frameworks\base\core\java\android\app\IActivityManager.aidl
- boolean clearApplicationUserData(in String packageName, boolean keepState,
- in IPackageDataObserver observer, int userId);
frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
- @Override
- public boolean clearApplicationUserData(final String packageName, boolean keepState,
- final IPackageDataObserver observer, int userId) {
- enforceNotIsolatedCaller("clearApplicationUserData");
- int uid = Binder.getCallingUid();
- int pid = Binder.getCallingPid();
- final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
- ALLOW_FULL_ONLY, "clearApplicationUserData", null);
-
- final ApplicationInfo appInfo;
- final boolean isInstantApp;
-
- long callingId = Binder.clearCallingIdentity();
- try {
- IPackageManager pm = AppGlobals.getPackageManager();
- synchronized(this) {
- // Instant packages are not protected
- if (getPackageManagerInternalLocked().isPackageDataProtected(
- resolvedUserId, packageName)) {
- throw new SecurityException(
- "Cannot clear data for a protected package: " + packageName);
- }
-
- ApplicationInfo applicationInfo = null;
- try {
- applicationInfo = pm.getApplicationInfo(packageName,
- MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
- } catch (RemoteException e) {
- /* ignore */
- }
- appInfo = applicationInfo;
-
- final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
-
- if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
- pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("PID " + pid + " does not have permission "
- + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
- + " of package " + packageName);
- }
-
- final boolean hasInstantMetadata = getPackageManagerInternalLocked()
- .hasInstantApplicationMetadata(packageName, resolvedUserId);
- final boolean isUninstalledAppWithoutInstantMetadata =
- (appInfo == null && !hasInstantMetadata);
- isInstantApp = (appInfo != null && appInfo.isInstantApp())
- || hasInstantMetadata;
- final boolean canAccessInstantApps = checkComponentPermission(
- permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
- == PackageManager.PERMISSION_GRANTED;
-
- if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
- && !canAccessInstantApps)) {
- Slog.w(TAG, "Invalid packageName: " + packageName);
- if (observer != null) {
- try {
- observer.onRemoveCompleted(packageName, false);
- } catch (RemoteException e) {
- Slog.i(TAG, "Observer no longer exists.");
- }
- }
- return false;
- }
-
- if (appInfo != null) {
- forceStopPackageLocked(packageName, appInfo.uid, "clear data");
- mAtmInternal.removeRecentTasksByPackageName(packageName, resolvedUserId);
- }
- }
-
- final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
- @Override
- public void onRemoveCompleted(String packageName, boolean succeeded)
- throws RemoteException {
- if (appInfo != null) {
- synchronized (ActivityManagerService.this) {
- finishForceStopPackageLocked(packageName, appInfo.uid);
- }
- }
- final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
- Uri.fromParts("package", packageName, null));
- intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
- intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
- if (isInstantApp) {
- intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
- broadcastIntentInPackage("android", null, SYSTEM_UID, uid, pid, intent,
- null, null, 0, null, null, permission.ACCESS_INSTANT_APPS, null,
- false, false, resolvedUserId, false);
- } else {
- broadcastIntentInPackage("android", null, SYSTEM_UID, uid, pid, intent,
- null, null, 0, null, null, null, null, false, false, resolvedUserId,
- false);
- }
-
- if (observer != null) {
- observer.onRemoveCompleted(packageName, succeeded);
- }
- }
- };
-
- try {
- // Clear application user data
- pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
-
- if (appInfo != null) {
- // Restore already established notification state and permission grants,
- // so it told us to keep those intact -- it's about to emplace app data
- // that is appropriate for those bits of system state.
- if (!keepState) {
- // Remove all permissions granted from/to this package
- mUgmInternal.removeUriPermissionsForPackage(packageName, resolvedUserId,
- true, false);
-
- // Reset notification state
- INotificationManager inm = NotificationManager.getService();
- inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
- }
-
- // Clear its scheduled jobs
- JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
- js.cancelJobsForUid(appInfo.uid, "clear data");
-
- // Clear its pending alarms
- AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
- ami.removeAlarmsForUid(appInfo.uid);
- }
- } catch (RemoteException e) {
- }
- } finally {
- Binder.restoreCallingIdentity(callingId);
- }
- return true;
- }
frameworks/base/core/java/android/content/pm/IPackageManager.aidl
void clearApplicationUserData(in String packageName, IPackageDataObserver observer, int userId);
7.具体实现在PMSframeworks\base\services\core\java\com\android\server\pm\PackageManagerService.java
- @Override
- public void clearApplicationUserData(final String packageName,
- final IPackageDataObserver observer, final int userId) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CLEAR_APP_USER_DATA, null);
-
- final int callingUid = Binder.getCallingUid();
- mPermissionManager.enforceCrossUserPermission(callingUid, userId,
- true /* requireFullPermission */, false /* checkShell */, "clear application data");
-
- final PackageSetting ps = mSettings.getPackageLPr(packageName);
- final boolean filterApp =
- (ps != null && shouldFilterApplicationLocked(ps, callingUid, userId));
- if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
- throw new SecurityException("Cannot clear data for a protected package: "
- + packageName);
- }
- // Queue up an async operation since the package deletion may take a little while.
- mHandler.post(new Runnable() {
- public void run() {
- mHandler.removeCallbacks(this);
- final boolean succeeded;
- if (!filterApp) {
- try (PackageFreezer freezer = freezePackage(packageName,
- "clearApplicationUserData")) {
- synchronized (mInstallLock) {
- succeeded = clearApplicationUserDataLIF(packageName, userId);
- }
- synchronized (mLock) {
- mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
- packageName, userId);
- }
- }
- if (succeeded) {
- // invoke DeviceStorageMonitor's update method to clear any notifications
- DeviceStorageMonitorInternal dsm = LocalServices
- .getService(DeviceStorageMonitorInternal.class);
- if (dsm != null) {
- dsm.checkMemory();
- }
- if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
- == PERMISSION_GRANTED) {
- unsuspendForSuspendingPackage(packageName, userId);
- removeAllDistractingPackageRestrictions(userId);
- flushPackageRestrictionsAsUserInternalLocked(userId);
- }
- }
- } else {
- succeeded = false;
- }
- if (observer != null) {
- try {
- observer.onRemoveCompleted(packageName, succeeded);
- } catch (RemoteException e) {
- Log.i(TAG, "Observer no longer exists.");
- }
- } //end if observer
- } //end run
- });
- }
- private boolean clearApplicationUserDataLIF(String packageName, int userId) {
- if (packageName == null) {
- Slog.w(TAG, "Attempt to delete null packageName.");
- return false;
- }
-
- // Try finding details about the requested package
- AndroidPackage pkg;
- PackageSetting ps;
- synchronized (mLock) {
- pkg = mPackages.get(packageName);
- ps = mSettings.mPackages.get(packageName);
- if (pkg == null) {
- if (ps != null) {
- pkg = ps.pkg;
- }
- }
- }
- if (pkg == null) {
- Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
- return false;
- }
- mPermissionManager.resetRuntimePermissions(pkg, userId);
-
- clearAppDataLIF(pkg, userId,
- FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
-
- final int appId = UserHandle.getAppId(pkg.getUid());
- removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), userId, appId);
-
- UserManagerInternal umInternal = mInjector.getUserManagerInternal();
- final int flags;
- if (umInternal.isUserUnlockingOrUnlocked(userId)) {
- flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
- } else if (umInternal.isUserRunning(userId)) {
- flags = StorageManager.FLAG_STORAGE_DE;
- } else {
- flags = 0;
- }
- prepareAppDataContentsLIF(pkg, ps, userId, flags);
-
- return true;
- }
- private void clearAppDataLIF(AndroidPackage pkg, int userId, int flags) {
- if (pkg == null) {
- Slog.wtf(TAG, "Package was null!", new Throwable());
- return;
- }
- clearAppDataLeafLIF(pkg, userId, flags);
-
- if ((flags & Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES) == 0) {
- clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
- }
- }
- private void clearAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
- final PackageSetting ps;
- synchronized (mLock) {
- ps = mSettings.mPackages.get(pkg.getPackageName());
- }
- for (int realUserId : resolveUserIds(userId)) {
- final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
- try {
- mInstaller.clearAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId,
- flags, ceDataInode);
- } catch (InstallerException e) {
- Slog.w(TAG, String.valueOf(e));
- }
- }
- }
frameworks/base/services/core/java/com/android/server/pm/Installer.java
- public void clearAppData(String uuid, String packageName, int userId, int flags,
- long ceDataInode) throws InstallerException {
- if (!checkBeforeRemote()) return;
- try {
- mInstalld.clearAppData(uuid, packageName, userId, flags, ceDataInode);
- } catch (Exception e) {
- throw InstallerException.from(e);
- }
- }
frameworks/native/cmds/installd/binder/android/os/IInstalld.aidl
void clearAppData(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName,
int userId, int flags, long ceDataInode);
frameworks\native\cmds\installd\InstalldNativeService.cpp
- binder::Status InstalldNativeService::clearAppData(const std::unique_ptr<std::string>& uuid,
- const std::string& packageName, int32_t userId, int32_t flags, int64_t ceDataInode) {
- ENFORCE_UID(AID_SYSTEM);
- CHECK_ARGUMENT_UUID(uuid);
- CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
-
- const char* uuid_ = uuid ? uuid->c_str() : nullptr;
- const char* pkgname = packageName.c_str();
-
- binder::Status res = ok();
- if (flags & FLAG_STORAGE_CE) {
- auto path = create_data_user_ce_package_path(uuid_, userId, pkgname, ceDataInode);
- if (flags & FLAG_CLEAR_CACHE_ONLY) {
- path = read_path_inode(path, "cache", kXattrInodeCache);
- } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
- path = read_path_inode(path, "code_cache", kXattrInodeCodeCache);
- }
- if (access(path.c_str(), F_OK) == 0) {
- if (delete_dir_contents(path) != 0) {
- res = error("Failed to delete contents of " + path);
- } else if ((flags & (FLAG_CLEAR_CACHE_ONLY | FLAG_CLEAR_CODE_CACHE_ONLY)) == 0) {
- remove_path_xattr(path, kXattrInodeCache);
- remove_path_xattr(path, kXattrInodeCodeCache);
- }
- }
- }
- if (flags & FLAG_STORAGE_DE) {
- std::string suffix = "";
- bool only_cache = false;
- if (flags & FLAG_CLEAR_CACHE_ONLY) {
- suffix = CACHE_DIR_POSTFIX;
- only_cache = true;
- } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
- suffix = CODE_CACHE_DIR_POSTFIX;
- only_cache = true;
- }
-
- auto path = create_data_user_de_package_path(uuid_, userId, pkgname) + suffix;
- if (access(path.c_str(), F_OK) == 0) {
- if (delete_dir_contents(path) != 0) {
- res = error("Failed to delete contents of " + path);
- }
- }
- }
- if (flags & FLAG_STORAGE_EXTERNAL) {
- std::lock_guard<std::recursive_mutex> lock(mMountsLock);
- for (const auto& n : mStorageMounts) {
- auto extPath = n.second;
-
- if (android::base::GetBoolProperty(kFuseProp, false)) {
- std::regex re("^\\/mnt\\/pass_through\\/[0-9]+\\/emulated");
- if (std::regex_match(extPath, re)) {
- extPath += "/" + std::to_string(userId);
- }
- } else {
- if (n.first.compare(0, 14, "/mnt/media_rw/") != 0) {
- extPath += StringPrintf("/%d", userId);
- } else if (userId != 0) {
- // TODO: support devices mounted under secondary users
- continue;
- }
- }
-
- if (flags & FLAG_CLEAR_CACHE_ONLY) {
- // Clear only cached data from shared storage
- auto path = StringPrintf("%s/Android/data/%s/cache", extPath.c_str(), pkgname);
- if (delete_dir_contents(path, true) != 0) {
- res = error("Failed to delete contents of " + path);
- }
- } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
- // No code cache on shared storage
- } else {
- // Clear everything on shared storage
- auto path = StringPrintf("%s/Android/data/%s", extPath.c_str(), pkgname);
- if (delete_dir_contents(path, true) != 0) {
- res = error("Failed to delete contents of " + path);
- }
- path = StringPrintf("%s/Android/media/%s", extPath.c_str(), pkgname);
- if (delete_dir_contents(path, true) != 0) {
- res = error("Failed to delete contents of " + path);
- }
- // Note that we explicitly don't delete OBBs - those are only removed on
- // app uninstall.
- }
- }
- }
- return res;
- }