/* * Copyright (C) 2019 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.testing.shadows; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; import static android.content.pm.PackageManager.NameNotFoundException; import android.app.ApplicationPackageManager; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.ResolveInfo; import android.os.UserHandle; import android.util.ArrayMap; import org.robolectric.annotation.Implements; import org.robolectric.annotation.Resetter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Extends {@link org.robolectric.shadows.ShadowApplicationPackageManager} to return the correct * package in user-specific invocations. */ @Implements(value = ApplicationPackageManager.class) public class ShadowApplicationPackageManager extends org.robolectric.shadows.ShadowApplicationPackageManager { private static final Map sPackageInfos = new ArrayMap<>(); private static final List sInstalledPackages = new ArrayList<>(); private static final Map sPackageUids = new ArrayMap<>(); private static final Map> sUserPackageUids = new ArrayMap<>(); private static final Map sPackageAppEnabledStates = new ArrayMap<>(); /** * Registers the package {@code packageName} to be returned when invoking {@link * ApplicationPackageManager#getPackageInfoAsUser(String, int, int)} and {@link * ApplicationPackageManager#getInstalledPackagesAsUser(int, int)}. */ public static void addInstalledPackage(String packageName, PackageInfo packageInfo) { sPackageInfos.put(packageName, packageInfo); sInstalledPackages.add(packageInfo); sPackageAppEnabledStates.put(packageName, Integer.valueOf(COMPONENT_ENABLED_STATE_DEFAULT)); } /** * Sets the package uid {@code packageUid} for the package {@code packageName} to be returned * when invoking {@link ApplicationPackageManager#getPackageUidAsUser(String, int, int)}. */ public static void setPackageUid(String packageName, int packageUid) { sPackageUids.put(packageName, packageUid); } /** * Sets the package uid {@code packageUid} for the package {@code packageName} to be returned * when invoking {@link ApplicationPackageManager#getPackageUidAsUser(String, int, int)}. */ public static void setPackageUidAsUser(String packageName, int packageUid, int userId) { final Map userPackageUids = sUserPackageUids.containsKey(userId) ? sUserPackageUids.get(userId) : new HashMap<>(); userPackageUids.put(packageName, packageUid); sUserPackageUids.put(userId, userPackageUids); } @Override protected int getApplicationEnabledSetting(String packageName) { if (packageName.isEmpty()) { throw new IllegalArgumentException("Robo: Package '' does not exist."); } if (!sPackageAppEnabledStates.containsKey(packageName)) { return COMPONENT_ENABLED_STATE_DEFAULT; } return sPackageAppEnabledStates.get(packageName); } @Override protected void setApplicationEnabledSetting(String packageName, int newState, int flags) { sPackageAppEnabledStates.put(packageName, Integer.valueOf(newState)); // flags unused here. } @Override protected PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId) throws NameNotFoundException { if (!sPackageInfos.containsKey(packageName)) { throw new NameNotFoundException(packageName); } return sPackageInfos.get(packageName); } @Override protected List getInstalledPackagesAsUser(int flags, int userId) { return sInstalledPackages; } @Override protected int getPackageUidAsUser(String packageName, int flags, int userId) throws NameNotFoundException { if (sUserPackageUids.containsKey(userId) && sUserPackageUids.get(userId).containsKey(packageName)) { return sUserPackageUids.get(userId).get(packageName); } if (!sPackageUids.containsKey(packageName)) { throw new NameNotFoundException(packageName); } return sPackageUids.get(packageName); } @Override protected List queryBroadcastReceiversAsUser( Intent intent, int flags, UserHandle userHandle) { // Currently does not handle multi-user. return queryBroadcastReceivers(intent, flags); } /** Clear package state. */ @Resetter public static void reset() { sPackageInfos.clear(); sInstalledPackages.clear(); sPackageAppEnabledStates.clear(); org.robolectric.shadows.ShadowApplicationPackageManager.reset(); } }