Merge "Make JobSchedulerService encryption aware."

This commit is contained in:
Jeff Sharkey
2015-12-20 22:40:43 +00:00
committed by Android (Google) Code Review
9 changed files with 108 additions and 65 deletions

View File

@@ -16,6 +16,7 @@
package android.content.pm;
import android.content.ComponentName;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -148,6 +149,11 @@ public class ComponentInfo extends PackageItemInfo {
return banner != 0 ? banner : applicationInfo.banner;
}
/** {@hide} */
public ComponentName getComponentName() {
return new ComponentName(packageName, name);
}
protected void dumpFront(Printer pw, String prefix) {
super.dumpFront(pw, prefix);
if (processName != null && !packageName.equals(processName)) {

View File

@@ -252,6 +252,14 @@ public abstract class PackageManager {
public static final int MATCH_ENCRYPTION_AWARE_AND_UNAWARE = MATCH_ENCRYPTION_AWARE_ONLY
| MATCH_ENCRYPTION_UNAWARE_ONLY;
/**
* {@link PackageInfo} flag: include only components from applications that
* are marked with {@link ApplicationInfo#FLAG_SYSTEM}.
*
* @hide
*/
public static final int MATCH_SYSTEM_ONLY = 0x00100000;
/**
* {@link PackageInfo} flag: use the default encryption matching behavior
* based on user state. Internal flag used to indicate that a system
@@ -260,7 +268,7 @@ public abstract class PackageManager {
*
* @hide
*/
public static final int MATCH_ENCRYPTION_DEFAULT = 0x00100000;
public static final int MATCH_ENCRYPTION_DEFAULT = 0x10000000;
/**
* Flag for {@link addCrossProfileIntentFilter}: if this flag is set:

View File

@@ -125,28 +125,28 @@ public class ArrayUtils {
/**
* Checks if given array is null or has zero elements.
*/
public static <T> boolean isEmpty(T[] array) {
public static <T> boolean isEmpty(@Nullable T[] array) {
return array == null || array.length == 0;
}
/**
* Checks if given array is null or has zero elements.
*/
public static boolean isEmpty(int[] array) {
public static boolean isEmpty(@Nullable int[] array) {
return array == null || array.length == 0;
}
/**
* Checks if given array is null or has zero elements.
*/
public static boolean isEmpty(long[] array) {
public static boolean isEmpty(@Nullable long[] array) {
return array == null || array.length == 0;
}
/**
* Checks if given array is null or has zero elements.
*/
public static boolean isEmpty(byte[] array) {
public static boolean isEmpty(@Nullable byte[] array) {
return array == null || array.length == 0;
}
@@ -156,7 +156,7 @@ public class ArrayUtils {
* @param value the value to check for
* @return true if the value is present in the array
*/
public static <T> boolean contains(T[] array, T value) {
public static <T> boolean contains(@Nullable T[] array, T value) {
return indexOf(array, value) != -1;
}
@@ -164,7 +164,7 @@ public class ArrayUtils {
* Return first index of {@code value} in {@code array}, or {@code -1} if
* not found.
*/
public static <T> int indexOf(T[] array, T value) {
public static <T> int indexOf(@Nullable T[] array, T value) {
if (array == null) return -1;
for (int i = 0; i < array.length; i++) {
if (Objects.equals(array[i], value)) return i;
@@ -175,7 +175,7 @@ public class ArrayUtils {
/**
* Test if all {@code check} items are contained in {@code array}.
*/
public static <T> boolean containsAll(T[] array, T[] check) {
public static <T> boolean containsAll(@Nullable T[] array, T[] check) {
if (check == null) return true;
for (T checkItem : check) {
if (!contains(array, checkItem)) {
@@ -185,7 +185,7 @@ public class ArrayUtils {
return true;
}
public static boolean contains(int[] array, int value) {
public static boolean contains(@Nullable int[] array, int value) {
if (array == null) return false;
for (int element : array) {
if (element == value) {
@@ -195,7 +195,7 @@ public class ArrayUtils {
return false;
}
public static boolean contains(long[] array, long value) {
public static boolean contains(@Nullable long[] array, long value) {
if (array == null) return false;
for (long element : array) {
if (element == value) {
@@ -205,10 +205,12 @@ public class ArrayUtils {
return false;
}
public static long total(long[] array) {
public static long total(@Nullable long[] array) {
long total = 0;
for (long value : array) {
total += value;
if (array != null) {
for (long value : array) {
total += value;
}
}
return total;
}
@@ -366,11 +368,11 @@ public class ArrayUtils {
return cur;
}
public static long[] cloneOrNull(long[] array) {
public static @Nullable long[] cloneOrNull(@Nullable long[] array) {
return (array != null) ? array.clone() : null;
}
public static <T> ArraySet<T> add(ArraySet<T> cur, T val) {
public static @NonNull <T> ArraySet<T> add(@Nullable ArraySet<T> cur, T val) {
if (cur == null) {
cur = new ArraySet<>();
}
@@ -378,7 +380,7 @@ public class ArrayUtils {
return cur;
}
public static <T> ArraySet<T> remove(ArraySet<T> cur, T val) {
public static @Nullable <T> ArraySet<T> remove(@Nullable ArraySet<T> cur, T val) {
if (cur == null) {
return null;
}
@@ -390,11 +392,11 @@ public class ArrayUtils {
}
}
public static <T> boolean contains(ArraySet<T> cur, T val) {
public static <T> boolean contains(@Nullable ArraySet<T> cur, T val) {
return (cur != null) ? cur.contains(val) : false;
}
public static <T> ArrayList<T> add(ArrayList<T> cur, T val) {
public static @NonNull <T> ArrayList<T> add(@Nullable ArrayList<T> cur, T val) {
if (cur == null) {
cur = new ArrayList<>();
}
@@ -402,7 +404,7 @@ public class ArrayUtils {
return cur;
}
public static <T> ArrayList<T> remove(ArrayList<T> cur, T val) {
public static @Nullable <T> ArrayList<T> remove(@Nullable ArrayList<T> cur, T val) {
if (cur == null) {
return null;
}
@@ -414,7 +416,7 @@ public class ArrayUtils {
}
}
public static <T> boolean contains(ArrayList<T> cur, T val) {
public static <T> boolean contains(@Nullable ArrayList<T> cur, T val) {
return (cur != null) ? cur.contains(val) : false;
}

View File

@@ -24,6 +24,7 @@ import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
import static com.android.internal.util.XmlUtils.writeIntAttribute;
import static com.android.internal.util.XmlUtils.writeLongAttribute;
import static com.android.internal.util.XmlUtils.writeStringAttribute;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
@@ -89,9 +90,6 @@ import android.util.Slog;
import android.util.TimeUtils;
import android.util.Xml;
import libcore.io.IoUtils;
import libcore.util.EmptyArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IMediaContainerService;
import com.android.internal.os.SomeArgs;
@@ -106,6 +104,9 @@ import com.android.server.NativeDaemonConnector.Command;
import com.android.server.NativeDaemonConnector.SensitiveArg;
import com.android.server.pm.PackageManagerService;
import libcore.io.IoUtils;
import libcore.util.EmptyArray;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

View File

@@ -978,7 +978,7 @@ public class InputManagerService extends IInputManager.Stub
final PackageManager pm = mContext.getPackageManager();
Intent intent = new Intent(InputManager.ACTION_QUERY_KEYBOARD_LAYOUTS);
for (ResolveInfo resolveInfo : pm.queryBroadcastReceivers(intent,
PackageManager.GET_META_DATA)) {
PackageManager.GET_META_DATA | PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE)) {
final ActivityInfo activityInfo = resolveInfo.activityInfo;
final int priority = resolveInfo.priority;
visitKeyboardLayoutsInPackage(pm, activityInfo, null, priority, visitor);
@@ -993,7 +993,8 @@ public class InputManagerService extends IInputManager.Stub
try {
ActivityInfo receiver = pm.getReceiverInfo(
new ComponentName(d.packageName, d.receiverName),
PackageManager.GET_META_DATA);
PackageManager.GET_META_DATA
| PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE);
visitKeyboardLayoutsInPackage(pm, receiver, d.keyboardLayoutName, 0, visitor);
} catch (NameNotFoundException ex) {
}

View File

@@ -16,20 +16,14 @@
package com.android.server.job;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.AppGlobals;
import android.app.IUidObserver;
import android.app.job.IJobScheduler;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.app.job.IJobScheduler;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -53,6 +47,7 @@ import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.app.IBatteryStats;
import com.android.internal.util.ArrayUtils;
import com.android.server.DeviceIdleController;
import com.android.server.LocalServices;
import com.android.server.job.controllers.AppIdleController;
@@ -63,6 +58,15 @@ import com.android.server.job.controllers.JobStatus;
import com.android.server.job.controllers.StateController;
import com.android.server.job.controllers.TimeController;
import libcore.util.EmptyArray;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
/**
* Responsible for taking jobs representing work to be performed by a client app, and determining
* based on the criteria specified when that job should be run against the client application's
@@ -126,7 +130,7 @@ public class JobSchedulerService extends com.android.server.SystemService
*/
final ArrayList<JobStatus> mPendingJobs = new ArrayList<>();
final ArrayList<Integer> mStartedUsers = new ArrayList<>();
int[] mStartedUsers = EmptyArray.INT;
final JobHandler mHandler;
final JobSchedulerStub mJobSchedulerStub;
@@ -201,14 +205,20 @@ public class JobSchedulerService extends com.android.server.SystemService
@Override
public void onStartUser(int userHandle) {
mStartedUsers.add(userHandle);
mStartedUsers = ArrayUtils.appendInt(mStartedUsers, userHandle);
// Let's kick any outstanding jobs for this user.
mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
}
@Override
public void onUnlockUser(int userHandle) {
// Let's kick any outstanding jobs for this user.
mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
}
@Override
public void onStopUser(int userHandle) {
mStartedUsers.remove(Integer.valueOf(userHandle));
mStartedUsers = ArrayUtils.removeInt(mStartedUsers, userHandle);
}
/**
@@ -744,7 +754,7 @@ public class JobSchedulerService extends com.android.server.SystemService
*/
private void maybeQueueReadyJobsForExecutionLockedH() {
int chargingCount = 0;
int idleCount = 0;
int idleCount = 0;
int backoffCount = 0;
int connectivityCount = 0;
List<JobStatus> runnableJobs = null;
@@ -812,18 +822,31 @@ public class JobSchedulerService extends com.android.server.SystemService
* - It's not pending.
* - It's not already running on a JSC.
* - The user that requested the job is running.
* - The component is enabled and runnable.
*/
private boolean isReadyToBeExecutedLocked(JobStatus job) {
final boolean jobReady = job.isReady();
final boolean jobPending = mPendingJobs.contains(job);
final boolean jobActive = isCurrentlyActiveLocked(job);
final boolean userRunning = mStartedUsers.contains(job.getUserId());
final int userId = job.getUserId();
final boolean userStarted = ArrayUtils.contains(mStartedUsers, userId);
final boolean componentPresent;
try {
componentPresent = (AppGlobals.getPackageManager().getServiceInfo(
job.getServiceComponent(), PackageManager.MATCH_ENCRYPTION_DEFAULT,
userId) != null);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
if (DEBUG) {
Slog.v(TAG, "isReadyToBeExecutedLocked: " + job.toShortString()
+ " ready=" + jobReady + " pending=" + jobPending
+ " active=" + jobActive + " userRunning=" + userRunning);
+ " active=" + jobActive + " userStarted=" + userStarted
+ " componentPresent=" + componentPresent);
}
return userRunning && jobReady && !jobPending && !jobActive;
return userStarted && componentPresent && jobReady && !jobPending && !jobActive;
}
/**
@@ -901,7 +924,8 @@ public class JobSchedulerService extends com.android.server.SystemService
final IPackageManager pm = AppGlobals.getPackageManager();
final ComponentName service = job.getService();
try {
ServiceInfo si = pm.getServiceInfo(service, 0, UserHandle.getUserId(uid));
ServiceInfo si = pm.getServiceInfo(service, PackageManager.MATCH_ENCRYPTION_DEFAULT,
UserHandle.getUserId(uid));
if (si == null) {
throw new IllegalArgumentException("No such service " + service);
}
@@ -1014,16 +1038,12 @@ public class JobSchedulerService extends com.android.server.SystemService
Binder.restoreCallingIdentity(identityToken);
}
}
};
}
void dumpInternal(PrintWriter pw) {
final long now = SystemClock.elapsedRealtime();
synchronized (mJobs) {
pw.print("Started users: ");
for (int i=0; i<mStartedUsers.size(); i++) {
pw.print("u" + mStartedUsers.get(i) + " ");
}
pw.println();
pw.println("Started users: " + Arrays.toString(mStartedUsers));
pw.println("Registered jobs:");
if (mJobs.size() > 0) {
ArraySet<JobStatus> jobs = mJobs.getJobs();

View File

@@ -3227,7 +3227,7 @@ public class PackageManagerService extends IPackageManager.Stub {
PackageParser.Activity a = mActivities.mActivities.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
if (a != null && mSettings.isEnabledAndVisibleLPr(a.info, flags, userId)) {
if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
@@ -3272,7 +3272,7 @@ public class PackageManagerService extends IPackageManager.Stub {
PackageParser.Activity a = mReceivers.mActivities.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getReceiverInfo " + component + ": " + a);
if (a != null && mSettings.isEnabledAndVisibleLPr(a.info, flags, userId)) {
if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
@@ -3291,7 +3291,7 @@ public class PackageManagerService extends IPackageManager.Stub {
PackageParser.Service s = mServices.mServices.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getServiceInfo " + component + ": " + s);
if (s != null && mSettings.isEnabledAndVisibleLPr(s.info, flags, userId)) {
if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
@@ -3310,7 +3310,7 @@ public class PackageManagerService extends IPackageManager.Stub {
PackageParser.Provider p = mProviders.mProviders.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getProviderInfo " + component + ": " + p);
if (p != null && mSettings.isEnabledAndVisibleLPr(p.info, flags, userId)) {
if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
@@ -5751,7 +5751,6 @@ public class PackageManagerService extends IPackageManager.Stub {
public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
String[] permissions, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
flags = augmentFlagsForUser(flags, userId, null);
final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
// writer
@@ -5779,7 +5778,6 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
flags = augmentFlagsForUser(flags, userId, null);
final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
// writer
@@ -5930,7 +5928,7 @@ public class PackageManagerService extends IPackageManager.Stub {
? mSettings.mPackages.get(provider.owner.packageName)
: null;
return ps != null
&& mSettings.isEnabledAndVisibleLPr(provider.info, flags, userId)
&& mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)
&& (!mSafeMode || (provider.info.applicationInfo.flags
&ApplicationInfo.FLAG_SYSTEM) != 0)
? PackageParser.generateProviderInfo(provider, flags,
@@ -5987,7 +5985,7 @@ public class PackageManagerService extends IPackageManager.Stub {
&& (processName == null
|| (p.info.processName.equals(processName)
&& UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
&& mSettings.isEnabledAndVisibleLPr(p.info, flags, userId)
&& mSettings.isEnabledAndMatchLPr(p.info, flags, userId)
&& (!mSafeMode
|| (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
if (finalList == null) {
@@ -9253,7 +9251,7 @@ public class PackageManagerService extends IPackageManager.Stub {
protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
int match, int userId) {
if (!sUserManager.exists(userId)) return null;
if (!mSettings.isEnabledAndVisibleLPr(info.activity.info, mFlags, userId)) {
if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
return null;
}
final PackageParser.Activity activity = info.activity;
@@ -9477,7 +9475,7 @@ public class PackageManagerService extends IPackageManager.Stub {
int match, int userId) {
if (!sUserManager.exists(userId)) return null;
final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
if (!mSettings.isEnabledAndVisibleLPr(info.service.info, mFlags, userId)) {
if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
return null;
}
final PackageParser.Service service = info.service;
@@ -9700,7 +9698,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (!sUserManager.exists(userId))
return null;
final PackageParser.ProviderIntentInfo info = filter;
if (!mSettings.isEnabledAndVisibleLPr(info.provider.info, mFlags, userId)) {
if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
return null;
}
final PackageParser.Provider provider = info.provider;

View File

@@ -3790,17 +3790,16 @@ final class Settings {
return cmp != null ? Arrays.toString(cmp.toArray()) : "[]";
}
boolean isEnabledAndVisibleLPr(ComponentInfo componentInfo, int flags, int userId) {
boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, int flags, int userId) {
return isEnabledLPr(componentInfo, flags, userId)
&& isVisibleLPr(componentInfo, flags);
&& isMatchLPr(componentInfo, flags);
}
private boolean isEnabledLPr(ComponentInfo componentInfo, int flags, int userId) {
if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
return true;
}
final String pkgName = componentInfo.packageName;
final PackageSetting packageSettings = mPackages.get(pkgName);
final PackageSetting packageSettings = mPackages.get(componentInfo.packageName);
if (PackageManagerService.DEBUG_SETTINGS) {
Log.v(PackageManagerService.TAG, "isEnabledLock - packageName = "
+ componentInfo.packageName + " componentName = " + componentInfo.name);
@@ -3836,12 +3835,19 @@ final class Settings {
return componentInfo.enabled;
}
private boolean isVisibleLPr(ComponentInfo componentInfo, int flags) {
final boolean matchUnaware = ((flags & PackageManager.MATCH_ENCRYPTION_UNAWARE_ONLY) != 0)
private boolean isMatchLPr(ComponentInfo componentInfo, int flags) {
if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
final PackageSetting ps = mPackages.get(componentInfo.packageName);
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
return false;
}
}
final boolean matchesUnaware = ((flags & PackageManager.MATCH_ENCRYPTION_UNAWARE_ONLY) != 0)
&& !componentInfo.encryptionAware;
final boolean matchAware = ((flags & PackageManager.MATCH_ENCRYPTION_AWARE_ONLY) != 0)
final boolean matchesAware = ((flags & PackageManager.MATCH_ENCRYPTION_AWARE_ONLY) != 0)
&& componentInfo.encryptionAware;
return matchUnaware || matchAware;
return matchesUnaware || matchesAware;
}
String getInstallerPackageNameLPr(String packageName) {

View File

@@ -126,6 +126,7 @@ public class KeyguardServiceDelegate {
final ComponentName keyguardComponent = ComponentName.unflattenFromString(
resources.getString(com.android.internal.R.string.config_keyguardComponent));
intent.addFlags(Intent.FLAG_DEBUG_ENCRYPTION_TRIAGED);
intent.setComponent(keyguardComponent);
if (!context.bindServiceAsUser(intent, mKeyguardConnection,