当前位置:网站首页>App clear data source code tracking
App clear data source code tracking
2022-07-07 05:25:00 【Novice Xiaowang】
1. entrance setting
packages\apps\TvSettings\Settings\src\com\android\tv\settings\device\apps\ClearDataPreference.java
@Override
public void onOk() {
final AppManagementFragment fragment =
(AppManagementFragment) getTargetFragment();
fragment.clearData();
}
2. Get into AppManagementFragment
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();
}
3. Get into ActivityManager
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();
}
4. Get into IActivityManager
frameworks\base\core\java\android\app\IActivityManager.aidl
boolean clearApplicationUserData(in String packageName, boolean keepState,
in IPackageDataObserver observer, int userId);
5. The specific method is implemented in AMS
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;
}
6. Get into IPackageManager
frameworks/base/core/java/android/content/pm/IPackageManager.aidl
void clearApplicationUserData(in String packageName, IPackageDataObserver observer, int userId);
7. The concrete realization is PMS
frameworks\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));
}
}
}
8. Get into Installer
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);
}
}
9. Get into 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. The specific clearing action is in InstalldNativeService In the definition of
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;
}
边栏推荐
- 背包问题(01背包,完全背包,动态规划)
- 漏电继电器JD1-100
- 1.AVL树:左右旋-bite
- DBSync新增对MongoDB、ES的支持
- ThinkPHP Association preload with
- Auto.js 获取手机所有app名字
- 《5》 Table
- When deleting a file, the prompt "the length of the source file name is greater than the length supported by the system" cannot be deleted. Solution
- Longest palindrome substring (dynamic programming)
- Wonderful express | Tencent cloud database June issue
猜你喜欢
随机推荐
Understand common network i/o models
SQL injection - secondary injection and multi statement injection
Two person game based on bevy game engine and FPGA
Where is NPDP product manager certification sacred?
Safe landing practice of software supply chain under salesforce containerized ISV scenario
磁盘监控相关命令
带你遨游银河系的 10 种分布式数据库
What changes will PMP certification bring?
最长公共子序列(LCS)(动态规划,递归)
Creation and use of thread pool
Array initialization of local variables
模拟线程通信
Let f (x) = Σ x^n/n^2, prove that f (x) + F (1-x) + lnxln (1-x) = Σ 1/n^2
Senior programmers must know and master. This article explains in detail the principle of MySQL master-slave synchronization, and recommends collecting
全链路压测:影子库与影子表之争
Annotation初体验
Zhang Ping'an: accelerate cloud digital innovation and jointly build an industrial smart ecosystem
[QT] custom control loading
Clickhouse (03) how to install and deploy Clickhouse
SQL injection HTTP header injection