Listen for PACKAGE_RESET queries and events
Respond to queries for whether there is any force-stoppable state for a given package, and remove state for packages that are force-stopped. Test: LocationProviderManagerTest Change-Id: I7b4552b947b84052c1d2024eab31c9f1c811fa46
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"presubmit": [
|
||||
{
|
||||
"name": "CtsLocationFineTestCases"
|
||||
},
|
||||
{
|
||||
"name": "CtsLocationCoarseTestCases"
|
||||
},
|
||||
@@ -66,10 +69,5 @@
|
||||
],
|
||||
"file_patterns": ["ClipboardService\\.java"]
|
||||
}
|
||||
],
|
||||
"postsubmit": [
|
||||
{
|
||||
"name": "CtsLocationFineTestCases"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -115,6 +115,7 @@ import com.android.server.location.injector.Injector;
|
||||
import com.android.server.location.injector.LocationPermissionsHelper;
|
||||
import com.android.server.location.injector.LocationPowerSaveModeHelper;
|
||||
import com.android.server.location.injector.LocationUsageLogger;
|
||||
import com.android.server.location.injector.PackageResetHelper;
|
||||
import com.android.server.location.injector.ScreenInteractiveHelper;
|
||||
import com.android.server.location.injector.SettingsHelper;
|
||||
import com.android.server.location.injector.SystemAlarmHelper;
|
||||
@@ -125,6 +126,7 @@ import com.android.server.location.injector.SystemDeviceStationaryHelper;
|
||||
import com.android.server.location.injector.SystemEmergencyHelper;
|
||||
import com.android.server.location.injector.SystemLocationPermissionsHelper;
|
||||
import com.android.server.location.injector.SystemLocationPowerSaveModeHelper;
|
||||
import com.android.server.location.injector.SystemPackageResetHelper;
|
||||
import com.android.server.location.injector.SystemScreenInteractiveHelper;
|
||||
import com.android.server.location.injector.SystemSettingsHelper;
|
||||
import com.android.server.location.injector.SystemUserInfoHelper;
|
||||
@@ -1696,11 +1698,13 @@ public class LocationManagerService extends ILocationManager.Stub implements
|
||||
private final SystemDeviceStationaryHelper mDeviceStationaryHelper;
|
||||
private final SystemDeviceIdleHelper mDeviceIdleHelper;
|
||||
private final LocationUsageLogger mLocationUsageLogger;
|
||||
private final PackageResetHelper mPackageResetHelper;
|
||||
|
||||
// lazily instantiated since they may not always be used
|
||||
|
||||
@GuardedBy("this")
|
||||
private @Nullable SystemEmergencyHelper mEmergencyCallHelper;
|
||||
@Nullable
|
||||
private SystemEmergencyHelper mEmergencyCallHelper;
|
||||
|
||||
@GuardedBy("this")
|
||||
private boolean mSystemReady;
|
||||
@@ -1721,6 +1725,7 @@ public class LocationManagerService extends ILocationManager.Stub implements
|
||||
mDeviceStationaryHelper = new SystemDeviceStationaryHelper();
|
||||
mDeviceIdleHelper = new SystemDeviceIdleHelper(context);
|
||||
mLocationUsageLogger = new LocationUsageLogger();
|
||||
mPackageResetHelper = new SystemPackageResetHelper(context);
|
||||
}
|
||||
|
||||
synchronized void onSystemReady() {
|
||||
@@ -1811,5 +1816,10 @@ public class LocationManagerService extends ILocationManager.Stub implements
|
||||
public LocationUsageLogger getLocationUsageLogger() {
|
||||
return mLocationUsageLogger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PackageResetHelper getPackageResetHelper() {
|
||||
return mPackageResetHelper;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.android.server.LocalServices;
|
||||
import com.android.server.location.injector.AppForegroundHelper;
|
||||
import com.android.server.location.injector.Injector;
|
||||
import com.android.server.location.injector.LocationPermissionsHelper;
|
||||
import com.android.server.location.injector.PackageResetHelper;
|
||||
import com.android.server.location.injector.SettingsHelper;
|
||||
import com.android.server.location.injector.UserInfoHelper;
|
||||
import com.android.server.location.injector.UserInfoHelper.UserListener;
|
||||
@@ -193,6 +194,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter
|
||||
protected final LocationPermissionsHelper mLocationPermissionsHelper;
|
||||
protected final AppForegroundHelper mAppForegroundHelper;
|
||||
protected final LocationManagerInternal mLocationManagerInternal;
|
||||
private final PackageResetHelper mPackageResetHelper;
|
||||
|
||||
private final UserListener mUserChangedListener = this::onUserChanged;
|
||||
private final ProviderEnabledListener mProviderEnabledChangedListener =
|
||||
@@ -218,12 +220,25 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter
|
||||
};
|
||||
private final AppForegroundHelper.AppForegroundListener mAppForegroundChangedListener =
|
||||
this::onAppForegroundChanged;
|
||||
private final PackageResetHelper.Responder mPackageResetResponder =
|
||||
new PackageResetHelper.Responder() {
|
||||
@Override
|
||||
public void onPackageReset(String packageName) {
|
||||
GnssListenerMultiplexer.this.onPackageReset(packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResetableForPackage(String packageName) {
|
||||
return GnssListenerMultiplexer.this.isResetableForPackage(packageName);
|
||||
}
|
||||
};
|
||||
|
||||
protected GnssListenerMultiplexer(Injector injector) {
|
||||
mUserInfoHelper = injector.getUserInfoHelper();
|
||||
mSettingsHelper = injector.getSettingsHelper();
|
||||
mLocationPermissionsHelper = injector.getLocationPermissionsHelper();
|
||||
mAppForegroundHelper = injector.getAppForegroundHelper();
|
||||
mPackageResetHelper = injector.getPackageResetHelper();
|
||||
mLocationManagerInternal = Objects.requireNonNull(
|
||||
LocalServices.getService(LocationManagerInternal.class));
|
||||
}
|
||||
@@ -357,6 +372,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter
|
||||
mLocationPackageBlacklistChangedListener);
|
||||
mLocationPermissionsHelper.addListener(mLocationPermissionsListener);
|
||||
mAppForegroundHelper.addListener(mAppForegroundChangedListener);
|
||||
mPackageResetHelper.register(mPackageResetResponder);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -374,6 +390,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter
|
||||
mLocationPackageBlacklistChangedListener);
|
||||
mLocationPermissionsHelper.removeListener(mLocationPermissionsListener);
|
||||
mAppForegroundHelper.removeListener(mAppForegroundChangedListener);
|
||||
mPackageResetHelper.unregister(mPackageResetResponder);
|
||||
}
|
||||
|
||||
private void onUserChanged(int userId, int change) {
|
||||
@@ -407,6 +424,27 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter
|
||||
updateRegistrations(registration -> registration.onForegroundChanged(uid, foreground));
|
||||
}
|
||||
|
||||
private void onPackageReset(String packageName) {
|
||||
// invoked when a package is "force quit" - move off the main thread
|
||||
FgThread.getExecutor().execute(
|
||||
() ->
|
||||
updateRegistrations(
|
||||
registration -> {
|
||||
if (registration.getIdentity().getPackageName().equals(
|
||||
packageName)) {
|
||||
registration.remove();
|
||||
}
|
||||
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
|
||||
private boolean isResetableForPackage(String packageName) {
|
||||
// invoked to find out if the given package has any state that can be "force quit"
|
||||
return findRegistration(
|
||||
registration -> registration.getIdentity().getPackageName().equals(packageName));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getServiceState() {
|
||||
if (!isSupported()) {
|
||||
|
||||
@@ -63,4 +63,7 @@ public interface Injector {
|
||||
|
||||
/** Returns a LocationUsageLogger. */
|
||||
LocationUsageLogger getLocationUsageLogger();
|
||||
|
||||
/** Returns a PackageResetHelper. */
|
||||
PackageResetHelper getPackageResetHelper();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.location.injector;
|
||||
|
||||
import static com.android.server.location.LocationManagerService.D;
|
||||
import static com.android.server.location.LocationManagerService.TAG;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/** Helpers for tracking queries and resets of package state. */
|
||||
public abstract class PackageResetHelper {
|
||||
|
||||
/** Interface for responding to reset events. */
|
||||
public interface Responder {
|
||||
|
||||
/**
|
||||
* Called when a package's runtime state is being reset for whatever reason and any
|
||||
* components carrying runtime state on behalf of the package should clear that state.
|
||||
*
|
||||
* @param packageName The name of the package.
|
||||
*/
|
||||
void onPackageReset(String packageName);
|
||||
|
||||
/**
|
||||
* Called when the system queries whether this package has any active state for the given
|
||||
* package. Should return true if the component has some runtime state that is resetable of
|
||||
* behalf of the given package, and false otherwise.
|
||||
*
|
||||
* @param packageName The name of the package.
|
||||
* @return True if this component has resetable state for the given package.
|
||||
*/
|
||||
boolean isResetableForPackage(String packageName);
|
||||
}
|
||||
|
||||
private final CopyOnWriteArrayList<Responder> mResponders;
|
||||
|
||||
public PackageResetHelper() {
|
||||
mResponders = new CopyOnWriteArrayList<>();
|
||||
}
|
||||
|
||||
/** Begin listening for package reset events. */
|
||||
public synchronized void register(Responder responder) {
|
||||
boolean empty = mResponders.isEmpty();
|
||||
mResponders.add(responder);
|
||||
if (empty) {
|
||||
onRegister();
|
||||
}
|
||||
}
|
||||
|
||||
/** Stop listening for package reset events. */
|
||||
public synchronized void unregister(Responder responder) {
|
||||
mResponders.remove(responder);
|
||||
if (mResponders.isEmpty()) {
|
||||
onUnregister();
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("this")
|
||||
protected abstract void onRegister();
|
||||
|
||||
@GuardedBy("this")
|
||||
protected abstract void onUnregister();
|
||||
|
||||
protected final void notifyPackageReset(String packageName) {
|
||||
if (D) {
|
||||
Log.d(TAG, "package " + packageName + " reset");
|
||||
}
|
||||
|
||||
for (Responder responder : mResponders) {
|
||||
responder.onPackageReset(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
protected final boolean queryResetableForPackage(String packageName) {
|
||||
for (Responder responder : mResponders) {
|
||||
if (responder.isResetableForPackage(packageName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.location.injector;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
/** Listens to appropriate broadcasts for queries and resets. */
|
||||
public class SystemPackageResetHelper extends PackageResetHelper {
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
@Nullable
|
||||
private BroadcastReceiver mReceiver;
|
||||
|
||||
public SystemPackageResetHelper(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRegister() {
|
||||
Preconditions.checkState(mReceiver == null);
|
||||
mReceiver = new Receiver();
|
||||
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
|
||||
filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
|
||||
filter.addDataScheme("package");
|
||||
|
||||
// We don't filter for Intent.ACTION_PACKAGE_DATA_CLEARED as 1) it refers to persistent
|
||||
// data, and 2) it should always be preceded by Intent.ACTION_PACKAGE_RESTARTED, which
|
||||
// refers to runtime data. in this way we also avoid redundant callbacks.
|
||||
|
||||
mContext.registerReceiver(mReceiver, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUnregister() {
|
||||
Preconditions.checkState(mReceiver != null);
|
||||
mContext.unregisterReceiver(mReceiver);
|
||||
mReceiver = null;
|
||||
}
|
||||
|
||||
private class Receiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (action == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Uri data = intent.getData();
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String packageName = data.getSchemeSpecificPart();
|
||||
if (packageName == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case Intent.ACTION_QUERY_PACKAGE_RESTART:
|
||||
String[] packages = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
|
||||
if (packages != null) {
|
||||
// it would be more efficient to pass through the whole array, but at the
|
||||
// moment the array is always size 1, and this makes for a nicer callback.
|
||||
for (String pkg : packages) {
|
||||
if (queryResetableForPackage(pkg)) {
|
||||
setResultCode(Activity.RESULT_OK);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Intent.ACTION_PACKAGE_CHANGED:
|
||||
// make sure this is an enabled/disabled change to the package as a whole, not
|
||||
// just some of its components. This avoids unnecessary work in the callback.
|
||||
boolean isPackageChange = false;
|
||||
String[] components = intent.getStringArrayExtra(
|
||||
Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
|
||||
if (components != null) {
|
||||
for (String component : components) {
|
||||
if (packageName.equals(component)) {
|
||||
isPackageChange = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isPackageChange) {
|
||||
try {
|
||||
ApplicationInfo appInfo =
|
||||
context.getPackageManager().getApplicationInfo(packageName,
|
||||
PackageManager.ApplicationInfoFlags.of(0));
|
||||
if (!appInfo.enabled) {
|
||||
notifyPackageReset(packageName);
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Intent.ACTION_PACKAGE_REMOVED:
|
||||
// fall through
|
||||
case Intent.ACTION_PACKAGE_RESTARTED:
|
||||
notifyPackageReset(packageName);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,6 +106,7 @@ import com.android.server.location.injector.LocationPermissionsHelper.LocationPe
|
||||
import com.android.server.location.injector.LocationPowerSaveModeHelper;
|
||||
import com.android.server.location.injector.LocationPowerSaveModeHelper.LocationPowerSaveModeChangedListener;
|
||||
import com.android.server.location.injector.LocationUsageLogger;
|
||||
import com.android.server.location.injector.PackageResetHelper;
|
||||
import com.android.server.location.injector.ScreenInteractiveHelper;
|
||||
import com.android.server.location.injector.ScreenInteractiveHelper.ScreenInteractiveChangedListener;
|
||||
import com.android.server.location.injector.SettingsHelper;
|
||||
@@ -1373,6 +1374,7 @@ public class LocationProviderManager extends
|
||||
protected final ScreenInteractiveHelper mScreenInteractiveHelper;
|
||||
protected final LocationUsageLogger mLocationUsageLogger;
|
||||
protected final LocationFudger mLocationFudger;
|
||||
private final PackageResetHelper mPackageResetHelper;
|
||||
|
||||
private final UserListener mUserChangedListener = this::onUserChanged;
|
||||
private final LocationSettings.LocationUserSettingsListener mLocationUserSettingsListener =
|
||||
@@ -1407,6 +1409,18 @@ public class LocationProviderManager extends
|
||||
this::onLocationPowerSaveModeChanged;
|
||||
private final ScreenInteractiveChangedListener mScreenInteractiveChangedListener =
|
||||
this::onScreenInteractiveChanged;
|
||||
private final PackageResetHelper.Responder mPackageResetResponder =
|
||||
new PackageResetHelper.Responder() {
|
||||
@Override
|
||||
public void onPackageReset(String packageName) {
|
||||
LocationProviderManager.this.onPackageReset(packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResetableForPackage(String packageName) {
|
||||
return LocationProviderManager.this.isResetableForPackage(packageName);
|
||||
}
|
||||
};
|
||||
|
||||
// acquiring mMultiplexerLock makes operations on mProvider atomic, but is otherwise unnecessary
|
||||
protected final MockableLocationProvider mProvider;
|
||||
@@ -1442,6 +1456,7 @@ public class LocationProviderManager extends
|
||||
mScreenInteractiveHelper = injector.getScreenInteractiveHelper();
|
||||
mLocationUsageLogger = injector.getLocationUsageLogger();
|
||||
mLocationFudger = new LocationFudger(mSettingsHelper.getCoarseLocationAccuracyM());
|
||||
mPackageResetHelper = injector.getPackageResetHelper();
|
||||
|
||||
mProvider = new MockableLocationProvider(mMultiplexerLock);
|
||||
|
||||
@@ -1970,6 +1985,7 @@ public class LocationProviderManager extends
|
||||
mAppForegroundHelper.addListener(mAppForegroundChangedListener);
|
||||
mLocationPowerSaveModeHelper.addListener(mLocationPowerSaveModeChangedListener);
|
||||
mScreenInteractiveHelper.addListener(mScreenInteractiveChangedListener);
|
||||
mPackageResetHelper.register(mPackageResetResponder);
|
||||
}
|
||||
|
||||
@GuardedBy("mMultiplexerLock")
|
||||
@@ -1988,6 +2004,7 @@ public class LocationProviderManager extends
|
||||
mAppForegroundHelper.removeListener(mAppForegroundChangedListener);
|
||||
mLocationPowerSaveModeHelper.removeListener(mLocationPowerSaveModeChangedListener);
|
||||
mScreenInteractiveHelper.removeListener(mScreenInteractiveChangedListener);
|
||||
mPackageResetHelper.unregister(mPackageResetResponder);
|
||||
}
|
||||
|
||||
@GuardedBy("mMultiplexerLock")
|
||||
@@ -2391,6 +2408,27 @@ public class LocationProviderManager extends
|
||||
updateRegistrations(registration -> registration.onLocationPermissionsChanged(uid));
|
||||
}
|
||||
|
||||
private void onPackageReset(String packageName) {
|
||||
// invoked when a package is "force quit" - move off the main thread
|
||||
FgThread.getExecutor().execute(
|
||||
() ->
|
||||
updateRegistrations(
|
||||
registration -> {
|
||||
if (registration.getIdentity().getPackageName().equals(
|
||||
packageName)) {
|
||||
registration.remove();
|
||||
}
|
||||
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
|
||||
private boolean isResetableForPackage(String packageName) {
|
||||
// invoked to find out if the given package has any state that can be "force quit"
|
||||
return findRegistration(
|
||||
registration -> registration.getIdentity().getPackageName().equals(packageName));
|
||||
}
|
||||
|
||||
@GuardedBy("mMultiplexerLock")
|
||||
@Override
|
||||
public void onStateChanged(
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.location.injector;
|
||||
|
||||
/** Version of PackageResetHelper for testing. */
|
||||
public class FakePackageResetHelper extends PackageResetHelper {
|
||||
|
||||
public FakePackageResetHelper() {}
|
||||
|
||||
@Override
|
||||
protected void onRegister() {}
|
||||
|
||||
@Override
|
||||
protected void onUnregister() {}
|
||||
|
||||
public boolean isResetableForPackage(String packageName) {
|
||||
return queryResetableForPackage(packageName);
|
||||
}
|
||||
|
||||
public void reset(String packageName) {
|
||||
notifyPackageReset(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ public class TestInjector implements Injector {
|
||||
private final FakeDeviceIdleHelper mDeviceIdleHelper;
|
||||
private final FakeEmergencyHelper mEmergencyHelper;
|
||||
private final LocationUsageLogger mLocationUsageLogger;
|
||||
private final FakePackageResetHelper mPackageResetHelper;
|
||||
|
||||
public TestInjector(Context context) {
|
||||
mUserInfoHelper = new FakeUserInfoHelper();
|
||||
@@ -50,6 +51,7 @@ public class TestInjector implements Injector {
|
||||
mDeviceIdleHelper = new FakeDeviceIdleHelper();
|
||||
mEmergencyHelper = new FakeEmergencyHelper();
|
||||
mLocationUsageLogger = new LocationUsageLogger();
|
||||
mPackageResetHelper = new FakePackageResetHelper();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -116,4 +118,9 @@ public class TestInjector implements Injector {
|
||||
public LocationUsageLogger getLocationUsageLogger() {
|
||||
return mLocationUsageLogger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FakePackageResetHelper getPackageResetHelper() {
|
||||
return mPackageResetHelper;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1218,6 +1218,44 @@ public class LocationProviderManagerTest {
|
||||
assertThat(mProvider.getRequest().isActive()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryPackageReset() {
|
||||
assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isFalse();
|
||||
|
||||
ILocationListener listener1 = createMockLocationListener();
|
||||
mManager.registerLocationRequest(new LocationRequest.Builder(0).setWorkSource(
|
||||
WORK_SOURCE).build(), IDENTITY, PERMISSION_FINE, listener1);
|
||||
assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isTrue();
|
||||
|
||||
ILocationListener listener2 = createMockLocationListener();
|
||||
mManager.registerLocationRequest(new LocationRequest.Builder(0).setWorkSource(
|
||||
WORK_SOURCE).build(), IDENTITY, PERMISSION_FINE, listener2);
|
||||
assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isTrue();
|
||||
|
||||
mManager.unregisterLocationRequest(listener1);
|
||||
assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isTrue();
|
||||
|
||||
mManager.unregisterLocationRequest(listener2);
|
||||
assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPackageReset() {
|
||||
ILocationListener listener1 = createMockLocationListener();
|
||||
mManager.registerLocationRequest(new LocationRequest.Builder(0).setWorkSource(
|
||||
WORK_SOURCE).build(), IDENTITY, PERMISSION_FINE, listener1);
|
||||
ILocationListener listener2 = createMockLocationListener();
|
||||
mManager.registerLocationRequest(new LocationRequest.Builder(0).setWorkSource(
|
||||
WORK_SOURCE).build(), IDENTITY, PERMISSION_FINE, listener2);
|
||||
|
||||
assertThat(mProvider.getRequest().isActive()).isTrue();
|
||||
assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isTrue();
|
||||
|
||||
mInjector.getPackageResetHelper().reset("mypackage");
|
||||
assertThat(mProvider.getRequest().isActive()).isFalse();
|
||||
assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isFalse();
|
||||
}
|
||||
|
||||
private ILocationListener createMockLocationListener() {
|
||||
return spy(new ILocationListener.Stub() {
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user