当前位置:网站首页>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;
}边栏推荐
- Scheduledexecutorservice timer
- 高级程序员必知必会,一文详解MySQL主从同步原理,推荐收藏
- No experts! Growth secrets for junior and intermediate programmers and "quasi programmers" who are still practicing in Universities
- Auto.js 获取手机所有app名字
- Phenomenon analysis when Autowired annotation is used for list
- Redis如何实现多可用区?
- 精彩速递|腾讯云数据库6月刊
- 创始人负债10亿,开课吧即将“下课”?
- 最长回文子串(动态规划)
- PMP证书有没有必要续期?
猜你喜欢

【opencv】图像形态学操作-opencv标记不同连通域的位置

Dynamically generate tables

10 distributed databases that take you to the galaxy

Pytest testing framework -- data driven

【js组件】自定义select

window定时计划任务

Longest palindrome substring (dynamic programming)
[email protected] Mapping relatio"/>Why JSON is used for calls between interfaces, how fastjson is assigned, fastjson 1.2 [email protected] Mapping relatio

PMP证书有没有必要续期?

Record a pressure measurement experience summary
随机推荐
y58.第三章 Kubernetes从入门到精通 -- 持续集成与部署(三一)
K6EL-100漏电继电器
Talk about mvcc multi version concurrency controller?
A cool "ghost" console tool
删除文件时提示‘源文件名长度大于系统支持的长度’无法删除解决办法
What changes will PMP certification bring?
带你遨游银河系的 10 种分布式数据库
JVM(十九) -- 字节码与类的加载(四) -- 再谈类的加载器
Auto. JS get all app names of mobile phones
SQL injection - secondary injection and multi statement injection
线程池的创建与使用
Complete code of C language neural network and its meaning
【最佳网页宽度及其实现】「建议收藏」
10 distributed databases that take you to the galaxy
Safe landing practice of software supply chain under salesforce containerized ISV scenario
qt 简单布局 盒子模型 加弹簧
Addressable 预下载
Wonderful express | Tencent cloud database June issue
Error: No named parameter with the name ‘foregroundColor‘
JVM(二十) -- 性能监控与调优(一) -- 概述