当前位置:网站首页>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;
}
边栏推荐
猜你喜欢
带你遨游银河系的 10 种分布式数据库
DJ-ZBS2漏电继电器
拿到PMP认证带来什么改变?
JVM(十九) -- 字节码与类的加载(四) -- 再谈类的加载器
利用OPNET进行网络单播(一服务器多客户端)仿真的设计、配置及注意点
张平安:加快云上数字创新,共建产业智慧生态
If you‘re running pod install manually, make sure flutter pub get is executed first.
《4》 Form
Phenomenon analysis when Autowired annotation is used for list
EGR-20USCM接地故障继电器
随机推荐
The sooner you understand the four rules of life, the more blessed you will be
Scheduledexecutorservice timer
Talk about mvcc multi version concurrency controller?
If you‘re running pod install manually, make sure flutter pub get is executed first.
【问道】编译原理
Is it necessary to renew the PMP certificate?
Error: No named parameter with the name ‘foregroundColor‘
2039: [Bluebridge cup 2022 preliminaries] Li Bai's enhanced version (dynamic planning)
Development thoughts of adding new requirements in secondary development
10 distributed databases that take you to the galaxy
项目经理如何凭借NPDP证书逆袭?看这里
[QT] custom control loading
Record a pressure measurement experience summary
QT控件样式系列(一)之QSlider
Creation and use of thread pool
《4》 Form
Dynamically generate tables
做自媒体视频剪辑,专业的人会怎么寻找背景音乐素材?
张平安:加快云上数字创新,共建产业智慧生态
Timer create timer