blob: 9ca248b69a4db9c2b20d3c93b3fc78f907059ec0 [file] [log] [blame]
package org.robolectric.shadows;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.GET_ACTIVITIES;
import static android.content.pm.PackageManager.GET_CONFIGURATIONS;
import static android.content.pm.PackageManager.GET_GIDS;
import static android.content.pm.PackageManager.GET_INSTRUMENTATION;
import static android.content.pm.PackageManager.GET_INTENT_FILTERS;
import static android.content.pm.PackageManager.GET_META_DATA;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.GET_PROVIDERS;
import static android.content.pm.PackageManager.GET_RECEIVERS;
import static android.content.pm.PackageManager.GET_RESOLVED_FILTER;
import static android.content.pm.PackageManager.GET_SERVICES;
import static android.content.pm.PackageManager.GET_SHARED_LIBRARY_FILES;
import static android.content.pm.PackageManager.GET_SIGNATURES;
import static android.content.pm.PackageManager.GET_URI_PERMISSION_PATTERNS;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static android.content.pm.PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
import static android.content.pm.PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
import static android.content.pm.PackageManager.SIGNATURE_MATCH;
import static android.content.pm.PackageManager.SIGNATURE_NEITHER_SIGNED;
import static android.content.pm.PackageManager.SIGNATURE_NO_MATCH;
import static android.content.pm.PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
import static android.os.Build.VERSION_CODES.N;
import static java.util.Arrays.asList;
import android.Manifest;
import android.annotation.UserIdInt;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.Activity;
import android.content.pm.PackageParser.Package;
import android.content.pm.PackageParser.Service;
import android.content.pm.PackageStats;
import android.content.pm.PackageUserState;
import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.Signature;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Pair;
import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.TempDirectory;
@Implements(PackageManager.class)
public class ShadowPackageManager {
Map<String, Boolean> permissionRationaleMap = new HashMap<>();
List<FeatureInfo> systemAvailableFeatures = new ArrayList<>();
final Map<String, PackageInfo> packageInfos = new LinkedHashMap<>();
final Map<String, Package> packages = new LinkedHashMap<>();
private Map<String, PackageInfo> packageArchiveInfo = new HashMap<>();
final Map<String, PackageStats> packageStatsMap = new HashMap<>();
final Map<String, String> packageInstallerMap = new HashMap<>();
final Map<Integer, String[]> packagesForUid = new HashMap<>();
final Map<String, Integer> uidForPackage = new HashMap<>();
final Map<Integer, String> namesForUid = new HashMap<>();
final Map<Integer, Integer> verificationResults = new HashMap<>();
final Map<Integer, Long> verificationTimeoutExtension = new HashMap<>();
final Map<String, String> currentToCanonicalNames = new HashMap<>();
final Map<ComponentName, ComponentState> componentList = new LinkedHashMap<>();
final Map<ComponentName, Drawable> drawableList = new LinkedHashMap<>();
final Map<String, Drawable> applicationIcons = new HashMap<>();
final Map<String, Boolean> systemFeatureList = new LinkedHashMap<>();
final Map<IntentFilter, ComponentName> preferredActivities = new LinkedHashMap<>();
final Map<Pair<String, Integer>, Drawable> drawables = new LinkedHashMap<>();
final Map<String, Integer> applicationEnabledSettingMap = new HashMap<>();
boolean queryIntentImplicitly = false;
Map<String, PermissionInfo> extraPermissions = new HashMap<>();
public Map<String, Resources> resources = new HashMap<>();
private final Map<Intent, List<ResolveInfo>> resolveInfoForIntent = new TreeMap<>(new IntentComparator());
private Set<String> deletedPackages = new HashSet<>();
Map<String, IPackageDeleteObserver> pendingDeleteCallbacks = new HashMap<>();
// From com.android.server.pm.PackageManagerService.compareSignatures().
static int compareSignature(Signature[] signatures1, Signature[] signatures2) {
if (signatures1 == null) {
return (signatures2 == null) ? SIGNATURE_NEITHER_SIGNED
: SIGNATURE_FIRST_NOT_SIGNED;
}
if (signatures2 == null) {
return SIGNATURE_SECOND_NOT_SIGNED;
}
if (signatures1.length != signatures2.length) {
return SIGNATURE_NO_MATCH;
}
HashSet<Signature> signatures1set = new HashSet<>(asList(signatures1));
HashSet<Signature> signatures2set = new HashSet<>(asList(signatures2));
return signatures1set.equals(signatures2set) ? SIGNATURE_MATCH : SIGNATURE_NO_MATCH;
}
static String resolvePackageName(String packageName, ComponentName componentName) {
String classString = componentName.getClassName();
int index = classString.indexOf('.');
if (index == -1) {
classString = packageName + "." + classString;
} else if (index == 0) {
classString = packageName + classString;
}
return classString;
}
static ResolveInfo getResolveInfo(Activity activity, IntentFilter intentFilter) {
ResolveInfo info = new ResolveInfo();
info.isDefault = intentFilter.hasCategory("Intent.CATEGORY_DEFAULT");
info.activityInfo = new ActivityInfo();
info.activityInfo.name = activity.info.name;
info.activityInfo.packageName = activity.info.packageName;
info.activityInfo.applicationInfo = activity.info.applicationInfo;
info.activityInfo.permission = activity.info.permission;
info.filter = new IntentFilter(intentFilter);
return info;
}
static ResolveInfo getResolveInfo(Service service, IntentFilter intentFilter) {
ResolveInfo info = new ResolveInfo();
info.isDefault = intentFilter.hasCategory("Intent.CATEGORY_DEFAULT");
info.serviceInfo = new ServiceInfo();
info.serviceInfo.name = service.info.name;
info.serviceInfo.packageName = service.info.packageName;
info.serviceInfo.applicationInfo = service.info.applicationInfo;
info.serviceInfo.permission = service.info.permission;
info.filter = new IntentFilter(intentFilter);
return info;
}
private static void setUpPackageStorage(ApplicationInfo applicationInfo) {
TempDirectory tempDirectory = RuntimeEnvironment.getTempDirectory();
if (applicationInfo.sourceDir == null) {
applicationInfo.sourceDir =
tempDirectory
.createIfNotExists(applicationInfo.packageName + "-sourceDir")
.toAbsolutePath()
.toString();
}
if (applicationInfo.dataDir == null) {
applicationInfo.dataDir =
tempDirectory
.createIfNotExists(applicationInfo.packageName + "-dataDir")
.toAbsolutePath()
.toString();
}
applicationInfo.publicSourceDir = applicationInfo.sourceDir;
if (RuntimeEnvironment.getApiLevel() >= N) {
applicationInfo.credentialProtectedDataDir = tempDirectory.createIfNotExists("userDataDir").toAbsolutePath().toString();
applicationInfo.deviceProtectedDataDir = tempDirectory.createIfNotExists("deviceDataDir").toAbsolutePath().toString();
}
}
/**
* @deprecated Prefer {@link PackageManager#getPackageInfo(String, int)} instead.
*/
@Deprecated
public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException {
throw new UnsupportedOperationException("Not implemented");
}
/**
* @deprecated Prefer {@link PackageManager#getApplicationInfo(String, int)} instead.
*/
@Deprecated
public ApplicationInfo getApplicationInfo(String packageName, int flags) throws NameNotFoundException {
throw new UnsupportedOperationException("Not implemented");
}
/**
* @deprecated Prefer {@link PackageManager#getActivityInfo(ComponentName, int)} instead.
*/
@Deprecated
public ActivityInfo getActivityInfo(ComponentName className, int flags) throws NameNotFoundException {
throw new UnsupportedOperationException("Not implemented");
}
/**
* @deprecated Prefer {@link PackageManager#getReceiverInfo(ComponentName, int)} instead.
*/
@Deprecated
public ActivityInfo getReceiverInfo(ComponentName className, int flags) throws NameNotFoundException {
throw new UnsupportedOperationException("Not implemented");
}
/**
* @deprecated Prefer {@link PackageManager#getServiceInfo(ComponentName, int)} instead.
*/
@Deprecated
public ServiceInfo getServiceInfo(ComponentName className, int flags) throws NameNotFoundException {
throw new UnsupportedOperationException("Not implemented");
}
/**
* @deprecated Prefer {@link PackageManager#getInstalledPackages(int)} instead.
*/
@Deprecated
public List<PackageInfo> getInstalledPackages(int flags) {
throw new UnsupportedOperationException("Not implemented");
}
/**
* @deprecated Prefer {@link PackageManager#queryIntentActivities(Intent, int)} instead.
*/
@Deprecated
public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
throw new UnsupportedOperationException("Not implemented");
}
/**
* @deprecated Prefer {@link PackageManager#queryIntentServices(Intent, int)} instead.
*/
@Deprecated
public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
throw new UnsupportedOperationException("Not implemented");
}
/**
* @deprecated Prefer {@link PackageManager#queryBroadcastReceivers(Intent, int)} instead.
*/
@Deprecated
public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
throw new UnsupportedOperationException("Not implemented");
}
/**
* @deprecated Prefer {@link PackageManager#resolveActivity(Intent, int)} instead.
*/
@Deprecated
public ResolveInfo resolveActivity(Intent intent, int flags) {
throw new UnsupportedOperationException("Not implemented");
}
/**
* @deprecated Prefer {@link PackageManager#resolveService(Intent, int)} instead.
*/
@Deprecated
public ResolveInfo resolveService(Intent intent, int flags) {
throw new UnsupportedOperationException("Not implemented");
}
public void addResolveInfoForIntent(Intent intent, List<ResolveInfo> info) {
resolveInfoForIntent.put(intent, info);
}
public void addResolveInfoForIntent(Intent intent, ResolveInfo info) {
List<ResolveInfo> infoList = resolveInfoForIntent.get(intent);
if (infoList == null) {
infoList = new ArrayList<>();
resolveInfoForIntent.put(intent, infoList);
}
infoList.add(info);
}
public void removeResolveInfosForIntent(Intent intent, String packageName) {
List<ResolveInfo> infoList = resolveInfoForIntent.get(intent);
if (infoList == null) {
infoList = new ArrayList<>();
resolveInfoForIntent.put(intent, infoList);
}
for (Iterator<ResolveInfo> iterator = infoList.iterator(); iterator.hasNext(); ) {
ResolveInfo resolveInfo = iterator.next();
if (resolveInfo.activityInfo.packageName.equals(packageName)) {
iterator.remove();
}
}
}
public Drawable getActivityIcon(Intent intent) throws NameNotFoundException {
return drawableList.get(intent.getComponent());
}
public Drawable getActivityIcon(ComponentName componentName) throws NameNotFoundException {
return drawableList.get(componentName);
}
public void addActivityIcon(ComponentName component, Drawable drawable) {
drawableList.put(component, drawable);
}
public void addActivityIcon(Intent intent, Drawable drawable) {
drawableList.put(intent.getComponent(), drawable);
}
/**
* @deprecated Prefer {@link PackageManager#getApplicationIcon(String)} instead.
*/
@Deprecated
public Drawable getApplicationIcon(String packageName) throws NameNotFoundException {
throw new UnsupportedOperationException("Not implemented");
}
public void setApplicationIcon(String packageName, Drawable drawable) {
applicationIcons.put(packageName, drawable);
}
/**
* @deprecated Prefer {@link PackageManager#getLaunchIntentForPackage(String)} instead.
*/
@Deprecated
public Intent getLaunchIntentForPackage(String packageName) {
throw new UnsupportedOperationException("Not implemented");
}
/**
* @deprecated Prefer {@link PackageManager#getApplicationLabel(ApplicationInfo)} instead.
*/
@Deprecated
public CharSequence getApplicationLabel(ApplicationInfo info) {
throw new UnsupportedOperationException("Not implemented");
}
/**
* @deprecated Prefer {@link PackageManager#setComponentEnabledSetting(ComponentName, int, int)} instead.
*/
@Deprecated
public void setComponentEnabledSetting(ComponentName componentName, int newState, int flags) {
throw new UnsupportedOperationException("Not implemented");
}
public void setApplicationEnabledSetting(String packageName, int newState, int flags) {
applicationEnabledSettingMap.put(packageName, newState);
}
public void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity) {
preferredActivities.put(filter, activity);
}
public int getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName) {
if (outFilters == null) {
return 0;
}
Set<IntentFilter> filters = preferredActivities.keySet();
for (IntentFilter filter : outFilters) {
step:
for (IntentFilter testFilter : filters) {
ComponentName name = preferredActivities.get(testFilter);
// filter out based on the given packageName;
if (packageName != null && !name.getPackageName().equals(packageName)) {
continue step;
}
// Check actions
Iterator<String> iterator = filter.actionsIterator();
while (iterator.hasNext()) {
if (!testFilter.matchAction(iterator.next())) {
continue step;
}
}
iterator = filter.categoriesIterator();
while (iterator.hasNext()) {
if (!filter.hasCategory(iterator.next())) {
continue step;
}
}
if (outActivities == null) {
outActivities = new ArrayList<>();
}
outActivities.add(name);
}
}
return 0;
}
/**
* @deprecated Use {@link android.app.ApplicationPackageManager#getComponentEnabledSetting(ComponentName)} or
* {@link #getComponentEnabledSettingFlags(ComponentName)} instead. This method will be removed in Robolectric 3.5.
*/
@Deprecated
public ComponentState getComponentState(ComponentName componentName) {
return componentList.get(componentName);
}
/**
* Return the flags set in call to {@link android.app.ApplicationPackageManager#setComponentEnabledSetting(ComponentName, int, int)}.
*
* @param componentName The component name.
* @return The flags.
*/
public int getComponentEnabledSettingFlags(ComponentName componentName) {
ComponentState state = componentList.get(componentName);
return state != null ? state.flags : 0;
}
/** @deprecated - use {@link #addPackage(PackageInfo)} instead */
@Deprecated
public void addPackage(String packageName) {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = packageName;
ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.packageName = packageName;
setUpPackageStorage(applicationInfo);
packageInfo.applicationInfo = applicationInfo;
addPackage(packageInfo);
}
public void addPackage(PackageInfo packageInfo) {
PackageStats packageStats = new PackageStats(packageInfo.packageName);
addPackage(packageInfo, packageStats);
}
public void addPackage(PackageInfo packageInfo, PackageStats packageStats) {
Preconditions.checkArgument(packageInfo.packageName.equals(packageStats.packageName));
packageInfos.put(packageInfo.packageName, packageInfo);
packageStatsMap.put(packageInfo.packageName, packageStats);
applicationEnabledSettingMap.put(packageInfo.packageName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
if (packageInfo.applicationInfo != null) {
namesForUid.put(packageInfo.applicationInfo.uid, packageInfo.packageName);
}
}
public void addPermissionInfo(PermissionInfo permissionInfo) {
extraPermissions.put(permissionInfo.name, permissionInfo);
}
public void removePackage(String packageName) {
packages.remove(packageName);
packageInfos.remove(packageName);
}
/**
* @deprecated Prefer {@link PackageManager#hasSystemFeature(String)} instead.
*/
@Deprecated
public boolean hasSystemFeature(String name) {
throw new UnsupportedOperationException("Not implemented");
}
public void setSystemFeature(String name, boolean supported) {
systemFeatureList.put(name, supported);
}
public void addDrawableResolution(String packageName, int resourceId, Drawable drawable) {
drawables.put(new Pair(packageName, resourceId), drawable);
}
public Drawable getDrawable(String packageName, int resourceId, ApplicationInfo applicationInfo) {
return drawables.get(new Pair(packageName, resourceId));
}
/**
* @deprecated Prefer {@link PackageManager#checkPermission(String, String)} instead.
*/
@Deprecated
public int checkPermission(String permName, String pkgName) {
return 0;
}
/**
* @deprecated - this will be the default behaviour in Robolectric 3.7 and bring behaviour into line with that of
* other Android components (note this method only affects Activities)
*/
@Deprecated
public boolean isQueryIntentImplicitly() {
return queryIntentImplicitly;
}
/**
* @deprecated - this will be the default behaviour in Robolectric 3.7 and bring behaviour into line with that of
* other Android components (note this method only affects Activities)
*/
@Deprecated
public void setQueryIntentImplicitly(boolean queryIntentImplicitly) {
this.queryIntentImplicitly = queryIntentImplicitly;
}
public void setNameForUid(int uid, String name) {
namesForUid.put(uid, name);
}
public void setPackagesForCallingUid(String... packagesForCallingUid) {
packagesForUid.put(Binder.getCallingUid(), packagesForCallingUid);
for (String packageName : packagesForCallingUid) {
uidForPackage.put(packageName, Binder.getCallingUid());
}
}
public void setPackagesForUid(int uid, String... packagesForCallingUid) {
packagesForUid.put(uid, packagesForCallingUid);
for (String packageName : packagesForCallingUid) {
uidForPackage.put(packageName, uid);
}
}
public void setPackageArchiveInfo(String archiveFilePath, PackageInfo packageInfo) {
packageArchiveInfo.put(archiveFilePath, packageInfo);
}
public int getVerificationResult(int id) {
Integer result = verificationResults.get(id);
if (result == null) {
// 0 isn't a "valid" result, so we can check for the case when verification isn't
// called, if needed
return 0;
}
return result;
}
public long getVerificationExtendedTimeout(int id) {
Long result = verificationTimeoutExtension.get(id);
if (result == null) {
return 0;
}
return result;
}
public void setShouldShowRequestPermissionRationale(String permission, boolean show) {
permissionRationaleMap.put(permission, show);
}
public void addSystemAvailableFeature(FeatureInfo featureInfo) {
systemAvailableFeatures.add(featureInfo);
}
public void clearSystemAvailableFeatures() {
systemAvailableFeatures.clear();
}
public void addCurrentToCannonicalName(String currentName, String canonicalName) {
currentToCanonicalNames.put(currentName, canonicalName);
}
@Implementation
public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags, UserHandle userHandle) {
return null;
}
@Implementation
public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags, @UserIdInt int userId) {
return null;
}
@Implementation
public PackageInfo getPackageArchiveInfo(String archiveFilePath, int flags) {
List<PackageInfo> result = new ArrayList<>();
for (PackageInfo packageInfo : packageInfos.values()) {
if (applicationEnabledSettingMap.get(packageInfo.packageName)
!= COMPONENT_ENABLED_STATE_DISABLED
|| (flags & MATCH_UNINSTALLED_PACKAGES) == MATCH_UNINSTALLED_PACKAGES) {
result.add(packageInfo);
}
}
List<PackageInfo> packages = result;
for (PackageInfo aPackage : packages) {
ApplicationInfo appInfo = aPackage.applicationInfo;
if (appInfo != null && archiveFilePath.equals(appInfo.sourceDir)) {
return aPackage;
}
}
return null;
}
@Implementation
public void freeStorageAndNotify(long freeStorageSize, IPackageDataObserver observer) {
}
@Implementation
public void freeStorage(long freeStorageSize, IntentSender pi) {
}
/**
* Runs the callbacks pending from calls to {@link PackageManager#deletePackage(String, IPackageDeleteObserver, int)}
*/
public void doPendingUninstallCallbacks() {
boolean hasDeletePackagesPermission = false;
String[] requestedPermissions =
packageInfos.get(RuntimeEnvironment.application.getPackageName()).requestedPermissions;
if (requestedPermissions != null) {
for (String permission : requestedPermissions) {
if (Manifest.permission.DELETE_PACKAGES.equals(permission)) {
hasDeletePackagesPermission = true;
break;
}
}
}
for (String packageName : pendingDeleteCallbacks.keySet()) {
int resultCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
PackageInfo removed = packageInfos.get(packageName);
if (hasDeletePackagesPermission && removed != null) {
packageInfos.remove(packageName);
deletedPackages.add(packageName);
resultCode = PackageManager.DELETE_SUCCEEDED;
}
try {
pendingDeleteCallbacks.get(packageName).packageDeleted(packageName, resultCode);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
pendingDeleteCallbacks.clear();
}
/**
* Returns package names successfully deleted with {@link PackageManager#deletePackage(String, IPackageDeleteObserver, int)}
* Note that like real {@link PackageManager} the calling context must have {@link android.Manifest.permission#DELETE_PACKAGES} permission set.
*/
public Set<String> getDeletedPackages() {
return deletedPackages;
}
protected List<ResolveInfo> queryIntent(Intent intent, int flags) {
List<ResolveInfo> result = resolveInfoForIntent.get(intent);
if (result == null) {
return Collections.emptyList();
} else {
return result;
}
}
public void addPackage(Package appPackage) {
int flags =
GET_ACTIVITIES
| GET_RECEIVERS
| GET_SERVICES
| GET_PROVIDERS
| GET_INSTRUMENTATION
| GET_INTENT_FILTERS
| GET_SIGNATURES
| GET_RESOLVED_FILTER
| GET_META_DATA
| GET_GIDS
| MATCH_DISABLED_COMPONENTS
| GET_SHARED_LIBRARY_FILES
| GET_URI_PERMISSION_PATTERNS
| GET_PERMISSIONS
| MATCH_UNINSTALLED_PACKAGES
| GET_CONFIGURATIONS
| MATCH_DISABLED_UNTIL_USED_COMPONENTS
| MATCH_DIRECT_BOOT_UNAWARE
| MATCH_DIRECT_BOOT_AWARE;
packages.put(appPackage.packageName, appPackage);
PackageInfo packageInfo;
if (RuntimeEnvironment.getApiLevel() >= Build.VERSION_CODES.M) {
packageInfo =
PackageParser.generatePackageInfo(
appPackage,
new int[] {0},
flags,
0,
0,
new HashSet<String>(),
new PackageUserState());
} else if (RuntimeEnvironment.getApiLevel() >= Build.VERSION_CODES.LOLLIPOP_MR1) {
packageInfo =
ReflectionHelpers.callStaticMethod(
PackageParser.class,
"generatePackageInfo",
ReflectionHelpers.ClassParameter.from(Package.class, appPackage),
ReflectionHelpers.ClassParameter.from(int[].class, new int[] {0}),
ReflectionHelpers.ClassParameter.from(int.class, flags),
ReflectionHelpers.ClassParameter.from(long.class, 0L),
ReflectionHelpers.ClassParameter.from(long.class, 0L),
ReflectionHelpers.ClassParameter.from(ArraySet.class, new ArraySet<>()),
ReflectionHelpers.ClassParameter.from(
PackageUserState.class, new PackageUserState()));
} else if (RuntimeEnvironment.getApiLevel() >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
packageInfo =
ReflectionHelpers.callStaticMethod(
PackageParser.class,
"generatePackageInfo",
ReflectionHelpers.ClassParameter.from(Package.class, appPackage),
ReflectionHelpers.ClassParameter.from(int[].class, new int[] {0}),
ReflectionHelpers.ClassParameter.from(int.class, flags),
ReflectionHelpers.ClassParameter.from(long.class, 0L),
ReflectionHelpers.ClassParameter.from(long.class, 0L),
ReflectionHelpers.ClassParameter.from(HashSet.class, new HashSet<>()),
ReflectionHelpers.ClassParameter.from(
PackageUserState.class, new PackageUserState()));
} else {
packageInfo =
ReflectionHelpers.callStaticMethod(
PackageParser.class,
"generatePackageInfo",
ReflectionHelpers.ClassParameter.from(Package.class, appPackage),
ReflectionHelpers.ClassParameter.from(int[].class, new int[] {0}),
ReflectionHelpers.ClassParameter.from(int.class, flags),
ReflectionHelpers.ClassParameter.from(long.class, 0L),
ReflectionHelpers.ClassParameter.from(long.class, 0L),
ReflectionHelpers.ClassParameter.from(HashSet.class, new HashSet<>()));
}
packageInfo.applicationInfo.uid = Process.myUid();
addPackage(packageInfo);
}
public static class IntentComparator implements Comparator<Intent> {
@Override
public int compare(Intent i1, Intent i2) {
if (i1 == null && i2 == null) return 0;
if (i1 == null && i2 != null) return -1;
if (i1 != null && i2 == null) return 1;
if (i1.equals(i2)) return 0;
String action1 = i1.getAction();
String action2 = i2.getAction();
if (action1 == null && action2 != null) return -1;
if (action1 != null && action2 == null) return 1;
if (action1 != null && action2 != null) {
if (!action1.equals(action2)) {
return action1.compareTo(action2);
}
}
Uri data1 = i1.getData();
Uri data2 = i2.getData();
if (data1 == null && data2 != null) return -1;
if (data1 != null && data2 == null) return 1;
if (data1 != null && data2 != null) {
if (!data1.equals(data2)) {
return data1.compareTo(data2);
}
}
ComponentName component1 = i1.getComponent();
ComponentName component2 = i2.getComponent();
if (component1 == null && component2 != null) return -1;
if (component1 != null && component2 == null) return 1;
if (component1 != null && component2 != null) {
if (!component1.equals(component2)) {
return component1.compareTo(component2);
}
}
String package1 = i1.getPackage();
String package2 = i2.getPackage();
if (package1 == null && package2 != null) return -1;
if (package1 != null && package2 == null) return 1;
if (package1 != null && package2 != null) {
if (!package1.equals(package2)) {
return package1.compareTo(package2);
}
}
Set<String> categories1 = i1.getCategories();
Set<String> categories2 = i2.getCategories();
if (categories1 == null) return categories2 == null ? 0 : -1;
if (categories2 == null) return 1;
if (categories1.size() > categories2.size()) return 1;
if (categories1.size() < categories2.size()) return -1;
String[] array1 = categories1.toArray(new String[0]);
String[] array2 = categories2.toArray(new String[0]);
Arrays.sort(array1);
Arrays.sort(array2);
for (int i = 0; i < array1.length; ++i) {
int val = array1[i].compareTo(array2[i]);
if (val != 0) return val;
}
return 0;
}
}
/**
* @deprecated Use {@link android.app.ApplicationPackageManager#getComponentEnabledSetting(ComponentName)} instead. This class will be made private in Robolectric 3.5.
*/
@Deprecated
public static class ComponentState {
public int newState;
public int flags;
public ComponentState(int newState, int flags) {
this.newState = newState;
this.flags = flags;
}
}
}