Prune unused static libs and instant apps if space needed am: f36d53cbfc
am: a8505b5448
Change-Id: I27762e5bf5141f7cc14a43163e67fcef13785419
This commit is contained in:
@@ -9893,13 +9893,49 @@ public final class Settings {
|
||||
public static final String ENABLE_EPHEMERAL_FEATURE = "enable_ephemeral_feature";
|
||||
|
||||
/**
|
||||
* The duration for caching uninstalled instant apps.
|
||||
* The min period for caching installed instant apps in milliseconds.
|
||||
* <p>
|
||||
* Type: long
|
||||
* @hide
|
||||
*/
|
||||
public static final String UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS =
|
||||
"uninstalled_instant_app_cache_duration_millis";
|
||||
public static final String INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
|
||||
"installed_instant_app_min_cache_period";
|
||||
|
||||
/**
|
||||
* The max period for caching installed instant apps in milliseconds.
|
||||
* <p>
|
||||
* Type: long
|
||||
* @hide
|
||||
*/
|
||||
public static final String INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
|
||||
"installed_instant_app_max_cache_period";
|
||||
|
||||
/**
|
||||
* The min period for caching uninstalled instant apps in milliseconds.
|
||||
* <p>
|
||||
* Type: long
|
||||
* @hide
|
||||
*/
|
||||
public static final String UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
|
||||
"uninstalled_instant_app_min_cache_period";
|
||||
|
||||
/**
|
||||
* The max period for caching uninstalled instant apps in milliseconds.
|
||||
* <p>
|
||||
* Type: long
|
||||
* @hide
|
||||
*/
|
||||
public static final String UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
|
||||
"uninstalled_instant_app_max_cache_period";
|
||||
|
||||
/**
|
||||
* The min period for caching unused static shared libs in milliseconds.
|
||||
* <p>
|
||||
* Type: long
|
||||
* @hide
|
||||
*/
|
||||
public static final String UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
|
||||
"unused_static_shared_lib_min_cache_period";
|
||||
|
||||
/**
|
||||
* Allows switching users when system user is locked.
|
||||
|
||||
@@ -310,7 +310,7 @@ message GlobalSettingsProto {
|
||||
SettingProto lte_service_forced = 265;
|
||||
SettingProto ephemeral_cookie_max_size_bytes = 266;
|
||||
SettingProto enable_ephemeral_feature = 267;
|
||||
SettingProto uninstalled_ephemeral_app_cache_duration_millis = 268;
|
||||
SettingProto installed_instant_app_min_cache_period = 268;
|
||||
SettingProto allow_user_switching_when_system_user_locked = 269;
|
||||
SettingProto boot_count = 270;
|
||||
SettingProto safe_boot_disallowed = 271;
|
||||
@@ -331,6 +331,10 @@ message GlobalSettingsProto {
|
||||
SettingProto network_recommendations_package = 286;
|
||||
SettingProto bluetooth_a2dp_supports_optional_codecs_prefix = 287;
|
||||
SettingProto bluetooth_a2dp_optional_codecs_enabled_prefix = 288;
|
||||
SettingProto installed_instant_app_max_cache_period = 289;
|
||||
SettingProto uninstalled_instant_app_min_cache_period = 290;
|
||||
SettingProto uninstalled_instant_app_max_cache_period = 291;
|
||||
SettingProto unused_static_shared_lib_min_cache_period = 292;
|
||||
}
|
||||
|
||||
message SecureSettingsProto {
|
||||
|
||||
@@ -335,7 +335,11 @@ public class SettingsBackupTest {
|
||||
Settings.Global.TRUSTED_SOUND,
|
||||
Settings.Global.TZINFO_UPDATE_CONTENT_URL,
|
||||
Settings.Global.TZINFO_UPDATE_METADATA_URL,
|
||||
Settings.Global.UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS,
|
||||
Settings.Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
|
||||
Settings.Global.INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
|
||||
Settings.Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
|
||||
Settings.Global.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
|
||||
Settings.Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
|
||||
Settings.Global.UNLOCK_SOUND,
|
||||
Settings.Global.USE_GOOGLE_MAIL,
|
||||
Settings.Global.VT_IMS_ENABLED,
|
||||
|
||||
@@ -888,8 +888,20 @@ class SettingsProtoDumpUtil {
|
||||
Settings.Global.ENABLE_EPHEMERAL_FEATURE,
|
||||
GlobalSettingsProto.ENABLE_EPHEMERAL_FEATURE);
|
||||
dumpSetting(s, p,
|
||||
Settings.Global.UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS,
|
||||
GlobalSettingsProto.UNINSTALLED_EPHEMERAL_APP_CACHE_DURATION_MILLIS);
|
||||
Settings.Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
|
||||
GlobalSettingsProto.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD);
|
||||
dumpSetting(s, p,
|
||||
Settings.Global.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
|
||||
GlobalSettingsProto.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD);
|
||||
dumpSetting(s, p,
|
||||
Settings.Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
|
||||
GlobalSettingsProto.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD);
|
||||
dumpSetting(s, p,
|
||||
Settings.Global.INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
|
||||
GlobalSettingsProto.INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD);
|
||||
dumpSetting(s, p,
|
||||
Settings.Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
|
||||
GlobalSettingsProto.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD);
|
||||
dumpSetting(s, p,
|
||||
Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED,
|
||||
GlobalSettingsProto.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED);
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.InstantAppInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageParser;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
@@ -32,6 +33,8 @@ import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.UserHandle;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.provider.Settings;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.AtomicFile;
|
||||
@@ -76,7 +79,16 @@ class InstantAppRegistry {
|
||||
|
||||
private static final String LOG_TAG = "InstantAppRegistry";
|
||||
|
||||
private static final long DEFAULT_UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS =
|
||||
static final long DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
|
||||
DEBUG ? 30 * 1000L /* thirty seconds */ : 7 * 24 * 60 * 60 * 1000L; /* one week */
|
||||
|
||||
private static final long DEFAULT_INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
|
||||
DEBUG ? 60 * 1000L /* one min */ : 6 * 30 * 24 * 60 * 60 * 1000L; /* six months */
|
||||
|
||||
static final long DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
|
||||
DEBUG ? 30 * 1000L /* thirty seconds */ : 7 * 24 * 60 * 60 * 1000L; /* one week */
|
||||
|
||||
private static final long DEFAULT_UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
|
||||
DEBUG ? 60 * 1000L /* one min */ : 6 * 30 * 24 * 60 * 60 * 1000L; /* six months */
|
||||
|
||||
private static final String INSTANT_APPS_FOLDER = "instant";
|
||||
@@ -535,46 +547,195 @@ class InstantAppRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
public void pruneInstantAppsLPw() {
|
||||
// For now we prune only state for uninstalled instant apps
|
||||
final long maxCacheDurationMillis = Settings.Global.getLong(
|
||||
void pruneInstantApps() {
|
||||
final long maxInstalledCacheDuration = Settings.Global.getLong(
|
||||
mService.mContext.getContentResolver(),
|
||||
Settings.Global.UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS,
|
||||
DEFAULT_UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS);
|
||||
Settings.Global.INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
|
||||
DEFAULT_INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD);
|
||||
|
||||
for (int userId : UserManagerService.getInstance().getUserIds()) {
|
||||
// Prune in-memory state
|
||||
removeUninstalledInstantAppStateLPw((UninstalledInstantAppState state) -> {
|
||||
final long elapsedCachingMillis = System.currentTimeMillis() - state.mTimestamp;
|
||||
return (elapsedCachingMillis > maxCacheDurationMillis);
|
||||
}, userId);
|
||||
final long maxUninstalledCacheDuration = Settings.Global.getLong(
|
||||
mService.mContext.getContentResolver(),
|
||||
Settings.Global.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
|
||||
DEFAULT_UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD);
|
||||
|
||||
// Prune on-disk state
|
||||
File instantAppsDir = getInstantApplicationsDir(userId);
|
||||
if (!instantAppsDir.exists()) {
|
||||
continue;
|
||||
}
|
||||
File[] files = instantAppsDir.listFiles();
|
||||
if (files == null) {
|
||||
continue;
|
||||
}
|
||||
for (File instantDir : files) {
|
||||
if (!instantDir.isDirectory()) {
|
||||
try {
|
||||
pruneInstantApps(Long.MAX_VALUE,
|
||||
maxInstalledCacheDuration, maxUninstalledCacheDuration);
|
||||
} catch (IOException e) {
|
||||
Slog.e(LOG_TAG, "Error pruning installed and uninstalled instant apps", e);
|
||||
}
|
||||
}
|
||||
|
||||
boolean pruneInstalledInstantApps(long neededSpace, long maxInstalledCacheDuration) {
|
||||
try {
|
||||
return pruneInstantApps(neededSpace, maxInstalledCacheDuration, Long.MAX_VALUE);
|
||||
} catch (IOException e) {
|
||||
Slog.e(LOG_TAG, "Error pruning installed instant apps", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean pruneUninstalledInstantApps(long neededSpace, long maxUninstalledCacheDuration) {
|
||||
try {
|
||||
return pruneInstantApps(neededSpace, Long.MAX_VALUE, maxUninstalledCacheDuration);
|
||||
} catch (IOException e) {
|
||||
Slog.e(LOG_TAG, "Error pruning uninstalled instant apps", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prunes instant apps until there is enough <code>neededSpace</code>. Both
|
||||
* installed and uninstalled instant apps are pruned that are older than
|
||||
* <code>maxInstalledCacheDuration</code> and <code>maxUninstalledCacheDuration</code>
|
||||
* respectively. All times are in milliseconds.
|
||||
*
|
||||
* @param neededSpace The space to ensure is free.
|
||||
* @param maxInstalledCacheDuration The max duration for caching installed apps in millis.
|
||||
* @param maxUninstalledCacheDuration The max duration for caching uninstalled apps in millis.
|
||||
* @return Whether enough space was freed.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private boolean pruneInstantApps(long neededSpace, long maxInstalledCacheDuration,
|
||||
long maxUninstalledCacheDuration) throws IOException {
|
||||
final StorageManager storage = mService.mContext.getSystemService(StorageManager.class);
|
||||
final File file = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
|
||||
|
||||
if (file.getUsableSpace() >= neededSpace) {
|
||||
return true;
|
||||
}
|
||||
|
||||
List<String> packagesToDelete = null;
|
||||
|
||||
final int[] allUsers;
|
||||
final long now = System.currentTimeMillis();
|
||||
|
||||
// Prune first installed instant apps
|
||||
synchronized (mService.mPackages) {
|
||||
allUsers = PackageManagerService.sUserManager.getUserIds();
|
||||
|
||||
final int packageCount = mService.mPackages.size();
|
||||
for (int i = 0; i < packageCount; i++) {
|
||||
final PackageParser.Package pkg = mService.mPackages.valueAt(i);
|
||||
if (now - pkg.getLatestPackageUseTimeInMills() < maxInstalledCacheDuration) {
|
||||
continue;
|
||||
}
|
||||
|
||||
File metadataFile = new File(instantDir, INSTANT_APP_METADATA_FILE);
|
||||
if (!metadataFile.exists()) {
|
||||
if (!(pkg.mExtras instanceof PackageSetting)) {
|
||||
continue;
|
||||
}
|
||||
final PackageSetting ps = (PackageSetting) pkg.mExtras;
|
||||
boolean installedOnlyAsInstantApp = false;
|
||||
for (int userId : allUsers) {
|
||||
if (ps.getInstalled(userId)) {
|
||||
if (ps.getInstantApp(userId)) {
|
||||
installedOnlyAsInstantApp = true;
|
||||
} else {
|
||||
installedOnlyAsInstantApp = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (installedOnlyAsInstantApp) {
|
||||
if (packagesToDelete == null) {
|
||||
packagesToDelete = new ArrayList<>();
|
||||
}
|
||||
packagesToDelete.add(pkg.packageName);
|
||||
}
|
||||
}
|
||||
|
||||
final long elapsedCachingMillis = System.currentTimeMillis()
|
||||
- metadataFile.lastModified();
|
||||
if (elapsedCachingMillis > maxCacheDurationMillis) {
|
||||
deleteDir(instantDir);
|
||||
if (packagesToDelete != null) {
|
||||
packagesToDelete.sort((String lhs, String rhs) -> {
|
||||
final PackageParser.Package lhsPkg = mService.mPackages.get(lhs);
|
||||
final PackageParser.Package rhsPkg = mService.mPackages.get(rhs);
|
||||
if (lhsPkg == null && rhsPkg == null) {
|
||||
return 0;
|
||||
} else if (lhsPkg == null) {
|
||||
return -1;
|
||||
} else if (rhsPkg == null) {
|
||||
return 1;
|
||||
} else {
|
||||
if (lhsPkg.getLatestPackageUseTimeInMills() >
|
||||
rhsPkg.getLatestPackageUseTimeInMills()) {
|
||||
return 1;
|
||||
} else if (lhsPkg.getLatestPackageUseTimeInMills() <
|
||||
rhsPkg.getLatestPackageUseTimeInMills()) {
|
||||
return -1;
|
||||
} else {
|
||||
if (lhsPkg.mExtras instanceof PackageSetting
|
||||
&& rhsPkg.mExtras instanceof PackageSetting) {
|
||||
final PackageSetting lhsPs = (PackageSetting) lhsPkg.mExtras;
|
||||
final PackageSetting rhsPs = (PackageSetting) rhsPkg.mExtras;
|
||||
if (lhsPs.firstInstallTime > rhsPs.firstInstallTime) {
|
||||
return 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (packagesToDelete != null) {
|
||||
final int packageCount = packagesToDelete.size();
|
||||
for (int i = 0; i < packageCount; i++) {
|
||||
final String packageToDelete = packagesToDelete.get(i);
|
||||
if (mService.deletePackageX(packageToDelete, PackageManager.VERSION_CODE_HIGHEST,
|
||||
UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
|
||||
== PackageManager.DELETE_SUCCEEDED) {
|
||||
if (file.getUsableSpace() >= neededSpace) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prune uninstalled instant apps
|
||||
synchronized (mService.mPackages) {
|
||||
// TODO: Track last used time for uninstalled instant apps for better pruning
|
||||
for (int userId : UserManagerService.getInstance().getUserIds()) {
|
||||
// Prune in-memory state
|
||||
removeUninstalledInstantAppStateLPw((UninstalledInstantAppState state) -> {
|
||||
final long elapsedCachingMillis = System.currentTimeMillis() - state.mTimestamp;
|
||||
return (elapsedCachingMillis > maxUninstalledCacheDuration);
|
||||
}, userId);
|
||||
|
||||
// Prune on-disk state
|
||||
File instantAppsDir = getInstantApplicationsDir(userId);
|
||||
if (!instantAppsDir.exists()) {
|
||||
continue;
|
||||
}
|
||||
File[] files = instantAppsDir.listFiles();
|
||||
if (files == null) {
|
||||
continue;
|
||||
}
|
||||
for (File instantDir : files) {
|
||||
if (!instantDir.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
File metadataFile = new File(instantDir, INSTANT_APP_METADATA_FILE);
|
||||
if (!metadataFile.exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final long elapsedCachingMillis = System.currentTimeMillis()
|
||||
- metadataFile.lastModified();
|
||||
if (elapsedCachingMillis > maxUninstalledCacheDuration) {
|
||||
deleteDir(instantDir);
|
||||
if (file.getUsableSpace() >= neededSpace) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private @Nullable List<InstantAppInfo> getInstalledInstantApplicationsLPr(
|
||||
|
||||
@@ -877,9 +877,9 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
new ParallelPackageParserCallback();
|
||||
|
||||
public static final class SharedLibraryEntry {
|
||||
public final String path;
|
||||
public final String apk;
|
||||
public final SharedLibraryInfo info;
|
||||
public final @Nullable String path;
|
||||
public final @Nullable String apk;
|
||||
public final @NonNull SharedLibraryInfo info;
|
||||
|
||||
SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
|
||||
String declaringPackageName, int declaringPackageVersionCode) {
|
||||
@@ -1314,6 +1314,9 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
// Delay time in millisecs
|
||||
static final int BROADCAST_DELAY = 10 * 1000;
|
||||
|
||||
private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
|
||||
2 * 60 * 60 * 1000L; /* two hours */
|
||||
|
||||
static UserManagerService sUserManager;
|
||||
|
||||
// Stores a list of users whose package restrictions file needs to be updated
|
||||
@@ -4236,9 +4239,24 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
}
|
||||
if (file.getUsableSpace() >= bytes) return;
|
||||
|
||||
// 5. Consider shared libraries with refcount=0 and age>2h
|
||||
// 5. Consider shared libraries with refcount=0 and age>min cache period
|
||||
if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
|
||||
android.provider.Settings.Global.getLong(mContext.getContentResolver(),
|
||||
Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
|
||||
DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 6. Consider dexopt output (aggressive only)
|
||||
// 7. Consider ephemeral apps not used in last week
|
||||
// TODO: Implement
|
||||
|
||||
// 7. Consider installed instant apps unused longer than min cache period
|
||||
if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
|
||||
android.provider.Settings.Global.getLong(mContext.getContentResolver(),
|
||||
Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
|
||||
InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 8. Consider cached app data (below quotas)
|
||||
try {
|
||||
@@ -4249,8 +4267,15 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
if (file.getUsableSpace() >= bytes) return;
|
||||
|
||||
// 9. Consider DropBox entries
|
||||
// 10. Consider ephemeral cookies
|
||||
// TODO: Implement
|
||||
|
||||
// 10. Consider instant meta-data (uninstalled apps) older that min cache period
|
||||
if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
|
||||
android.provider.Settings.Global.getLong(mContext.getContentResolver(),
|
||||
Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
|
||||
InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
mInstaller.freeCache(volumeUuid, bytes, 0);
|
||||
@@ -4262,6 +4287,69 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
throw new IOException("Failed to free " + bytes + " on storage device at " + file);
|
||||
}
|
||||
|
||||
private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
|
||||
throws IOException {
|
||||
final StorageManager storage = mContext.getSystemService(StorageManager.class);
|
||||
final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
|
||||
|
||||
List<VersionedPackage> packagesToDelete = null;
|
||||
final long now = System.currentTimeMillis();
|
||||
|
||||
synchronized (mPackages) {
|
||||
final int[] allUsers = sUserManager.getUserIds();
|
||||
final int libCount = mSharedLibraries.size();
|
||||
for (int i = 0; i < libCount; i++) {
|
||||
final SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
|
||||
if (versionedLib == null) {
|
||||
continue;
|
||||
}
|
||||
final int versionCount = versionedLib.size();
|
||||
for (int j = 0; j < versionCount; j++) {
|
||||
SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
|
||||
// Skip packages that are not static shared libs.
|
||||
if (!libInfo.isStatic()) {
|
||||
break;
|
||||
}
|
||||
// Important: We skip static shared libs used for some user since
|
||||
// in such a case we need to keep the APK on the device. The check for
|
||||
// a lib being used for any user is performed by the uninstall call.
|
||||
final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
|
||||
// Resolve the package name - we use synthetic package names internally
|
||||
final String internalPackageName = resolveInternalPackageNameLPr(
|
||||
declaringPackage.getPackageName(), declaringPackage.getVersionCode());
|
||||
final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
|
||||
// Skip unused static shared libs cached less than the min period
|
||||
// to prevent pruning a lib needed by a subsequently installed package.
|
||||
if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
|
||||
continue;
|
||||
}
|
||||
if (packagesToDelete == null) {
|
||||
packagesToDelete = new ArrayList<>();
|
||||
}
|
||||
packagesToDelete.add(new VersionedPackage(internalPackageName,
|
||||
declaringPackage.getVersionCode()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (packagesToDelete != null) {
|
||||
final int packageCount = packagesToDelete.size();
|
||||
for (int i = 0; i < packageCount; i++) {
|
||||
final VersionedPackage pkgToDelete = packagesToDelete.get(i);
|
||||
// Delete the package synchronously (will fail of the lib used for any user).
|
||||
if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getVersionCode(),
|
||||
UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
|
||||
== PackageManager.DELETE_SUCCEEDED) {
|
||||
if (volume.getUsableSpace() >= neededSpace) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update given flags based on encryption status of current user.
|
||||
*/
|
||||
@@ -10712,8 +10800,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
final int versionCount = versionedLib.size();
|
||||
for (int i = 0; i < versionCount; i++) {
|
||||
SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
|
||||
// TODO: We will change version code to long, so in the new API it is long
|
||||
final int libVersionCode = (int) libInfo.getDeclaringPackage()
|
||||
final int libVersionCode = libInfo.getDeclaringPackage()
|
||||
.getVersionCode();
|
||||
if (libInfo.getVersion() < pkg.staticSharedLibVersion) {
|
||||
minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
|
||||
@@ -18559,7 +18646,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
* persisting settings for later use
|
||||
* sending a broadcast if necessary
|
||||
*/
|
||||
private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
|
||||
int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
|
||||
final PackageRemovedInfo info = new PackageRemovedInfo(this);
|
||||
final boolean res;
|
||||
|
||||
@@ -24348,9 +24435,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
|
||||
|
||||
@Override
|
||||
public void pruneInstantApps() {
|
||||
synchronized (mPackages) {
|
||||
mInstantAppRegistry.pruneInstantAppsLPw();
|
||||
}
|
||||
mInstantAppRegistry.pruneInstantApps();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user