Merge "Update deletion conditions for a package's UsageStats." into sc-dev

This commit is contained in:
Varun Shah
2021-11-11 01:03:49 +00:00
committed by Android (Google) Code Review
5 changed files with 43 additions and 10 deletions

View File

@@ -16,6 +16,7 @@
package android.app.admin; package android.app.admin;
import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.UserIdInt; import android.annotation.UserIdInt;
import android.content.ComponentName; import android.content.ComponentName;
@@ -76,6 +77,13 @@ public abstract class DevicePolicyManagerInternal {
public abstract void addOnCrossProfileWidgetProvidersChangeListener( public abstract void addOnCrossProfileWidgetProvidersChangeListener(
OnCrossProfileWidgetProvidersChangeListener listener); OnCrossProfileWidgetProvidersChangeListener listener);
/**
* @param userHandle the handle of the user whose profile owner is being fetched.
* @return the configured supervision app if it exists and is the device owner or policy owner.
*/
public abstract @Nullable ComponentName getProfileOwnerOrDeviceOwnerSupervisionComponent(
@NonNull UserHandle userHandle);
/** /**
* Checks if an app with given uid is an active device owner of its user. * Checks if an app with given uid is an active device owner of its user.
* *

View File

@@ -12643,6 +12643,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
} }
} }
@Override
public @Nullable ComponentName getProfileOwnerOrDeviceOwnerSupervisionComponent(
@NonNull UserHandle userHandle) {
return DevicePolicyManagerService.this.getProfileOwnerOrDeviceOwnerSupervisionComponent(
userHandle);
}
@Override @Override
public boolean isActiveDeviceOwner(int uid) { public boolean isActiveDeviceOwner(int uid) {
return isDeviceOwner(new CallerIdentity(uid, null, null)); return isDeviceOwner(new CallerIdentity(uid, null, null));

View File

@@ -72,7 +72,7 @@ public class UserUsageStatsServiceTest {
HashMap<String, Long> installedPkgs = new HashMap<>(); HashMap<String, Long> installedPkgs = new HashMap<>();
installedPkgs.put(TEST_PACKAGE_NAME, System.currentTimeMillis()); installedPkgs.put(TEST_PACKAGE_NAME, System.currentTimeMillis());
mService.init(System.currentTimeMillis(), installedPkgs); mService.init(System.currentTimeMillis(), installedPkgs, true);
} }
@After @After

View File

@@ -380,6 +380,7 @@ public class UsageStatsService extends SystemService implements
if (userId == UserHandle.USER_SYSTEM) { if (userId == UserHandle.USER_SYSTEM) {
UsageStatsIdleService.scheduleUpdateMappingsJob(getContext()); UsageStatsIdleService.scheduleUpdateMappingsJob(getContext());
} }
final boolean deleteObsoleteData = shouldDeleteObsoleteData(UserHandle.of(userId));
synchronized (mLock) { synchronized (mLock) {
// This should be safe to add this early. Other than reportEventOrAddToQueue, every // This should be safe to add this early. Other than reportEventOrAddToQueue, every
// other user grabs the lock before accessing // other user grabs the lock before accessing
@@ -402,7 +403,7 @@ public class UsageStatsService extends SystemService implements
boolean needToFlush = !pendingEvents.isEmpty(); boolean needToFlush = !pendingEvents.isEmpty();
initializeUserUsageStatsServiceLocked(userId, System.currentTimeMillis(), initializeUserUsageStatsServiceLocked(userId, System.currentTimeMillis(),
installedPackages); installedPackages, deleteObsoleteData);
final UserUsageStatsService userService = getUserUsageStatsServiceLocked(userId); final UserUsageStatsService userService = getUserUsageStatsServiceLocked(userId);
if (userService == null) { if (userService == null) {
Slog.i(TAG, "Attempted to unlock stopped or removed user " + userId); Slog.i(TAG, "Attempted to unlock stopped or removed user " + userId);
@@ -596,13 +597,13 @@ public class UsageStatsService extends SystemService implements
* when the user is initially unlocked. * when the user is initially unlocked.
*/ */
private void initializeUserUsageStatsServiceLocked(int userId, long currentTimeMillis, private void initializeUserUsageStatsServiceLocked(int userId, long currentTimeMillis,
HashMap<String, Long> installedPackages) { HashMap<String, Long> installedPackages, boolean deleteObsoleteData) {
final File usageStatsDir = new File(Environment.getDataSystemCeDirectory(userId), final File usageStatsDir = new File(Environment.getDataSystemCeDirectory(userId),
"usagestats"); "usagestats");
final UserUsageStatsService service = new UserUsageStatsService(getContext(), userId, final UserUsageStatsService service = new UserUsageStatsService(getContext(), userId,
usageStatsDir, this); usageStatsDir, this);
try { try {
service.init(currentTimeMillis, installedPackages); service.init(currentTimeMillis, installedPackages, deleteObsoleteData);
mUserState.put(userId, service); mUserState.put(userId, service);
} catch (Exception e) { } catch (Exception e) {
if (mUserManager.isUserUnlocked(userId)) { if (mUserManager.isUserUnlocked(userId)) {
@@ -1165,6 +1166,10 @@ public class UsageStatsService extends SystemService implements
* Called by the Binder stub. * Called by the Binder stub.
*/ */
private boolean updatePackageMappingsData() { private boolean updatePackageMappingsData() {
// don't update the mappings if a profile user is defined
if (!shouldDeleteObsoleteData(UserHandle.SYSTEM)) {
return true; // return true so job scheduler doesn't reschedule the job
}
// fetch the installed packages outside the lock so it doesn't block package manager. // fetch the installed packages outside the lock so it doesn't block package manager.
final HashMap<String, Long> installedPkgs = getInstalledPackages(UserHandle.USER_SYSTEM); final HashMap<String, Long> installedPkgs = getInstalledPackages(UserHandle.USER_SYSTEM);
synchronized (mLock) { synchronized (mLock) {
@@ -1309,6 +1314,13 @@ public class UsageStatsService extends SystemService implements
} }
} }
private boolean shouldDeleteObsoleteData(UserHandle userHandle) {
final DevicePolicyManagerInternal dpmInternal = getDpmInternal();
// If a profile owner is not defined for the given user, obsolete data should be deleted
return dpmInternal == null
|| dpmInternal.getProfileOwnerOrDeviceOwnerSupervisionComponent(userHandle) == null;
}
private String buildFullToken(String packageName, String token) { private String buildFullToken(String packageName, String token) {
final StringBuilder sb = new StringBuilder(packageName.length() + token.length() + 1); final StringBuilder sb = new StringBuilder(packageName.length() + token.length() + 1);
sb.append(packageName); sb.append(packageName);
@@ -2532,8 +2544,12 @@ public class UsageStatsService extends SystemService implements
private class MyPackageMonitor extends PackageMonitor { private class MyPackageMonitor extends PackageMonitor {
@Override @Override
public void onPackageRemoved(String packageName, int uid) { public void onPackageRemoved(String packageName, int uid) {
mHandler.obtainMessage(MSG_PACKAGE_REMOVED, getChangingUserId(), 0, packageName) final int changingUserId = getChangingUserId();
.sendToTarget(); // Only remove the package's data if a profile owner is not defined for the user
if (shouldDeleteObsoleteData(UserHandle.of(changingUserId))) {
mHandler.obtainMessage(MSG_PACKAGE_REMOVED, changingUserId, 0, packageName)
.sendToTarget();
}
super.onPackageRemoved(packageName, uid); super.onPackageRemoved(packageName, uid);
} }
} }

View File

@@ -115,8 +115,9 @@ class UserUsageStatsService {
mSystemTimeSnapshot = System.currentTimeMillis(); mSystemTimeSnapshot = System.currentTimeMillis();
} }
void init(final long currentTimeMillis, HashMap<String, Long> installedPackages) { void init(final long currentTimeMillis, HashMap<String, Long> installedPackages,
readPackageMappingsLocked(installedPackages); boolean deleteObsoleteData) {
readPackageMappingsLocked(installedPackages, deleteObsoleteData);
mDatabase.init(currentTimeMillis); mDatabase.init(currentTimeMillis);
if (mDatabase.wasUpgradePerformed()) { if (mDatabase.wasUpgradePerformed()) {
mDatabase.prunePackagesDataOnUpgrade(installedPackages); mDatabase.prunePackagesDataOnUpgrade(installedPackages);
@@ -180,12 +181,13 @@ class UserUsageStatsService {
return mDatabase.onPackageRemoved(packageName, timeRemoved); return mDatabase.onPackageRemoved(packageName, timeRemoved);
} }
private void readPackageMappingsLocked(HashMap<String, Long> installedPackages) { private void readPackageMappingsLocked(HashMap<String, Long> installedPackages,
boolean deleteObsoleteData) {
mDatabase.readMappingsLocked(); mDatabase.readMappingsLocked();
// Package mappings for the system user are updated after 24 hours via a job scheduled by // Package mappings for the system user are updated after 24 hours via a job scheduled by
// UsageStatsIdleService to ensure restored data is not lost on first boot. Additionally, // UsageStatsIdleService to ensure restored data is not lost on first boot. Additionally,
// this makes user service initialization a little quicker on subsequent boots. // this makes user service initialization a little quicker on subsequent boots.
if (mUserId != UserHandle.USER_SYSTEM) { if (mUserId != UserHandle.USER_SYSTEM && deleteObsoleteData) {
updatePackageMappingsLocked(installedPackages); updatePackageMappingsLocked(installedPackages);
} }
} }