Merge "Updates location services to support concurrent multi user."
This commit is contained in:
@@ -140,9 +140,7 @@ import com.android.server.location.provider.StationaryThrottlingLocationProvider
|
||||
import com.android.server.location.provider.proxy.ProxyLocationProvider;
|
||||
import com.android.server.location.settings.LocationSettings;
|
||||
import com.android.server.location.settings.LocationUserSettings;
|
||||
import com.android.server.pm.UserManagerInternal;
|
||||
import com.android.server.pm.permission.LegacyPermissionManagerInternal;
|
||||
import com.android.server.utils.Slogf;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
@@ -310,10 +308,6 @@ public class LocationManagerService extends ILocationManager.Stub implements
|
||||
permissionManagerInternal.setLocationExtraPackagesProvider(
|
||||
userId -> mContext.getResources().getStringArray(
|
||||
com.android.internal.R.array.config_locationExtraPackageNames));
|
||||
|
||||
// TODO(b/241604546): properly handle this callback
|
||||
LocalServices.getService(UserManagerInternal.class).addUserVisibilityListener(
|
||||
(u, v) -> Slogf.i(TAG, "onUserVisibilityChanged(): %d -> %b", u, v));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1702,7 +1696,7 @@ public class LocationManagerService extends ILocationManager.Stub implements
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
private final UserInfoHelper mUserInfoHelper;
|
||||
private final SystemUserInfoHelper mUserInfoHelper;
|
||||
private final LocationSettings mLocationSettings;
|
||||
private final AlarmHelper mAlarmHelper;
|
||||
private final SystemAppOpsHelper mAppOpsHelper;
|
||||
@@ -1725,7 +1719,7 @@ public class LocationManagerService extends ILocationManager.Stub implements
|
||||
@GuardedBy("this")
|
||||
private boolean mSystemReady;
|
||||
|
||||
SystemInjector(Context context, UserInfoHelper userInfoHelper) {
|
||||
SystemInjector(Context context, SystemUserInfoHelper userInfoHelper) {
|
||||
mContext = context;
|
||||
|
||||
mUserInfoHelper = userInfoHelper;
|
||||
@@ -1745,6 +1739,7 @@ public class LocationManagerService extends ILocationManager.Stub implements
|
||||
}
|
||||
|
||||
synchronized void onSystemReady() {
|
||||
mUserInfoHelper.onSystemReady();
|
||||
mAppOpsHelper.onSystemReady();
|
||||
mLocationPermissionsHelper.onSystemReady();
|
||||
mSettingsHelper.onSystemReady();
|
||||
|
||||
@@ -110,6 +110,11 @@ public class LocationEventLog extends LocalEventLog<Object> {
|
||||
addLog(new UserSwitchedEvent(userIdFrom, userIdTo));
|
||||
}
|
||||
|
||||
/** Logs a user visibility changed event. */
|
||||
public void logUserVisibilityChanged(int userId, boolean visible) {
|
||||
addLog(new UserVisibilityChangedEvent(userId, visible));
|
||||
}
|
||||
|
||||
/** Logs a location enabled/disabled event. */
|
||||
public void logLocationEnabled(int userId, boolean enabled) {
|
||||
addLog(new LocationEnabledEvent(userId, enabled));
|
||||
@@ -475,6 +480,22 @@ public class LocationEventLog extends LocalEventLog<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class UserVisibilityChangedEvent {
|
||||
|
||||
private final int mUserId;
|
||||
private final boolean mVisible;
|
||||
|
||||
UserVisibilityChangedEvent(int userId, boolean visible) {
|
||||
mUserId = userId;
|
||||
mVisible = visible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[u" + mUserId + "] " + (mVisible ? "visible" : "invisible");
|
||||
}
|
||||
}
|
||||
|
||||
private static final class LocationEnabledEvent {
|
||||
|
||||
private final int mUserId;
|
||||
|
||||
@@ -387,7 +387,7 @@ public class GeofenceManager extends
|
||||
if (!mSettingsHelper.isLocationEnabled(identity.getUserId())) {
|
||||
return false;
|
||||
}
|
||||
if (!mUserInfoHelper.isCurrentUserId(identity.getUserId())) {
|
||||
if (!mUserInfoHelper.isVisibleUserId(identity.getUserId())) {
|
||||
return false;
|
||||
}
|
||||
if (mSettingsHelper.isLocationPackageBlacklisted(identity.getUserId(),
|
||||
@@ -534,7 +534,10 @@ public class GeofenceManager extends
|
||||
}
|
||||
|
||||
void onUserChanged(int userId, int change) {
|
||||
if (change == UserListener.CURRENT_USER_CHANGED) {
|
||||
// current user changes affect whether system server location requests are allowed to access
|
||||
// location, and visibility changes affect whether any given user may access location.
|
||||
if (change == UserListener.CURRENT_USER_CHANGED
|
||||
|| change == UserListener.USER_VISIBILITY_CHANGED) {
|
||||
updateRegistrations(registration -> registration.getIdentity().getUserId() == userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,7 +317,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter
|
||||
identity.getUserId())) {
|
||||
return false;
|
||||
}
|
||||
if (!mUserInfoHelper.isCurrentUserId(identity.getUserId())) {
|
||||
if (!mUserInfoHelper.isVisibleUserId(identity.getUserId())) {
|
||||
return false;
|
||||
}
|
||||
if (mSettingsHelper.isLocationPackageBlacklisted(identity.getUserId(),
|
||||
@@ -394,7 +394,10 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter
|
||||
}
|
||||
|
||||
private void onUserChanged(int userId, int change) {
|
||||
if (change == UserListener.CURRENT_USER_CHANGED) {
|
||||
// current user changes affect whether system server location requests are allowed to access
|
||||
// location, and visibility changes affect whether any given user may access location.
|
||||
if (change == UserListener.CURRENT_USER_CHANGED
|
||||
|| change == UserListener.USER_VISIBILITY_CHANGED) {
|
||||
updateRegistrations(registration -> registration.getIdentity().getUserId() == userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,9 +33,11 @@ import android.util.IndentingPrintWriter;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.pm.UserManagerInternal;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Provides accessors and listeners for all user info.
|
||||
@@ -50,11 +52,21 @@ public class SystemUserInfoHelper extends UserInfoHelper {
|
||||
@Nullable private IActivityManager mActivityManager;
|
||||
@GuardedBy("this")
|
||||
@Nullable private UserManager mUserManager;
|
||||
@GuardedBy("this")
|
||||
@Nullable private UserManagerInternal mUserManagerInternal;
|
||||
|
||||
public SystemUserInfoHelper(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
/** The function should be called when PHASE_SYSTEM_SERVICES_READY. */
|
||||
public synchronized void onSystemReady() {
|
||||
mUserManagerInternal =
|
||||
Objects.requireNonNull(LocalServices.getService(UserManagerInternal.class));
|
||||
mUserManagerInternal.addUserVisibilityListener(
|
||||
(userId, visible) -> dispatchOnVisibleUserChanged(userId, visible));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected final ActivityManagerInternal getActivityManagerInternal() {
|
||||
synchronized (this) {
|
||||
@@ -135,6 +147,24 @@ public class SystemUserInfoHelper extends UserInfoHelper {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisibleUserId(@UserIdInt int userId) {
|
||||
synchronized (this) {
|
||||
// if you're hitting this precondition then you are invoking this before the system is
|
||||
// ready
|
||||
Preconditions.checkState(mUserManagerInternal != null);
|
||||
}
|
||||
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (this) {
|
||||
return mUserManagerInternal.isUserVisible(userId);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int[] getProfileIds(@UserIdInt int userId) {
|
||||
UserManager userManager = getUserManager();
|
||||
|
||||
@@ -22,6 +22,7 @@ import static com.android.server.location.eventlog.LocationEventLog.EVENT_LOG;
|
||||
import static com.android.server.location.injector.UserInfoHelper.UserListener.CURRENT_USER_CHANGED;
|
||||
import static com.android.server.location.injector.UserInfoHelper.UserListener.USER_STARTED;
|
||||
import static com.android.server.location.injector.UserInfoHelper.UserListener.USER_STOPPED;
|
||||
import static com.android.server.location.injector.UserInfoHelper.UserListener.USER_VISIBILITY_CHANGED;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.UserIdInt;
|
||||
@@ -47,8 +48,9 @@ public abstract class UserInfoHelper {
|
||||
int CURRENT_USER_CHANGED = 1;
|
||||
int USER_STARTED = 2;
|
||||
int USER_STOPPED = 3;
|
||||
int USER_VISIBILITY_CHANGED = 4;
|
||||
|
||||
@IntDef({CURRENT_USER_CHANGED, USER_STARTED, USER_STOPPED})
|
||||
@IntDef({CURRENT_USER_CHANGED, USER_STARTED, USER_STOPPED, USER_VISIBILITY_CHANGED})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface UserChange {}
|
||||
|
||||
@@ -121,6 +123,18 @@ public abstract class UserInfoHelper {
|
||||
}
|
||||
}
|
||||
|
||||
protected final void dispatchOnVisibleUserChanged(@UserIdInt int userId, boolean visible) {
|
||||
if (D) {
|
||||
Log.d(TAG, "visibility of u" + userId + " changed to "
|
||||
+ (visible ? "visible" : "invisible"));
|
||||
}
|
||||
EVENT_LOG.logUserVisibilityChanged(userId, visible);
|
||||
|
||||
for (UserListener listener : mListeners) {
|
||||
listener.onUserChanged(userId, USER_VISIBILITY_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of running user ids. This will include all running users, and will also
|
||||
* include any profiles of the running users. The caller must never mutate the returned
|
||||
@@ -129,8 +143,8 @@ public abstract class UserInfoHelper {
|
||||
public abstract int[] getRunningUserIds();
|
||||
|
||||
/**
|
||||
* Returns true if the given user id is either the current user or a profile of the current
|
||||
* user.
|
||||
* Returns {@code true} if the given user id is either the current user or a profile of the
|
||||
* current user.
|
||||
*/
|
||||
public abstract boolean isCurrentUserId(@UserIdInt int userId);
|
||||
|
||||
@@ -140,6 +154,13 @@ public abstract class UserInfoHelper {
|
||||
*/
|
||||
public abstract @UserIdInt int getCurrentUserId();
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the user is visible.
|
||||
*
|
||||
* <p>The visibility of a user is defined by {@link android.os.UserManager#isUserVisible()}.
|
||||
*/
|
||||
public abstract boolean isVisibleUserId(@UserIdInt int userId);
|
||||
|
||||
protected abstract int[] getProfileIds(@UserIdInt int userId);
|
||||
|
||||
/**
|
||||
|
||||
@@ -2193,7 +2193,7 @@ public class LocationProviderManager extends
|
||||
if (!isEnabled(identity.getUserId())) {
|
||||
return false;
|
||||
}
|
||||
if (!mUserHelper.isCurrentUserId(identity.getUserId())) {
|
||||
if (!mUserHelper.isVisibleUserId(identity.getUserId())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -2322,6 +2322,10 @@ public class LocationProviderManager extends
|
||||
|
||||
switch (change) {
|
||||
case UserListener.CURRENT_USER_CHANGED:
|
||||
// current user changes affect whether system server location requests are
|
||||
// allowed to access location, and visibility changes affect whether any given
|
||||
// user may access location.
|
||||
case UserListener.USER_VISIBILITY_CHANGED:
|
||||
updateRegistrations(
|
||||
registration -> registration.getIdentity().getUserId() == userId);
|
||||
break;
|
||||
|
||||
@@ -34,14 +34,16 @@ public class FakeUserInfoHelper extends UserInfoHelper {
|
||||
public static final int DEFAULT_USERID = 0;
|
||||
|
||||
private final IntArray mRunningUserIds;
|
||||
private final IntArray mVisibleUserIds;
|
||||
private final SparseArray<IntArray> mProfiles;
|
||||
|
||||
private int mCurrentUserId;
|
||||
|
||||
public FakeUserInfoHelper() {
|
||||
mCurrentUserId = DEFAULT_USERID;
|
||||
mRunningUserIds = IntArray.wrap(new int[]{DEFAULT_USERID});
|
||||
mRunningUserIds = IntArray.wrap(new int[] {DEFAULT_USERID});
|
||||
mProfiles = new SparseArray<>();
|
||||
mVisibleUserIds = IntArray.wrap(new int[] {DEFAULT_USERID});
|
||||
}
|
||||
|
||||
public void startUser(int userId) {
|
||||
@@ -65,6 +67,7 @@ public class FakeUserInfoHelper extends UserInfoHelper {
|
||||
mRunningUserIds.remove(idx);
|
||||
}
|
||||
|
||||
setUserInvisibleInternal(userId);
|
||||
dispatchOnUserStopped(userId);
|
||||
}
|
||||
|
||||
@@ -82,16 +85,39 @@ public class FakeUserInfoHelper extends UserInfoHelper {
|
||||
// ensure all profiles are started if they didn't exist before...
|
||||
for (int userId : currentProfileUserIds) {
|
||||
startUserInternal(userId, false);
|
||||
setUserVisibleInternal(userId, true);
|
||||
}
|
||||
|
||||
if (oldUserId != mCurrentUserId) {
|
||||
dispatchOnCurrentUserChanged(oldUserId, mCurrentUserId);
|
||||
setUserVisibleInternal(mCurrentUserId, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getRunningUserIds() {
|
||||
return mRunningUserIds.toArray();
|
||||
private void setUserVisibleInternal(int userId, boolean alwaysDispatch) {
|
||||
int idx = mVisibleUserIds.indexOf(userId);
|
||||
if (idx < 0) {
|
||||
mVisibleUserIds.add(userId);
|
||||
} else if (!alwaysDispatch) {
|
||||
return;
|
||||
}
|
||||
dispatchOnVisibleUserChanged(userId, true);
|
||||
}
|
||||
|
||||
private void setUserInvisibleInternal(int userId) {
|
||||
int idx = mVisibleUserIds.indexOf(userId);
|
||||
if (idx >= 0) {
|
||||
mVisibleUserIds.remove(userId);
|
||||
}
|
||||
dispatchOnVisibleUserChanged(userId, false);
|
||||
}
|
||||
|
||||
public void setUserVisible(int userId, boolean visible) {
|
||||
if (visible) {
|
||||
setUserVisibleInternal(userId, true);
|
||||
} else {
|
||||
setUserInvisibleInternal(userId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,11 +125,21 @@ public class FakeUserInfoHelper extends UserInfoHelper {
|
||||
return ArrayUtils.contains(getProfileIds(mCurrentUserId), userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getRunningUserIds() {
|
||||
return mRunningUserIds.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentUserId() {
|
||||
return mCurrentUserId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisibleUserId(int userId) {
|
||||
return mVisibleUserIds.indexOf(userId) >= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int[] getProfileIds(int userId) {
|
||||
IntArray profiles = mProfiles.get(userId);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.server.location.injector;
|
||||
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -31,6 +32,7 @@ import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.location.injector.UserInfoHelper.UserListener;
|
||||
import com.android.server.pm.UserManagerInternal;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -45,13 +47,14 @@ public class SystemUserInfoHelperTest {
|
||||
|
||||
private static final int USER1_ID = 1;
|
||||
private static final int USER1_MANAGED_ID = 11;
|
||||
private static final int[] USER1_PROFILES = new int[]{USER1_ID, USER1_MANAGED_ID};
|
||||
private static final int[] USER1_PROFILES = new int[] {USER1_ID, USER1_MANAGED_ID};
|
||||
private static final int USER2_ID = 2;
|
||||
private static final int USER2_MANAGED_ID = 12;
|
||||
private static final int[] USER2_PROFILES = new int[]{USER2_ID, USER2_MANAGED_ID};
|
||||
private static final int[] USER2_PROFILES = new int[] {USER2_ID, USER2_MANAGED_ID};
|
||||
|
||||
@Mock private Context mContext;
|
||||
@Mock private UserManager mUserManager;
|
||||
@Mock private UserManagerInternal mUserManagerInternal;
|
||||
|
||||
private SystemUserInfoHelper mHelper;
|
||||
|
||||
@@ -63,12 +66,15 @@ public class SystemUserInfoHelperTest {
|
||||
doReturn(USER1_PROFILES).when(mUserManager).getEnabledProfileIds(USER1_ID);
|
||||
doReturn(USER2_PROFILES).when(mUserManager).getEnabledProfileIds(USER2_ID);
|
||||
|
||||
LocalServices.addService(UserManagerInternal.class, mUserManagerInternal);
|
||||
|
||||
mHelper = new SystemUserInfoHelper(mContext);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
LocalServices.removeServiceForTest(ActivityManagerInternal.class);
|
||||
LocalServices.removeServiceForTest(UserManagerInternal.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -77,11 +83,11 @@ public class SystemUserInfoHelperTest {
|
||||
mHelper.addListener(listener);
|
||||
|
||||
mHelper.dispatchOnCurrentUserChanged(USER1_ID, USER2_ID);
|
||||
verify(listener, times(1)).onUserChanged(USER1_ID, UserListener.CURRENT_USER_CHANGED);
|
||||
verify(listener, times(1)).onUserChanged(USER1_MANAGED_ID,
|
||||
verify(listener).onUserChanged(USER1_ID, UserListener.CURRENT_USER_CHANGED);
|
||||
verify(listener).onUserChanged(USER1_MANAGED_ID,
|
||||
UserListener.CURRENT_USER_CHANGED);
|
||||
verify(listener, times(1)).onUserChanged(USER2_ID, UserListener.CURRENT_USER_CHANGED);
|
||||
verify(listener, times(1)).onUserChanged(USER2_MANAGED_ID,
|
||||
verify(listener).onUserChanged(USER2_ID, UserListener.CURRENT_USER_CHANGED);
|
||||
verify(listener).onUserChanged(USER2_MANAGED_ID,
|
||||
UserListener.CURRENT_USER_CHANGED);
|
||||
|
||||
mHelper.dispatchOnCurrentUserChanged(USER2_ID, USER1_ID);
|
||||
@@ -93,6 +99,25 @@ public class SystemUserInfoHelperTest {
|
||||
UserListener.CURRENT_USER_CHANGED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListener_UserVisibilityChanged() {
|
||||
mHelper.onSystemReady();
|
||||
verify(mUserManagerInternal).addUserVisibilityListener(any());
|
||||
|
||||
UserListener listener = mock(UserListener.class);
|
||||
mHelper.addListener(listener);
|
||||
|
||||
mHelper.dispatchOnVisibleUserChanged(USER1_ID, false);
|
||||
mHelper.dispatchOnVisibleUserChanged(USER2_ID, true);
|
||||
verify(listener).onUserChanged(USER1_ID, UserListener.USER_VISIBILITY_CHANGED);
|
||||
verify(listener).onUserChanged(USER2_ID, UserListener.USER_VISIBILITY_CHANGED);
|
||||
|
||||
mHelper.dispatchOnVisibleUserChanged(USER2_ID, false);
|
||||
mHelper.dispatchOnVisibleUserChanged(USER1_ID, true);
|
||||
verify(listener, times(2)).onUserChanged(USER2_ID, UserListener.USER_VISIBILITY_CHANGED);
|
||||
verify(listener, times(2)).onUserChanged(USER1_ID, UserListener.USER_VISIBILITY_CHANGED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListener_StartUser() {
|
||||
UserListener listener = mock(UserListener.class);
|
||||
|
||||
@@ -175,7 +175,9 @@ public class LocationProviderManagerTest {
|
||||
doReturn(mWakeLock).when(mPowerManager).newWakeLock(anyInt(), anyString());
|
||||
|
||||
mInjector = new TestInjector(mContext);
|
||||
mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
|
||||
mInjector.getUserInfoHelper().startUser(OTHER_USER);
|
||||
mInjector.getUserInfoHelper().setUserVisible(OTHER_USER, true);
|
||||
|
||||
mPassive = new PassiveLocationProviderManager(mContext, mInjector);
|
||||
mPassive.startManager(null);
|
||||
@@ -330,6 +332,20 @@ public class LocationProviderManagerTest {
|
||||
assertThat(coarse).isNearby(loc, 5000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLastLocation_InvisibleUser() {
|
||||
Location loc = createLocation(NAME, mRandom);
|
||||
mProvider.setProviderLocation(loc);
|
||||
|
||||
mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
|
||||
assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
|
||||
PERMISSION_FINE)).isNull();
|
||||
|
||||
mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
|
||||
assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
|
||||
PERMISSION_FINE)).isEqualTo(loc);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLastLocation_Bypass() {
|
||||
mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
|
||||
@@ -568,6 +584,25 @@ public class LocationProviderManagerTest {
|
||||
nullable(IRemoteCallback.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterListener_InvisibleUser() throws Exception {
|
||||
ILocationListener listener = createMockLocationListener();
|
||||
LocationRequest request = new LocationRequest.Builder(0)
|
||||
.setWorkSource(WORK_SOURCE)
|
||||
.build();
|
||||
mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
|
||||
|
||||
mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
|
||||
mProvider.setProviderLocation(createLocationResult(NAME, mRandom));
|
||||
verify(listener, never()).onLocationChanged(any(List.class),
|
||||
nullable(IRemoteCallback.class));
|
||||
|
||||
mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
|
||||
LocationResult loc = createLocationResult(NAME, mRandom);
|
||||
mProvider.setProviderLocation(loc);
|
||||
verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterListener_ExpiringAlarm() throws Exception {
|
||||
ILocationListener listener = createMockLocationListener();
|
||||
@@ -798,6 +833,17 @@ public class LocationProviderManagerTest {
|
||||
verify(listener, times(1)).onLocation(isNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCurrentLocation_InvisibleUser() throws Exception {
|
||||
mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
|
||||
|
||||
ILocationCallback listener = createMockGetCurrentLocationListener();
|
||||
LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
|
||||
mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
|
||||
|
||||
verify(listener).onLocation(isNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFlush() throws Exception {
|
||||
ILocationListener listener = createMockLocationListener();
|
||||
@@ -1007,6 +1053,21 @@ public class LocationProviderManagerTest {
|
||||
mInjector.getSettingsHelper().getBackgroundThrottleIntervalMs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderRequest_InvisibleUser() {
|
||||
ILocationListener listener = createMockLocationListener();
|
||||
LocationRequest request = new LocationRequest.Builder(5)
|
||||
.setWorkSource(WORK_SOURCE)
|
||||
.build();
|
||||
mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
|
||||
|
||||
mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
|
||||
assertThat(mProvider.getRequest().isActive()).isFalse();
|
||||
|
||||
mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
|
||||
assertThat(mProvider.getRequest().isActive()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderRequest_IgnoreLocationSettings() {
|
||||
mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
|
||||
|
||||
Reference in New Issue
Block a user