• app clear data源码追踪


    1.入口 setting

    packages\apps\TvSettings\Settings\src\com\android\tv\settings\device\apps\ClearDataPreference.java

    1. @Override
    2. public void onOk() {
    3. final AppManagementFragment fragment =
    4. (AppManagementFragment) getTargetFragment();
    5. fragment.clearData();
    6. }

    2.进入 AppManagementFragment 

    packages\apps\TvSettings\Settings\src\com\android\tv\settings\device\apps\AppManagementFragment.java

    1. public void clearData() {
    2. if (!clearDataAllowed()) {
    3. Log.e(TAG, "Attempt to clear data failed. Clear data is disabled for " + mPackageName);
    4. return;
    5. }
    6. mClearDataPreference.setClearingData(true);
    7. String spaceManagementActivityName = mEntry.info.manageSpaceActivityName;
    8. if (spaceManagementActivityName != null) {
    9. if (!ActivityManager.isUserAMonkey()) {
    10. Intent intent = new Intent(Intent.ACTION_DEFAULT);
    11. intent.setClassName(mEntry.info.packageName, spaceManagementActivityName);
    12. startActivityForResult(intent, REQUEST_MANAGE_SPACE);
    13. }
    14. } else {
    15. // Disabling clear cache preference while clearing data is in progress. See b/77815256
    16. // for details.
    17. mClearCachePreference.setClearingCache(true);
    18. ActivityManager am = (ActivityManager) getActivity().getSystemService(
    19. Context.ACTIVITY_SERVICE);
    20. boolean success = am.clearApplicationUserData(
    21. mEntry.info.packageName, new IPackageDataObserver.Stub() {
    22. public void onRemoveCompleted(
    23. final String packageName, final boolean succeeded) {
    24. mHandler.post(new Runnable() {
    25. @Override
    26. public void run() {
    27. mClearDataPreference.setClearingData(false);
    28. mClearCachePreference.setClearingCache(false);
    29. if (succeeded) {
    30. dataCleared(true);
    31. } else {
    32. dataCleared(false);
    33. }
    34. }
    35. });
    36. }
    37. });
    38. if (!success) {
    39. mClearDataPreference.setClearingData(false);
    40. dataCleared(false);
    41. }
    42. }
    43. mClearDataPreference.refresh();
    44. }

    3.进入ActivityManager

    frameworks\base\core\java\android\app\ActivityManager.java

    1. @RequiresPermission(anyOf={Manifest.permission.CLEAR_APP_USER_DATA,
    2. Manifest.permission.ACCESS_INSTANT_APPS})
    3. @UnsupportedAppUsage
    4. public boolean clearApplicationUserData(String packageName, IPackageDataObserver observer) {
    5. try {
    6. return getService().clearApplicationUserData(packageName, false,
    7. observer, mContext.getUserId());
    8. } catch (RemoteException e) {
    9. throw e.rethrowFromSystemServer();
    10. }
    11. }
    1. @UnsupportedAppUsage
    2. public static IActivityManager getService() {
    3. return (IActivityManager)IActivityManagerSingleton.get();
    4. }

    4.进入  IActivityManager 

    frameworks\base\core\java\android\app\IActivityManager.aidl

    1. boolean clearApplicationUserData(in String packageName, boolean keepState,
    2. in IPackageDataObserver observer, int userId);

    5.具体方法实现在AMS

    frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java

    1. @Override
    2. public boolean clearApplicationUserData(final String packageName, boolean keepState,
    3. final IPackageDataObserver observer, int userId) {
    4. enforceNotIsolatedCaller("clearApplicationUserData");
    5. int uid = Binder.getCallingUid();
    6. int pid = Binder.getCallingPid();
    7. final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
    8. ALLOW_FULL_ONLY, "clearApplicationUserData", null);
    9. final ApplicationInfo appInfo;
    10. final boolean isInstantApp;
    11. long callingId = Binder.clearCallingIdentity();
    12. try {
    13. IPackageManager pm = AppGlobals.getPackageManager();
    14. synchronized(this) {
    15. // Instant packages are not protected
    16. if (getPackageManagerInternalLocked().isPackageDataProtected(
    17. resolvedUserId, packageName)) {
    18. throw new SecurityException(
    19. "Cannot clear data for a protected package: " + packageName);
    20. }
    21. ApplicationInfo applicationInfo = null;
    22. try {
    23. applicationInfo = pm.getApplicationInfo(packageName,
    24. MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
    25. } catch (RemoteException e) {
    26. /* ignore */
    27. }
    28. appInfo = applicationInfo;
    29. final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
    30. if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
    31. pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
    32. throw new SecurityException("PID " + pid + " does not have permission "
    33. + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
    34. + " of package " + packageName);
    35. }
    36. final boolean hasInstantMetadata = getPackageManagerInternalLocked()
    37. .hasInstantApplicationMetadata(packageName, resolvedUserId);
    38. final boolean isUninstalledAppWithoutInstantMetadata =
    39. (appInfo == null && !hasInstantMetadata);
    40. isInstantApp = (appInfo != null && appInfo.isInstantApp())
    41. || hasInstantMetadata;
    42. final boolean canAccessInstantApps = checkComponentPermission(
    43. permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
    44. == PackageManager.PERMISSION_GRANTED;
    45. if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
    46. && !canAccessInstantApps)) {
    47. Slog.w(TAG, "Invalid packageName: " + packageName);
    48. if (observer != null) {
    49. try {
    50. observer.onRemoveCompleted(packageName, false);
    51. } catch (RemoteException e) {
    52. Slog.i(TAG, "Observer no longer exists.");
    53. }
    54. }
    55. return false;
    56. }
    57. if (appInfo != null) {
    58. forceStopPackageLocked(packageName, appInfo.uid, "clear data");
    59. mAtmInternal.removeRecentTasksByPackageName(packageName, resolvedUserId);
    60. }
    61. }
    62. final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
    63. @Override
    64. public void onRemoveCompleted(String packageName, boolean succeeded)
    65. throws RemoteException {
    66. if (appInfo != null) {
    67. synchronized (ActivityManagerService.this) {
    68. finishForceStopPackageLocked(packageName, appInfo.uid);
    69. }
    70. }
    71. final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
    72. Uri.fromParts("package", packageName, null));
    73. intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
    74. intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
    75. intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
    76. if (isInstantApp) {
    77. intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
    78. broadcastIntentInPackage("android", null, SYSTEM_UID, uid, pid, intent,
    79. null, null, 0, null, null, permission.ACCESS_INSTANT_APPS, null,
    80. false, false, resolvedUserId, false);
    81. } else {
    82. broadcastIntentInPackage("android", null, SYSTEM_UID, uid, pid, intent,
    83. null, null, 0, null, null, null, null, false, false, resolvedUserId,
    84. false);
    85. }
    86. if (observer != null) {
    87. observer.onRemoveCompleted(packageName, succeeded);
    88. }
    89. }
    90. };
    91. try {
    92. // Clear application user data
    93. pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
    94. if (appInfo != null) {
    95. // Restore already established notification state and permission grants,
    96. // so it told us to keep those intact -- it's about to emplace app data
    97. // that is appropriate for those bits of system state.
    98. if (!keepState) {
    99. // Remove all permissions granted from/to this package
    100. mUgmInternal.removeUriPermissionsForPackage(packageName, resolvedUserId,
    101. true, false);
    102. // Reset notification state
    103. INotificationManager inm = NotificationManager.getService();
    104. inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
    105. }
    106. // Clear its scheduled jobs
    107. JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
    108. js.cancelJobsForUid(appInfo.uid, "clear data");
    109. // Clear its pending alarms
    110. AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
    111. ami.removeAlarmsForUid(appInfo.uid);
    112. }
    113. } catch (RemoteException e) {
    114. }
    115. } finally {
    116. Binder.restoreCallingIdentity(callingId);
    117. }
    118. return true;
    119. }

    6.进入 IPackageManager

    frameworks/base/core/java/android/content/pm/IPackageManager.aidl

    void clearApplicationUserData(in String packageName, IPackageDataObserver observer, int userId);

    7.具体实现在PMS

    frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java

    1. @Override
    2. public void clearApplicationUserData(final String packageName,
    3. final IPackageDataObserver observer, final int userId) {
    4. mContext.enforceCallingOrSelfPermission(
    5. android.Manifest.permission.CLEAR_APP_USER_DATA, null);
    6. final int callingUid = Binder.getCallingUid();
    7. mPermissionManager.enforceCrossUserPermission(callingUid, userId,
    8. true /* requireFullPermission */, false /* checkShell */, "clear application data");
    9. final PackageSetting ps = mSettings.getPackageLPr(packageName);
    10. final boolean filterApp =
    11. (ps != null && shouldFilterApplicationLocked(ps, callingUid, userId));
    12. if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
    13. throw new SecurityException("Cannot clear data for a protected package: "
    14. + packageName);
    15. }
    16. // Queue up an async operation since the package deletion may take a little while.
    17. mHandler.post(new Runnable() {
    18. public void run() {
    19. mHandler.removeCallbacks(this);
    20. final boolean succeeded;
    21. if (!filterApp) {
    22. try (PackageFreezer freezer = freezePackage(packageName,
    23. "clearApplicationUserData")) {
    24. synchronized (mInstallLock) {
    25. succeeded = clearApplicationUserDataLIF(packageName, userId);
    26. }
    27. synchronized (mLock) {
    28. mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
    29. packageName, userId);
    30. }
    31. }
    32. if (succeeded) {
    33. // invoke DeviceStorageMonitor's update method to clear any notifications
    34. DeviceStorageMonitorInternal dsm = LocalServices
    35. .getService(DeviceStorageMonitorInternal.class);
    36. if (dsm != null) {
    37. dsm.checkMemory();
    38. }
    39. if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
    40. == PERMISSION_GRANTED) {
    41. unsuspendForSuspendingPackage(packageName, userId);
    42. removeAllDistractingPackageRestrictions(userId);
    43. flushPackageRestrictionsAsUserInternalLocked(userId);
    44. }
    45. }
    46. } else {
    47. succeeded = false;
    48. }
    49. if (observer != null) {
    50. try {
    51. observer.onRemoveCompleted(packageName, succeeded);
    52. } catch (RemoteException e) {
    53. Log.i(TAG, "Observer no longer exists.");
    54. }
    55. } //end if observer
    56. } //end run
    57. });
    58. }
    1. private boolean clearApplicationUserDataLIF(String packageName, int userId) {
    2. if (packageName == null) {
    3. Slog.w(TAG, "Attempt to delete null packageName.");
    4. return false;
    5. }
    6. // Try finding details about the requested package
    7. AndroidPackage pkg;
    8. PackageSetting ps;
    9. synchronized (mLock) {
    10. pkg = mPackages.get(packageName);
    11. ps = mSettings.mPackages.get(packageName);
    12. if (pkg == null) {
    13. if (ps != null) {
    14. pkg = ps.pkg;
    15. }
    16. }
    17. }
    18. if (pkg == null) {
    19. Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
    20. return false;
    21. }
    22. mPermissionManager.resetRuntimePermissions(pkg, userId);
    23. clearAppDataLIF(pkg, userId,
    24. FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
    25. final int appId = UserHandle.getAppId(pkg.getUid());
    26. removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), userId, appId);
    27. UserManagerInternal umInternal = mInjector.getUserManagerInternal();
    28. final int flags;
    29. if (umInternal.isUserUnlockingOrUnlocked(userId)) {
    30. flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
    31. } else if (umInternal.isUserRunning(userId)) {
    32. flags = StorageManager.FLAG_STORAGE_DE;
    33. } else {
    34. flags = 0;
    35. }
    36. prepareAppDataContentsLIF(pkg, ps, userId, flags);
    37. return true;
    38. }
    1. private void clearAppDataLIF(AndroidPackage pkg, int userId, int flags) {
    2. if (pkg == null) {
    3. Slog.wtf(TAG, "Package was null!", new Throwable());
    4. return;
    5. }
    6. clearAppDataLeafLIF(pkg, userId, flags);
    7. if ((flags & Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES) == 0) {
    8. clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
    9. }
    10. }
    1. private void clearAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
    2. final PackageSetting ps;
    3. synchronized (mLock) {
    4. ps = mSettings.mPackages.get(pkg.getPackageName());
    5. }
    6. for (int realUserId : resolveUserIds(userId)) {
    7. final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
    8. try {
    9. mInstaller.clearAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId,
    10. flags, ceDataInode);
    11. } catch (InstallerException e) {
    12. Slog.w(TAG, String.valueOf(e));
    13. }
    14. }
    15. }

    8.进入 Installer

    frameworks/base/services/core/java/com/android/server/pm/Installer.java

    1. public void clearAppData(String uuid, String packageName, int userId, int flags,
    2. long ceDataInode) throws InstallerException {
    3. if (!checkBeforeRemote()) return;
    4. try {
    5. mInstalld.clearAppData(uuid, packageName, userId, flags, ceDataInode);
    6. } catch (Exception e) {
    7. throw InstallerException.from(e);
    8. }
    9. }

    9.进入 IInstalld

    frameworks/native/cmds/installd/binder/android/os/IInstalld.aidl

    void clearAppData(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName,
                int userId, int flags, long ceDataInode);
    

    10.具体清除动作在InstalldNativeService中定义 

    frameworks\native\cmds\installd\InstalldNativeService.cpp

    1. binder::Status InstalldNativeService::clearAppData(const std::unique_ptr<std::string>& uuid,
    2. const std::string& packageName, int32_t userId, int32_t flags, int64_t ceDataInode) {
    3. ENFORCE_UID(AID_SYSTEM);
    4. CHECK_ARGUMENT_UUID(uuid);
    5. CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    6. std::lock_guard<std::recursive_mutex> lock(mLock);
    7. const char* uuid_ = uuid ? uuid->c_str() : nullptr;
    8. const char* pkgname = packageName.c_str();
    9. binder::Status res = ok();
    10. if (flags & FLAG_STORAGE_CE) {
    11. auto path = create_data_user_ce_package_path(uuid_, userId, pkgname, ceDataInode);
    12. if (flags & FLAG_CLEAR_CACHE_ONLY) {
    13. path = read_path_inode(path, "cache", kXattrInodeCache);
    14. } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
    15. path = read_path_inode(path, "code_cache", kXattrInodeCodeCache);
    16. }
    17. if (access(path.c_str(), F_OK) == 0) {
    18. if (delete_dir_contents(path) != 0) {
    19. res = error("Failed to delete contents of " + path);
    20. } else if ((flags & (FLAG_CLEAR_CACHE_ONLY | FLAG_CLEAR_CODE_CACHE_ONLY)) == 0) {
    21. remove_path_xattr(path, kXattrInodeCache);
    22. remove_path_xattr(path, kXattrInodeCodeCache);
    23. }
    24. }
    25. }
    26. if (flags & FLAG_STORAGE_DE) {
    27. std::string suffix = "";
    28. bool only_cache = false;
    29. if (flags & FLAG_CLEAR_CACHE_ONLY) {
    30. suffix = CACHE_DIR_POSTFIX;
    31. only_cache = true;
    32. } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
    33. suffix = CODE_CACHE_DIR_POSTFIX;
    34. only_cache = true;
    35. }
    36. auto path = create_data_user_de_package_path(uuid_, userId, pkgname) + suffix;
    37. if (access(path.c_str(), F_OK) == 0) {
    38. if (delete_dir_contents(path) != 0) {
    39. res = error("Failed to delete contents of " + path);
    40. }
    41. }
    42. }
    43. if (flags & FLAG_STORAGE_EXTERNAL) {
    44. std::lock_guard<std::recursive_mutex> lock(mMountsLock);
    45. for (const auto& n : mStorageMounts) {
    46. auto extPath = n.second;
    47. if (android::base::GetBoolProperty(kFuseProp, false)) {
    48. std::regex re("^\\/mnt\\/pass_through\\/[0-9]+\\/emulated");
    49. if (std::regex_match(extPath, re)) {
    50. extPath += "/" + std::to_string(userId);
    51. }
    52. } else {
    53. if (n.first.compare(0, 14, "/mnt/media_rw/") != 0) {
    54. extPath += StringPrintf("/%d", userId);
    55. } else if (userId != 0) {
    56. // TODO: support devices mounted under secondary users
    57. continue;
    58. }
    59. }
    60. if (flags & FLAG_CLEAR_CACHE_ONLY) {
    61. // Clear only cached data from shared storage
    62. auto path = StringPrintf("%s/Android/data/%s/cache", extPath.c_str(), pkgname);
    63. if (delete_dir_contents(path, true) != 0) {
    64. res = error("Failed to delete contents of " + path);
    65. }
    66. } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
    67. // No code cache on shared storage
    68. } else {
    69. // Clear everything on shared storage
    70. auto path = StringPrintf("%s/Android/data/%s", extPath.c_str(), pkgname);
    71. if (delete_dir_contents(path, true) != 0) {
    72. res = error("Failed to delete contents of " + path);
    73. }
    74. path = StringPrintf("%s/Android/media/%s", extPath.c_str(), pkgname);
    75. if (delete_dir_contents(path, true) != 0) {
    76. res = error("Failed to delete contents of " + path);
    77. }
    78. // Note that we explicitly don't delete OBBs - those are only removed on
    79. // app uninstall.
    80. }
    81. }
    82. }
    83. return res;
    84. }

  • 相关阅读:
    python工程打包成可执行文件
    (科目三)数据库基础知识
    阿里巴巴面试题- - -多线程&并发篇(三十九)
    国家开放大学 模拟 试题 训练
    《混沌工程》读书笔记
    Go: panic / recover 简介与实践
    时光倒流-第12届蓝桥杯Scratch选拔赛真题精选
    ThreadLocal底层源码分析
    6个步骤实现 Postman 接口压力测试
    Leetcode49 字母异位词分组解析
  • 原文地址:https://blog.csdn.net/xiaowang_lj/article/details/125632070