Loading services/backup/backuplib/java/com/android/server/backup/TransportManager.java +52 −2 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.server.backup; package com.android.server.backup; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; import android.annotation.Nullable; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.annotation.UserIdInt; import android.annotation.WorkerThread; import android.annotation.WorkerThread; Loading @@ -28,7 +31,6 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo; import android.os.Binder; import android.os.Bundle; import android.os.Bundle; import android.os.RemoteException; import android.os.RemoteException; import android.util.ArrayMap; import android.util.ArrayMap; Loading @@ -42,8 +44,8 @@ import com.android.internal.util.Preconditions; import com.android.server.backup.transport.BackupTransportClient; import com.android.server.backup.transport.BackupTransportClient; import com.android.server.backup.transport.OnTransportRegisteredListener; import com.android.server.backup.transport.OnTransportRegisteredListener; import com.android.server.backup.transport.TransportConnection; import com.android.server.backup.transport.TransportConnection; import com.android.server.backup.transport.TransportConnectionManager; import com.android.server.backup.transport.TransportConnectionListener; import com.android.server.backup.transport.TransportConnectionListener; import com.android.server.backup.transport.TransportConnectionManager; import com.android.server.backup.transport.TransportNotAvailableException; import com.android.server.backup.transport.TransportNotAvailableException; import com.android.server.backup.transport.TransportNotRegisteredException; import com.android.server.backup.transport.TransportNotRegisteredException; import com.android.server.backup.transport.TransportStats; import com.android.server.backup.transport.TransportStats; Loading @@ -58,6 +60,7 @@ import java.util.function.Predicate; /** Handles in-memory bookkeeping of all BackupTransport objects. */ /** Handles in-memory bookkeeping of all BackupTransport objects. */ public class TransportManager { public class TransportManager { private static final String TAG = "BackupTransportManager"; private static final String TAG = "BackupTransportManager"; private static final boolean MORE_DEBUG = false; @VisibleForTesting @VisibleForTesting public static final String SERVICE_ACTION_TRANSPORT_HOST = "android.backup.TRANSPORT_HOST"; public static final String SERVICE_ACTION_TRANSPORT_HOST = "android.backup.TRANSPORT_HOST"; Loading Loading @@ -130,14 +133,61 @@ public class TransportManager { } } } } void onPackageEnabled(String packageName) { onPackageAdded(packageName); } void onPackageDisabled(String packageName) { onPackageRemoved(packageName); } @WorkerThread @WorkerThread void onPackageChanged(String packageName, String... components) { void onPackageChanged(String packageName, String... components) { // Determine if the overall package has changed and not just its // components - see {@link EXTRA_CHANGED_COMPONENT_NAME_LIST}. When we // know a package was enabled/disabled we'll handle that directly and // not continue with onPackageChanged. if (components.length == 1 && components[0].equals(packageName)) { int enabled; try { enabled = mPackageManager.getApplicationEnabledSetting(packageName); } catch (IllegalArgumentException ex) { // packageName doesn't exist: likely due to a race with it being uninstalled. if (MORE_DEBUG) { Slog.d(TAG, "Package " + packageName + " was changed, but no longer exists."); } return; } switch (enabled) { case COMPONENT_ENABLED_STATE_ENABLED: { if (MORE_DEBUG) { Slog.d(TAG, "Package " + packageName + " was enabled."); } onPackageEnabled(packageName); return; } case COMPONENT_ENABLED_STATE_DISABLED: { if (MORE_DEBUG) { Slog.d(TAG, "Package " + packageName + " was disabled."); } onPackageDisabled(packageName); return; } default: { Slog.w(TAG, "Package " + packageName + " enabled setting: " + enabled); return; } } } // Unfortunately this can't be atomic because we risk a deadlock if // Unfortunately this can't be atomic because we risk a deadlock if // registerTransportsFromPackage() is put inside the synchronized block // registerTransportsFromPackage() is put inside the synchronized block Set<ComponentName> transportComponents = new ArraySet<>(components.length); Set<ComponentName> transportComponents = new ArraySet<>(components.length); for (String componentName : components) { for (String componentName : components) { transportComponents.add(new ComponentName(packageName, componentName)); transportComponents.add(new ComponentName(packageName, componentName)); } } if (transportComponents.isEmpty()) { return; } synchronized (mTransportLock) { synchronized (mTransportLock) { mRegisteredTransportsDescriptionMap.keySet().removeIf(transportComponents::contains); mRegisteredTransportsDescriptionMap.keySet().removeIf(transportComponents::contains); } } Loading services/robotests/backup/src/com/android/server/backup/TransportManagerTest.java +84 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,10 @@ package com.android.server.backup; package com.android.server.backup; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; import static com.android.server.backup.testing.TransportData.genericTransport; import static com.android.server.backup.testing.TransportData.genericTransport; import static com.android.server.backup.testing.TransportTestUtils.mockTransport; import static com.android.server.backup.testing.TransportTestUtils.mockTransport; import static com.android.server.backup.testing.TransportTestUtils.setUpTransportsForTransportManager; import static com.android.server.backup.testing.TransportTestUtils.setUpTransportsForTransportManager; Loading Loading @@ -311,6 +315,86 @@ public class TransportManagerTest { .onTransportRegistered(mTransportA2.transportName, mTransportA2.transportDirName); .onTransportRegistered(mTransportA2.transportName, mTransportA2.transportDirName); } } @Test public void testOnPackageChanged_whenPackageChanged_packageDisabledUnregistersTransport() throws Exception { TransportManager transportManager = createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1); reset(mListener); mContext.getPackageManager() .setApplicationEnabledSetting( PACKAGE_A, Integer.valueOf(COMPONENT_ENABLED_STATE_DISABLED), 0 /*flags*/); transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A); assertRegisteredTransports(transportManager, singletonList(mTransportB1)); verify(mListener, never()).onTransportRegistered(any(), any()); } @Test public void testOnPackageChanged_whenPackageChanged_packageEnabledRegistersTransport() throws Exception { TransportManager transportManager = createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1); reset(mListener); mContext.getPackageManager() .setApplicationEnabledSetting( PACKAGE_A, Integer.valueOf(COMPONENT_ENABLED_STATE_DISABLED), 0 /*flags*/); transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A); assertRegisteredTransports(transportManager, singletonList(mTransportB1)); verify(mListener, never()).onTransportRegistered(any(), any()); mContext.getPackageManager() .setApplicationEnabledSetting( PACKAGE_A, Integer.valueOf(COMPONENT_ENABLED_STATE_ENABLED), 0 /*flags*/); transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A); assertRegisteredTransports(transportManager, asList(mTransportA1, mTransportB1)); verify(mListener) .onTransportRegistered(mTransportA1.transportName, mTransportA1.transportDirName); } @Test public void testOnPackageChanged_whenPackageChanged_unknownComponentStateIsIgnored() throws Exception { TransportManager transportManager = createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1); reset(mListener); mContext.getPackageManager() .setApplicationEnabledSetting( PACKAGE_A, Integer.valueOf(COMPONENT_ENABLED_STATE_DEFAULT), 0 /*flags*/); transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A); assertRegisteredTransports(transportManager, asList(mTransportA1, mTransportB1)); verify(mListener, never()).onTransportRegistered(any(), any()); } @Test public void testOnPackageChanged_whenPackageChanged_unknownPackageExceptionIsIgnored() throws Exception { TransportManager transportManager = createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1); reset(mListener); // empty packageName triggers Robolectric ApplicationPackageManager to throw // exception as if package does not exist. transportManager.onPackageChanged("", ""); assertRegisteredTransports(transportManager, asList(mTransportA1, mTransportB1)); verify(mListener, never()).onTransportRegistered(any(), any()); } @Test @Test public void testRegisterAndSelectTransport_whenTransportRegistered() throws Exception { public void testRegisterAndSelectTransport_whenTransportRegistered() throws Exception { TransportManager transportManager = TransportManager transportManager = Loading services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java +20 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.testing.shadows; package com.android.server.testing.shadows; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; import static android.content.pm.PackageManager.NameNotFoundException; import static android.content.pm.PackageManager.NameNotFoundException; import android.app.ApplicationPackageManager; import android.app.ApplicationPackageManager; Loading Loading @@ -44,6 +45,7 @@ public class ShadowApplicationPackageManager private static final List<PackageInfo> sInstalledPackages = new ArrayList<>(); private static final List<PackageInfo> sInstalledPackages = new ArrayList<>(); private static final Map<String, Integer> sPackageUids = new ArrayMap<>(); private static final Map<String, Integer> sPackageUids = new ArrayMap<>(); private static final Map<Integer, Map<String, Integer>> sUserPackageUids = new ArrayMap<>(); private static final Map<Integer, Map<String, Integer>> sUserPackageUids = new ArrayMap<>(); private static final Map<String, Integer> sPackageAppEnabledStates = new ArrayMap<>(); /** /** * Registers the package {@code packageName} to be returned when invoking {@link * Registers the package {@code packageName} to be returned when invoking {@link Loading @@ -53,6 +55,7 @@ public class ShadowApplicationPackageManager public static void addInstalledPackage(String packageName, PackageInfo packageInfo) { public static void addInstalledPackage(String packageName, PackageInfo packageInfo) { sPackageInfos.put(packageName, packageInfo); sPackageInfos.put(packageName, packageInfo); sInstalledPackages.add(packageInfo); sInstalledPackages.add(packageInfo); sPackageAppEnabledStates.put(packageName, Integer.valueOf(COMPONENT_ENABLED_STATE_DEFAULT)); } } /** /** Loading @@ -76,6 +79,22 @@ public class ShadowApplicationPackageManager sUserPackageUids.put(userId, userPackageUids); 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 @Override protected PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId) protected PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId) throws NameNotFoundException { throws NameNotFoundException { Loading Loading @@ -115,6 +134,7 @@ public class ShadowApplicationPackageManager public static void reset() { public static void reset() { sPackageInfos.clear(); sPackageInfos.clear(); sInstalledPackages.clear(); sInstalledPackages.clear(); sPackageAppEnabledStates.clear(); org.robolectric.shadows.ShadowApplicationPackageManager.reset(); org.robolectric.shadows.ShadowApplicationPackageManager.reset(); } } } } Loading
services/backup/backuplib/java/com/android/server/backup/TransportManager.java +52 −2 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.server.backup; package com.android.server.backup; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; import android.annotation.Nullable; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.annotation.UserIdInt; import android.annotation.WorkerThread; import android.annotation.WorkerThread; Loading @@ -28,7 +31,6 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo; import android.os.Binder; import android.os.Bundle; import android.os.Bundle; import android.os.RemoteException; import android.os.RemoteException; import android.util.ArrayMap; import android.util.ArrayMap; Loading @@ -42,8 +44,8 @@ import com.android.internal.util.Preconditions; import com.android.server.backup.transport.BackupTransportClient; import com.android.server.backup.transport.BackupTransportClient; import com.android.server.backup.transport.OnTransportRegisteredListener; import com.android.server.backup.transport.OnTransportRegisteredListener; import com.android.server.backup.transport.TransportConnection; import com.android.server.backup.transport.TransportConnection; import com.android.server.backup.transport.TransportConnectionManager; import com.android.server.backup.transport.TransportConnectionListener; import com.android.server.backup.transport.TransportConnectionListener; import com.android.server.backup.transport.TransportConnectionManager; import com.android.server.backup.transport.TransportNotAvailableException; import com.android.server.backup.transport.TransportNotAvailableException; import com.android.server.backup.transport.TransportNotRegisteredException; import com.android.server.backup.transport.TransportNotRegisteredException; import com.android.server.backup.transport.TransportStats; import com.android.server.backup.transport.TransportStats; Loading @@ -58,6 +60,7 @@ import java.util.function.Predicate; /** Handles in-memory bookkeeping of all BackupTransport objects. */ /** Handles in-memory bookkeeping of all BackupTransport objects. */ public class TransportManager { public class TransportManager { private static final String TAG = "BackupTransportManager"; private static final String TAG = "BackupTransportManager"; private static final boolean MORE_DEBUG = false; @VisibleForTesting @VisibleForTesting public static final String SERVICE_ACTION_TRANSPORT_HOST = "android.backup.TRANSPORT_HOST"; public static final String SERVICE_ACTION_TRANSPORT_HOST = "android.backup.TRANSPORT_HOST"; Loading Loading @@ -130,14 +133,61 @@ public class TransportManager { } } } } void onPackageEnabled(String packageName) { onPackageAdded(packageName); } void onPackageDisabled(String packageName) { onPackageRemoved(packageName); } @WorkerThread @WorkerThread void onPackageChanged(String packageName, String... components) { void onPackageChanged(String packageName, String... components) { // Determine if the overall package has changed and not just its // components - see {@link EXTRA_CHANGED_COMPONENT_NAME_LIST}. When we // know a package was enabled/disabled we'll handle that directly and // not continue with onPackageChanged. if (components.length == 1 && components[0].equals(packageName)) { int enabled; try { enabled = mPackageManager.getApplicationEnabledSetting(packageName); } catch (IllegalArgumentException ex) { // packageName doesn't exist: likely due to a race with it being uninstalled. if (MORE_DEBUG) { Slog.d(TAG, "Package " + packageName + " was changed, but no longer exists."); } return; } switch (enabled) { case COMPONENT_ENABLED_STATE_ENABLED: { if (MORE_DEBUG) { Slog.d(TAG, "Package " + packageName + " was enabled."); } onPackageEnabled(packageName); return; } case COMPONENT_ENABLED_STATE_DISABLED: { if (MORE_DEBUG) { Slog.d(TAG, "Package " + packageName + " was disabled."); } onPackageDisabled(packageName); return; } default: { Slog.w(TAG, "Package " + packageName + " enabled setting: " + enabled); return; } } } // Unfortunately this can't be atomic because we risk a deadlock if // Unfortunately this can't be atomic because we risk a deadlock if // registerTransportsFromPackage() is put inside the synchronized block // registerTransportsFromPackage() is put inside the synchronized block Set<ComponentName> transportComponents = new ArraySet<>(components.length); Set<ComponentName> transportComponents = new ArraySet<>(components.length); for (String componentName : components) { for (String componentName : components) { transportComponents.add(new ComponentName(packageName, componentName)); transportComponents.add(new ComponentName(packageName, componentName)); } } if (transportComponents.isEmpty()) { return; } synchronized (mTransportLock) { synchronized (mTransportLock) { mRegisteredTransportsDescriptionMap.keySet().removeIf(transportComponents::contains); mRegisteredTransportsDescriptionMap.keySet().removeIf(transportComponents::contains); } } Loading
services/robotests/backup/src/com/android/server/backup/TransportManagerTest.java +84 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,10 @@ package com.android.server.backup; package com.android.server.backup; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; import static com.android.server.backup.testing.TransportData.genericTransport; import static com.android.server.backup.testing.TransportData.genericTransport; import static com.android.server.backup.testing.TransportTestUtils.mockTransport; import static com.android.server.backup.testing.TransportTestUtils.mockTransport; import static com.android.server.backup.testing.TransportTestUtils.setUpTransportsForTransportManager; import static com.android.server.backup.testing.TransportTestUtils.setUpTransportsForTransportManager; Loading Loading @@ -311,6 +315,86 @@ public class TransportManagerTest { .onTransportRegistered(mTransportA2.transportName, mTransportA2.transportDirName); .onTransportRegistered(mTransportA2.transportName, mTransportA2.transportDirName); } } @Test public void testOnPackageChanged_whenPackageChanged_packageDisabledUnregistersTransport() throws Exception { TransportManager transportManager = createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1); reset(mListener); mContext.getPackageManager() .setApplicationEnabledSetting( PACKAGE_A, Integer.valueOf(COMPONENT_ENABLED_STATE_DISABLED), 0 /*flags*/); transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A); assertRegisteredTransports(transportManager, singletonList(mTransportB1)); verify(mListener, never()).onTransportRegistered(any(), any()); } @Test public void testOnPackageChanged_whenPackageChanged_packageEnabledRegistersTransport() throws Exception { TransportManager transportManager = createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1); reset(mListener); mContext.getPackageManager() .setApplicationEnabledSetting( PACKAGE_A, Integer.valueOf(COMPONENT_ENABLED_STATE_DISABLED), 0 /*flags*/); transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A); assertRegisteredTransports(transportManager, singletonList(mTransportB1)); verify(mListener, never()).onTransportRegistered(any(), any()); mContext.getPackageManager() .setApplicationEnabledSetting( PACKAGE_A, Integer.valueOf(COMPONENT_ENABLED_STATE_ENABLED), 0 /*flags*/); transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A); assertRegisteredTransports(transportManager, asList(mTransportA1, mTransportB1)); verify(mListener) .onTransportRegistered(mTransportA1.transportName, mTransportA1.transportDirName); } @Test public void testOnPackageChanged_whenPackageChanged_unknownComponentStateIsIgnored() throws Exception { TransportManager transportManager = createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1); reset(mListener); mContext.getPackageManager() .setApplicationEnabledSetting( PACKAGE_A, Integer.valueOf(COMPONENT_ENABLED_STATE_DEFAULT), 0 /*flags*/); transportManager.onPackageChanged(PACKAGE_A, PACKAGE_A); assertRegisteredTransports(transportManager, asList(mTransportA1, mTransportB1)); verify(mListener, never()).onTransportRegistered(any(), any()); } @Test public void testOnPackageChanged_whenPackageChanged_unknownPackageExceptionIsIgnored() throws Exception { TransportManager transportManager = createTransportManagerWithRegisteredTransports(mTransportA1, mTransportB1); reset(mListener); // empty packageName triggers Robolectric ApplicationPackageManager to throw // exception as if package does not exist. transportManager.onPackageChanged("", ""); assertRegisteredTransports(transportManager, asList(mTransportA1, mTransportB1)); verify(mListener, never()).onTransportRegistered(any(), any()); } @Test @Test public void testRegisterAndSelectTransport_whenTransportRegistered() throws Exception { public void testRegisterAndSelectTransport_whenTransportRegistered() throws Exception { TransportManager transportManager = TransportManager transportManager = Loading
services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java +20 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.testing.shadows; package com.android.server.testing.shadows; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; import static android.content.pm.PackageManager.NameNotFoundException; import static android.content.pm.PackageManager.NameNotFoundException; import android.app.ApplicationPackageManager; import android.app.ApplicationPackageManager; Loading Loading @@ -44,6 +45,7 @@ public class ShadowApplicationPackageManager private static final List<PackageInfo> sInstalledPackages = new ArrayList<>(); private static final List<PackageInfo> sInstalledPackages = new ArrayList<>(); private static final Map<String, Integer> sPackageUids = new ArrayMap<>(); private static final Map<String, Integer> sPackageUids = new ArrayMap<>(); private static final Map<Integer, Map<String, Integer>> sUserPackageUids = new ArrayMap<>(); private static final Map<Integer, Map<String, Integer>> sUserPackageUids = new ArrayMap<>(); private static final Map<String, Integer> sPackageAppEnabledStates = new ArrayMap<>(); /** /** * Registers the package {@code packageName} to be returned when invoking {@link * Registers the package {@code packageName} to be returned when invoking {@link Loading @@ -53,6 +55,7 @@ public class ShadowApplicationPackageManager public static void addInstalledPackage(String packageName, PackageInfo packageInfo) { public static void addInstalledPackage(String packageName, PackageInfo packageInfo) { sPackageInfos.put(packageName, packageInfo); sPackageInfos.put(packageName, packageInfo); sInstalledPackages.add(packageInfo); sInstalledPackages.add(packageInfo); sPackageAppEnabledStates.put(packageName, Integer.valueOf(COMPONENT_ENABLED_STATE_DEFAULT)); } } /** /** Loading @@ -76,6 +79,22 @@ public class ShadowApplicationPackageManager sUserPackageUids.put(userId, userPackageUids); 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 @Override protected PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId) protected PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId) throws NameNotFoundException { throws NameNotFoundException { Loading Loading @@ -115,6 +134,7 @@ public class ShadowApplicationPackageManager public static void reset() { public static void reset() { sPackageInfos.clear(); sPackageInfos.clear(); sInstalledPackages.clear(); sInstalledPackages.clear(); sPackageAppEnabledStates.clear(); org.robolectric.shadows.ShadowApplicationPackageManager.reset(); org.robolectric.shadows.ShadowApplicationPackageManager.reset(); } } } }