summaryrefslogtreecommitdiffstats
path: root/services/java
diff options
context:
space:
mode:
authorBrian Carlstrom <bdc@google.com>2014-04-28 22:11:01 -0700
committerBrian Carlstrom <bdc@google.com>2014-05-06 15:14:29 -0700
commit7395a8ab8a7c6b03c32500c934694dde80b9ade1 (patch)
treec58b373d189ae4fb54d912835ddc7da7da9a0e5e /services/java
parentff1ec4d9e7b7eb1b6303d147c796f8767ee6715b (diff)
downloadframeworks_base-7395a8ab8a7c6b03c32500c934694dde80b9ade1.zip
frameworks_base-7395a8ab8a7c6b03c32500c934694dde80b9ade1.tar.gz
frameworks_base-7395a8ab8a7c6b03c32500c934694dde80b9ade1.tar.bz2
Add BackgroundDexOptService
Change-Id: I0439a04f693ba92df906cbda34f8e53b32f63329
Diffstat (limited to 'services/java')
-rw-r--r--services/java/com/android/server/MountService.java2
-rw-r--r--services/java/com/android/server/SystemServer.java8
-rw-r--r--services/java/com/android/server/pm/BackgroundDexOptService.java91
-rwxr-xr-xservices/java/com/android/server/pm/PackageManagerService.java84
4 files changed, 183 insertions, 2 deletions
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index f73a92b..1fa0735 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -187,7 +187,7 @@ class MountService extends IMountService.Stub
public static final int FstrimCompleted = 700;
}
- private Context mContext;
+ private final Context mContext;
private NativeDaemonConnector mConnector;
private final Object mVolumesLock = new Object();
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index ade8414..8a3bc88 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -60,6 +60,7 @@ import com.android.server.media.MediaRouterService;
import com.android.server.net.NetworkPolicyManagerService;
import com.android.server.net.NetworkStatsService;
import com.android.server.os.SchedulingPolicyService;
+import com.android.server.pm.BackgroundDexOptService;
import com.android.server.pm.Installer;
import com.android.server.pm.PackageManagerService;
import com.android.server.pm.UserManagerService;
@@ -815,6 +816,13 @@ class ServerThread {
} catch (Throwable e) {
reportWtf("starting MediaRouterService", e);
}
+
+ try {
+ Slog.i(TAG, "BackgroundDexOptService");
+ new BackgroundDexOptService(context);
+ } catch (Throwable e) {
+ reportWtf("starting BackgroundDexOptService", e);
+ }
}
}
diff --git a/services/java/com/android/server/pm/BackgroundDexOptService.java b/services/java/com/android/server/pm/BackgroundDexOptService.java
new file mode 100644
index 0000000..f2db791
--- /dev/null
+++ b/services/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/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 9d9e383..e3e9d60 100755
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -614,6 +614,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (mBackgroundWriteRunning.compareAndSet(false, true)) {
new Thread("PackageUsage_DiskWriter") {
+ @Override
public void run() {
try {
write(true);
@@ -1688,10 +1689,12 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public boolean isFirstBoot() {
return !mRestoredSettings;
}
+ @Override
public boolean isOnlyCoreApps() {
return mOnlyCore;
}
@@ -1989,6 +1992,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");
@@ -2026,6 +2030,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return null;
}
+ @Override
public String[] currentToCanonicalPackageNames(String[] names) {
String[] out = new String[names.length];
// reader
@@ -2038,6 +2043,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return out;
}
+ @Override
public String[] canonicalToCurrentPackageNames(String[] names) {
String[] out = new String[names.length];
// reader
@@ -2098,6 +2104,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return pi;
}
+ @Override
public PermissionInfo getPermissionInfo(String name, int flags) {
// reader
synchronized (mPackages) {
@@ -2109,6 +2116,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
// reader
synchronized (mPackages) {
@@ -2132,6 +2140,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
// reader
synchronized (mPackages) {
@@ -2140,6 +2149,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
// reader
synchronized (mPackages) {
@@ -2225,6 +2235,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);
@@ -2250,6 +2261,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);
@@ -2353,6 +2365,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return null;
}
+ @Override
public String[] getSystemSharedLibraryNames() {
Set<String> libSet;
synchronized (mPackages) {
@@ -2367,6 +2380,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return null;
}
+ @Override
public FeatureInfo[] getSystemAvailableFeatures() {
Collection<FeatureInfo> featSet;
synchronized (mPackages) {
@@ -2385,6 +2399,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return null;
}
+ @Override
public boolean hasSystemFeature(String name) {
synchronized (mPackages) {
return mAvailableFeatures.containsKey(name);
@@ -2399,6 +2414,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);
@@ -2416,6 +2432,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));
@@ -2561,18 +2578,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);
@@ -2617,6 +2637,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public void grantPermission(String packageName, String permissionName) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
@@ -2646,6 +2667,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public void revokePermission(String packageName, String permissionName) {
int changedAppId = -1;
@@ -2704,12 +2726,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);
@@ -2722,6 +2746,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public int checkUidSignatures(int uid1, int uid2) {
// Map to base uids.
uid1 = UserHandle.getAppId(uid1);
@@ -2782,6 +2807,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return PackageManager.SIGNATURE_NO_MATCH;
}
+ @Override
public String[] getPackagesForUid(int uid) {
uid = UserHandle.getAppId(uid);
// reader
@@ -2805,6 +2831,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return null;
}
+ @Override
public String getNameForUid(int uid) {
// reader
synchronized (mPackages) {
@@ -2820,6 +2847,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return null;
}
+ @Override
public int getUidForSharedUser(String sharedUserName) {
if(sharedUserName == null) {
return -1;
@@ -2834,6 +2862,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public int getFlagsForUid(int uid) {
synchronized (mPackages) {
Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
@@ -3618,6 +3647,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public List<ProviderInfo> queryContentProviders(String processName,
int uid, int flags) {
ArrayList<ProviderInfo> finalList = null;
@@ -3655,6 +3685,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return finalList;
}
+ @Override
public InstrumentationInfo getInstrumentationInfo(ComponentName name,
int flags) {
// reader
@@ -3664,6 +3695,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
int flags) {
ArrayList<InstrumentationInfo> finalList =
@@ -4166,6 +4198,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) {
@@ -4173,7 +4209,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;
@@ -4186,6 +4224,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);
}
@@ -6913,6 +6970,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return mMediaMounted || Environment.isExternalStorageEmulated();
}
+ @Override
public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
// writer
synchronized (mPackages) {
@@ -7092,6 +7150,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) {
@@ -7109,6 +7168,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) {
@@ -7475,6 +7535,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public void finishPackageInstall(int token) {
enforceSystemOrRoot("Only the system is allowed to finish installs");
@@ -7546,6 +7607,7 @@ public class PackageManagerService extends IPackageManager.Stub {
-1);
}
+ @Override
public void setInstallerPackageName(String targetPackage, String installerPackageName) {
final int uid = Binder.getCallingUid();
// writer
@@ -10434,6 +10496,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public void deleteApplicationCacheFiles(final String packageName,
final IPackageDataObserver observer) {
mContext.enforceCallingOrSelfPermission(
@@ -10486,6 +10549,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return true;
}
+ @Override
public void getPackageSizeInfo(final String packageName, int userHandle,
final IPackageStatsObserver observer) {
mContext.enforceCallingOrSelfPermission(
@@ -10562,14 +10626,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>();
}
@@ -10597,6 +10664,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);
@@ -10633,6 +10701,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public void replacePreferredActivity(IntentFilter filter, int match,
ComponentName[] set, ComponentName activity) {
if (filter.countActions() != 1) {
@@ -10689,6 +10758,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public void clearPackagePreferredActivities(String packageName) {
final int uid = Binder.getCallingUid();
// writer
@@ -10752,6 +10822,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return changed;
}
+ @Override
public void resetPreferredActivities(int userId) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
@@ -10765,6 +10836,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public int getPreferredActivities(List<IntentFilter> outFilters,
List<ComponentName> outActivities, String packageName) {
@@ -10976,6 +11048,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();
@@ -10992,6 +11065,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public String getInstallerPackageName(String packageName) {
// reader
synchronized (mPackages) {
@@ -11021,6 +11095,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public void enterSafeMode() {
enforceSystemOrRoot("Only the system can request entering safe mode");
@@ -11029,6 +11104,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
public void systemReady() {
mSystemReady = true;
@@ -11074,10 +11150,12 @@ public class PackageManagerService extends IPackageManager.Stub {
sUserManager.systemReady();
}
+ @Override
public boolean isSafeMode() {
return mSafeMode;
}
+ @Override
public boolean hasSystemUidErrors() {
return mHasSystemUidErrors;
}
@@ -11517,6 +11595,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) {
@@ -12108,6 +12187,7 @@ public class PackageManagerService extends IPackageManager.Stub {
});
}
+ @Override
public boolean setInstallLocation(int loc) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
null);
@@ -12123,6 +12203,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,
@@ -12194,6 +12275,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return true;
}
+ @Override
public boolean isStorageLow() {
final long token = Binder.clearCallingIdentity();
try {