summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Grace Cheng <gracemc@google.com> 2022-11-29 03:59:58 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-11-29 03:59:58 +0000
commita98ee9546ec4cf7c3ae43b3c6a54d4b9f06fdb43 (patch)
tree3a966b292d8a6548a857c96f9fa3f394b325a83b
parentcddf907e07478879e00747dc020cb0c251d52275 (diff)
parent361e41067015d7aa4475eca50ed71a624ba7ea0a (diff)
Merge "Updates location services to support concurrent multi user."
-rw-r--r--services/core/java/com/android/server/location/LocationManagerService.java11
-rw-r--r--services/core/java/com/android/server/location/eventlog/LocationEventLog.java21
-rw-r--r--services/core/java/com/android/server/location/geofence/GeofenceManager.java7
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java7
-rw-r--r--services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java30
-rw-r--r--services/core/java/com/android/server/location/injector/UserInfoHelper.java27
-rw-r--r--services/core/java/com/android/server/location/provider/LocationProviderManager.java6
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/location/injector/FakeUserInfoHelper.java44
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/location/injector/SystemUserInfoHelperTest.java37
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java61
10 files changed, 225 insertions, 26 deletions
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index 2669d217120f..8d247f6a89e3 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -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();
diff --git a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
index 45436e753191..cb952edd0b71 100644
--- a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
+++ b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
@@ -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;
diff --git a/services/core/java/com/android/server/location/geofence/GeofenceManager.java b/services/core/java/com/android/server/location/geofence/GeofenceManager.java
index 0f5e3d46fd22..d3ceddd56827 100644
--- a/services/core/java/com/android/server/location/geofence/GeofenceManager.java
+++ b/services/core/java/com/android/server/location/geofence/GeofenceManager.java
@@ -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);
}
}
diff --git a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java
index 349b94bc137b..567d8ac5e5df 100644
--- a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java
+++ b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java
@@ -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);
}
}
diff --git a/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java b/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java
index ed1e65457b24..40dd979c9692 100644
--- a/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java
+++ b/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java
@@ -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) {
@@ -136,6 +148,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();
diff --git a/services/core/java/com/android/server/location/injector/UserInfoHelper.java b/services/core/java/com/android/server/location/injector/UserInfoHelper.java
index c835370a6f86..2b9db1c8a557 100644
--- a/services/core/java/com/android/server/location/injector/UserInfoHelper.java
+++ b/services/core/java/com/android/server/location/injector/UserInfoHelper.java
@@ -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);
/**
diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
index 338a99567b67..a2b001da78f2 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
@@ -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;
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeUserInfoHelper.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeUserInfoHelper.java
index ac23d4e427c4..014ef3d7ef63 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeUserInfoHelper.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeUserInfoHelper.java
@@ -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
@@ -100,11 +126,21 @@ public class FakeUserInfoHelper extends UserInfoHelper {
}
@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);
if (profiles != null) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemUserInfoHelperTest.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemUserInfoHelperTest.java
index 490b2e87976a..d9aa23244ce2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemUserInfoHelperTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemUserInfoHelperTest.java
@@ -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);
@@ -94,6 +100,25 @@ public class SystemUserInfoHelperTest {
}
@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);
mHelper.addListener(listener);
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
index 20e4e8011327..aa28ad489027 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
@@ -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);
@@ -331,6 +333,20 @@ public class LocationProviderManagerTest {
}
@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(
new PackageTagsList.Builder().add(
@@ -569,6 +585,25 @@ public class LocationProviderManagerTest {
}
@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();
LocationRequest request = new LocationRequest.Builder(0)
@@ -799,6 +834,17 @@ public class LocationProviderManagerTest {
}
@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();
mManager.registerLocationRequest(
@@ -1008,6 +1054,21 @@ public class LocationProviderManagerTest {
}
@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(
new PackageTagsList.Builder().add(