diff options
Diffstat (limited to 'services')
4 files changed, 183 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index 7ec9b82..d5f045e 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -201,8 +201,8 @@ class MountService extends IMountService.Stub public static final String[] CRYPTO_TYPES = { "password", "default", "pattern", "pin" }; - private Context mContext; - private NativeDaemonConnector mConnector; + private final Context mContext; + private final NativeDaemonConnector mConnector; private final Object mVolumesLock = new Object(); diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java new file mode 100644 index 0000000..f2db791 --- /dev/null +++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.pm; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.ServiceManager; +import android.os.UserHandle; +import android.util.Log; + +import java.util.HashSet; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * {@hide} + */ +public class BackgroundDexOptService { + + static final String TAG = "BackgroundDexOptService"; + + private final BroadcastReceiver mIdleMaintenanceReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (Intent.ACTION_IDLE_MAINTENANCE_START.equals(action)) { + onIdleStart(); + } else if (Intent.ACTION_IDLE_MAINTENANCE_END.equals(action)) { + onIdleStop(); + } + } + }; + + final PackageManagerService mPackageManager; + + final AtomicBoolean mIdleTime = new AtomicBoolean(false); + + public BackgroundDexOptService(Context context) { + mPackageManager = (PackageManagerService)ServiceManager.getService("package"); + + IntentFilter idleMaintenanceFilter = new IntentFilter(); + idleMaintenanceFilter.addAction(Intent.ACTION_IDLE_MAINTENANCE_START); + idleMaintenanceFilter.addAction(Intent.ACTION_IDLE_MAINTENANCE_END); + context.registerReceiverAsUser(mIdleMaintenanceReceiver, UserHandle.ALL, + idleMaintenanceFilter, null, null); + } + + public boolean onIdleStart() { + Log.i(TAG, "onIdleStart"); + if (mPackageManager.isStorageLow()) { + return false; + } + final HashSet<String> pkgs = mPackageManager.getPackagesThatNeedDexOpt(); + if (pkgs == null) { + return false; + } + mIdleTime.set(true); + new Thread("BackgroundDexOptService_DexOpter") { + @Override + public void run() { + for (String pkg : pkgs) { + if (!mIdleTime.get()) { + break; + } + mPackageManager.performDexOpt(pkg, false); + } + } + }.start(); + return true; + } + + public void onIdleStop() { + Log.i(TAG, "onIdleStop"); + mIdleTime.set(false); + } +} diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 9804aee..c8b61f1 100755 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -624,6 +624,7 @@ public class PackageManagerService extends IPackageManager.Stub { } if (mBackgroundWriteRunning.compareAndSet(false, true)) { new Thread("PackageUsage_DiskWriter") { + @Override public void run() { try { write(true); @@ -1742,10 +1743,12 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public boolean isFirstBoot() { return !mRestoredSettings; } + @Override public boolean isOnlyCoreApps() { return mOnlyCore; } @@ -2042,6 +2045,7 @@ public class PackageManagerService extends IPackageManager.Stub { state, userId); } + @Override public boolean isPackageAvailable(String packageName, int userId) { if (!sUserManager.exists(userId)) return false; enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "is package available"); @@ -2079,6 +2083,7 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } + @Override public String[] currentToCanonicalPackageNames(String[] names) { String[] out = new String[names.length]; // reader @@ -2091,6 +2096,7 @@ public class PackageManagerService extends IPackageManager.Stub { return out; } + @Override public String[] canonicalToCurrentPackageNames(String[] names) { String[] out = new String[names.length]; // reader @@ -2151,6 +2157,7 @@ public class PackageManagerService extends IPackageManager.Stub { return pi; } + @Override public PermissionInfo getPermissionInfo(String name, int flags) { // reader synchronized (mPackages) { @@ -2162,6 +2169,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) { // reader synchronized (mPackages) { @@ -2185,6 +2193,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { // reader synchronized (mPackages) { @@ -2193,6 +2202,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { // reader synchronized (mPackages) { @@ -2278,6 +2288,7 @@ public class PackageManagerService extends IPackageManager.Stub { } + @Override public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CLEAR_APP_CACHE, null); @@ -2303,6 +2314,7 @@ public class PackageManagerService extends IPackageManager.Stub { }); } + @Override public void freeStorage(final long freeStorageSize, final IntentSender pi) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CLEAR_APP_CACHE, null); @@ -2424,6 +2436,7 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } + @Override public String[] getSystemSharedLibraryNames() { Set<String> libSet; synchronized (mPackages) { @@ -2438,6 +2451,7 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } + @Override public FeatureInfo[] getSystemAvailableFeatures() { Collection<FeatureInfo> featSet; synchronized (mPackages) { @@ -2456,6 +2470,7 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } + @Override public boolean hasSystemFeature(String name) { synchronized (mPackages) { return mAvailableFeatures.containsKey(name); @@ -2470,6 +2485,7 @@ public class PackageManagerService extends IPackageManager.Stub { + " is not privileged to communicate with user=" + userId); } + @Override public int checkPermission(String permName, String pkgName) { synchronized (mPackages) { PackageParser.Package p = mPackages.get(pkgName); @@ -2487,6 +2503,7 @@ public class PackageManagerService extends IPackageManager.Stub { return PackageManager.PERMISSION_DENIED; } + @Override public int checkUidPermission(String permName, int uid) { synchronized (mPackages) { Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); @@ -2661,18 +2678,21 @@ public class PackageManagerService extends IPackageManager.Stub { return added; } + @Override public boolean addPermission(PermissionInfo info) { synchronized (mPackages) { return addPermissionLocked(info, false); } } + @Override public boolean addPermissionAsync(PermissionInfo info) { synchronized (mPackages) { return addPermissionLocked(info, true); } } + @Override public void removePermission(String name) { synchronized (mPackages) { checkPermissionTreeLP(name); @@ -2717,6 +2737,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public void grantPermission(String packageName, String permissionName) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null); @@ -2746,6 +2767,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public void revokePermission(String packageName, String permissionName) { int changedAppId = -1; @@ -2804,12 +2826,14 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public boolean isProtectedBroadcast(String actionName) { synchronized (mPackages) { return mProtectedBroadcasts.contains(actionName); } } + @Override public int checkSignatures(String pkg1, String pkg2) { synchronized (mPackages) { final PackageParser.Package p1 = mPackages.get(pkg1); @@ -2822,6 +2846,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public int checkUidSignatures(int uid1, int uid2) { // Map to base uids. uid1 = UserHandle.getAppId(uid1); @@ -2961,6 +2986,7 @@ public class PackageManagerService extends IPackageManager.Stub { return PackageManager.SIGNATURE_NO_MATCH; } + @Override public String[] getPackagesForUid(int uid) { uid = UserHandle.getAppId(uid); // reader @@ -2984,6 +3010,7 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } + @Override public String getNameForUid(int uid) { // reader synchronized (mPackages) { @@ -2999,6 +3026,7 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } + @Override public int getUidForSharedUser(String sharedUserName) { if(sharedUserName == null) { return -1; @@ -3013,6 +3041,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public int getFlagsForUid(int uid) { synchronized (mPackages) { Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); @@ -3944,6 +3973,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) { ArrayList<ProviderInfo> finalList = null; @@ -3981,6 +4011,7 @@ public class PackageManagerService extends IPackageManager.Stub { return finalList; } + @Override public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { // reader @@ -3990,6 +4021,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public List<InstrumentationInfo> queryInstrumentation(String targetPackage, int flags) { ArrayList<InstrumentationInfo> finalList = @@ -4501,6 +4533,10 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public boolean performDexOpt(String packageName) { enforceSystemOrRoot("Only the system can request dexopt be performed"); + return performDexOpt(packageName, true); + } + + public boolean performDexOpt(String packageName, boolean updateUsage) { PackageParser.Package p; synchronized (mPackages) { @@ -4508,7 +4544,9 @@ public class PackageManagerService extends IPackageManager.Stub { if (p == null) { return false; } - p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); + if (updateUsage) { + p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); + } mPackageUsage.write(); if (!p.mDexOptNeeded) { return false; @@ -4521,6 +4559,25 @@ public class PackageManagerService extends IPackageManager.Stub { } } + public HashSet<String> getPackagesThatNeedDexOpt() { + HashSet<String> pkgs = null; + synchronized (mPackages) { + for (PackageParser.Package p : mPackages.values()) { + if (DEBUG_DEXOPT) { + Log.i(TAG, p.packageName + " mDexOptNeeded=" + p.mDexOptNeeded); + } + if (!p.mDexOptNeeded) { + continue; + } + if (pkgs == null) { + pkgs = new HashSet<String>(); + } + pkgs.add(p.packageName); + } + } + return pkgs; + } + public void shutdown() { mPackageUsage.write(true); } @@ -7261,6 +7318,7 @@ public class PackageManagerService extends IPackageManager.Stub { return mMediaMounted || Environment.isExternalStorageEmulated(); } + @Override public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { // writer synchronized (mPackages) { @@ -7446,6 +7504,7 @@ public class PackageManagerService extends IPackageManager.Stub { } /* Called when a downloaded package installation has been confirmed by the user */ + @Override public void installPackage( final Uri packageURI, final IPackageInstallObserver observer, final int flags, final String installerPackageName) { @@ -7463,6 +7522,7 @@ public class PackageManagerService extends IPackageManager.Stub { installerPackageName, verificationParams, encryptionParams); } + @Override public void installPackageWithVerificationAndEncryption(Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName, VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { @@ -7872,6 +7932,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public void finishPackageInstall(int token) { enforceSystemOrRoot("Only the system is allowed to finish installs"); @@ -7943,6 +8004,7 @@ public class PackageManagerService extends IPackageManager.Stub { -1); } + @Override public void setInstallerPackageName(String targetPackage, String installerPackageName) { final int uid = Binder.getCallingUid(); // writer @@ -10877,6 +10939,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public void deleteApplicationCacheFiles(final String packageName, final IPackageDataObserver observer) { mContext.enforceCallingOrSelfPermission( @@ -10929,6 +10992,7 @@ public class PackageManagerService extends IPackageManager.Stub { return true; } + @Override public void getPackageSizeInfo(final String packageName, int userHandle, final IPackageStatsObserver observer) { mContext.enforceCallingOrSelfPermission( @@ -11008,14 +11072,17 @@ public class PackageManagerService extends IPackageManager.Stub { } + @Override public void addPackageToPreferred(String packageName) { Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); } + @Override public void removePackageFromPreferred(String packageName) { Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); } + @Override public List<PackageInfo> getPreferredPackages(int flags) { return new ArrayList<PackageInfo>(); } @@ -11043,6 +11110,7 @@ public class PackageManagerService extends IPackageManager.Stub { return Build.VERSION_CODES.CUR_DEVELOPMENT; } + @Override public void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId) { addPreferredActivityInternal(filter, match, set, activity, true, userId); @@ -11079,6 +11147,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public void replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity) { if (filter.countActions() != 1) { @@ -11135,6 +11204,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public void clearPackagePreferredActivities(String packageName) { final int uid = Binder.getCallingUid(); // writer @@ -11198,6 +11268,7 @@ public class PackageManagerService extends IPackageManager.Stub { return changed; } + @Override public void resetPreferredActivities(int userId) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); @@ -11211,6 +11282,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public int getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName) { @@ -11518,6 +11590,7 @@ public class PackageManagerService extends IPackageManager.Stub { new int[] {UserHandle.getUserId(packageUid)}); } + @Override public void setPackageStoppedState(String packageName, boolean stopped, int userId) { if (!sUserManager.exists(userId)) return; final int uid = Binder.getCallingUid(); @@ -11534,6 +11607,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public String getInstallerPackageName(String packageName) { // reader synchronized (mPackages) { @@ -11563,6 +11637,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public void enterSafeMode() { enforceSystemOrRoot("Only the system can request entering safe mode"); @@ -11571,6 +11646,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override public void systemReady() { mSystemReady = true; @@ -11616,10 +11692,12 @@ public class PackageManagerService extends IPackageManager.Stub { sUserManager.systemReady(); } + @Override public boolean isSafeMode() { return mSafeMode; } + @Override public boolean hasSystemUidErrors() { return mHasSystemUidErrors; } @@ -12117,6 +12195,7 @@ public class PackageManagerService extends IPackageManager.Stub { /* * Update media status on PackageManager. */ + @Override public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { int callingUid = Binder.getCallingUid(); if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { @@ -12711,6 +12790,7 @@ public class PackageManagerService extends IPackageManager.Stub { }); } + @Override public boolean setInstallLocation(int loc) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, null); @@ -12726,6 +12806,7 @@ public class PackageManagerService extends IPackageManager.Stub { return false; } + @Override public int getInstallLocation() { return android.provider.Settings.Global.getInt(mContext.getContentResolver(), android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 7c9f7a8..722b797 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -73,6 +73,7 @@ import com.android.server.net.NetworkPolicyManagerService; import com.android.server.net.NetworkStatsService; import com.android.server.notification.NotificationManagerService; import com.android.server.os.SchedulingPolicyService; +import com.android.server.pm.BackgroundDexOptService; import com.android.server.pm.Installer; import com.android.server.pm.LauncherAppsService; import com.android.server.pm.PackageManagerService; @@ -962,6 +963,13 @@ public final class SystemServer { } catch (Throwable e) { Slog.e(TAG, "Failure starting TrustManagerService", e); } + + try { + Slog.i(TAG, "BackgroundDexOptService"); + new BackgroundDexOptService(context); + } catch (Throwable e) { + reportWtf("starting BackgroundDexOptService", e); + } } try { |