Loading services/core/java/com/android/server/LocationManagerService.java +55 −9 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.pm.Signature; import android.content.pm.UserInfo; import android.content.res.Resources; import android.database.ContentObserver; import android.location.Address; Loading @@ -55,10 +56,12 @@ import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.os.WorkSource; import android.provider.Settings; import android.util.Log; import android.util.Slog; import com.android.internal.content.PackageMonitor; import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; Loading Loading @@ -144,6 +147,7 @@ public class LocationManagerService extends ILocationManager.Stub { private GeofenceManager mGeofenceManager; private PackageManager mPackageManager; private PowerManager mPowerManager; private UserManager mUserManager; private GeocoderProxy mGeocodeProvider; private IGpsStatusProvider mGpsStatusProvider; private INetInitiatedListener mNetInitiatedListener; Loading Loading @@ -197,6 +201,7 @@ public class LocationManagerService extends ILocationManager.Stub { // current active user on the device - other users are denied location data private int mCurrentUserId = UserHandle.USER_OWNER; private int[] mCurrentUserProfiles = new int[] { UserHandle.USER_OWNER }; public LocationManagerService(Context context) { super(); Loading Loading @@ -241,6 +246,9 @@ public class LocationManagerService extends ILocationManager.Stub { }; mAppOps.startWatchingMode(AppOpsManager.OP_COARSE_LOCATION, null, callback); mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); updateUserProfiles(mCurrentUserId); // prepare providers loadProvidersLocked(); updateProvidersLocked(); Loading @@ -262,6 +270,8 @@ public class LocationManagerService extends ILocationManager.Stub { // listen for user change IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_SWITCHED); intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); mContext.registerReceiverAsUser(new BroadcastReceiver() { @Override Loading @@ -269,11 +279,46 @@ public class LocationManagerService extends ILocationManager.Stub { String action = intent.getAction(); if (Intent.ACTION_USER_SWITCHED.equals(action)) { switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); } else if (Intent.ACTION_MANAGED_PROFILE_ADDED.equals(action) || Intent.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) { updateUserProfiles(mCurrentUserId); } } }, UserHandle.ALL, intentFilter, null, mLocationHandler); } /** * Makes a list of userids that are related to the current user. This is * relevant when using managed profiles. Otherwise the list only contains * the current user. * * @param currentUserId the current user, who might have an alter-ego. */ void updateUserProfiles(int currentUserId) { List<UserInfo> profiles = mUserManager.getProfiles(currentUserId); synchronized (mLock) { mCurrentUserProfiles = new int[profiles.size()]; for (int i = 0; i < mCurrentUserProfiles.length; i++) { mCurrentUserProfiles[i] = profiles.get(i).id; } } } /** * Checks if the specified userId matches any of the current foreground * users stored in mCurrentUserProfiles. */ private boolean isCurrentProfile(int userId) { synchronized (mLock) { for (int i = 0; i < mCurrentUserProfiles.length; i++) { if (mCurrentUserProfiles[i] == userId) { return true; } } return false; } } private void ensureFallbackFusedProviderPresentLocked(ArrayList<String> pkgs) { PackageManager pm = mContext.getPackageManager(); String systemPackageName = mContext.getPackageName(); Loading Loading @@ -492,9 +537,10 @@ public class LocationManagerService extends ILocationManager.Stub { mLastLocation.clear(); mLastLocationCoarseInterval.clear(); for (LocationProviderInterface p : mProviders) { updateProviderListenersLocked(p.getName(), false, mCurrentUserId); updateProviderListenersLocked(p.getName(), false); } mCurrentUserId = userId; updateUserProfiles(userId); updateProvidersLocked(); } } Loading Loading @@ -894,7 +940,7 @@ public class LocationManagerService extends ILocationManager.Stub { * @return */ private boolean isAllowedByUserSettingsLocked(String provider, int uid) { if (UserHandle.getUserId(uid) != mCurrentUserId && !isUidALocationProvider(uid)) { if (!isCurrentProfile(UserHandle.getUserId(uid)) && !isUidALocationProvider(uid)) { return false; } return isAllowedByCurrentUserSettingsLocked(provider); Loading Loading @@ -1181,7 +1227,7 @@ public class LocationManagerService extends ILocationManager.Stub { String name = p.getName(); boolean shouldBeEnabled = isAllowedByCurrentUserSettingsLocked(name); if (isEnabled && !shouldBeEnabled) { updateProviderListenersLocked(name, false, mCurrentUserId); updateProviderListenersLocked(name, false); // If any provider has been disabled, clear all last locations for all providers. // This is to be on the safe side in case a provider has location derived from // this disabled provider. Loading @@ -1189,7 +1235,7 @@ public class LocationManagerService extends ILocationManager.Stub { mLastLocationCoarseInterval.clear(); changesMade = true; } else if (!isEnabled && shouldBeEnabled) { updateProviderListenersLocked(name, true, mCurrentUserId); updateProviderListenersLocked(name, true); changesMade = true; } } Loading @@ -1201,7 +1247,7 @@ public class LocationManagerService extends ILocationManager.Stub { } } private void updateProviderListenersLocked(String provider, boolean enabled, int userId) { private void updateProviderListenersLocked(String provider, boolean enabled) { int listeners = 0; LocationProviderInterface p = mProvidersByName.get(provider); Loading @@ -1214,7 +1260,7 @@ public class LocationManagerService extends ILocationManager.Stub { final int N = records.size(); for (int i = 0; i < N; i++) { UpdateRecord record = records.get(i); if (UserHandle.getUserId(record.mReceiver.mUid) == userId) { if (isCurrentProfile(UserHandle.getUserId(record.mReceiver.mUid))) { // Sends a notification message to the receiver if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) { if (deadReceivers == null) { Loading Loading @@ -1253,7 +1299,7 @@ public class LocationManagerService extends ILocationManager.Stub { if (records != null) { for (UpdateRecord record : records) { if (UserHandle.getUserId(record.mReceiver.mUid) == mCurrentUserId) { if (isCurrentProfile(UserHandle.getUserId(record.mReceiver.mUid))) { if (checkLocationAccess(record.mReceiver.mUid, record.mReceiver.mPackageName, record.mReceiver.mAllowedResolutionLevel)) { LocationRequest locationRequest = record.mRequest; Loading @@ -1274,7 +1320,7 @@ public class LocationManagerService extends ILocationManager.Stub { // under that threshold. long thresholdInterval = (providerRequest.interval + 1000) * 3 / 2; for (UpdateRecord record : records) { if (UserHandle.getUserId(record.mReceiver.mUid) == mCurrentUserId) { if (isCurrentProfile(UserHandle.getUserId(record.mReceiver.mUid))) { LocationRequest locationRequest = record.mRequest; if (locationRequest.getInterval() <= thresholdInterval) { if (record.mReceiver.mWorkSource != null Loading Loading @@ -2018,7 +2064,7 @@ public class LocationManagerService extends ILocationManager.Stub { boolean receiverDead = false; int receiverUserId = UserHandle.getUserId(receiver.mUid); if (receiverUserId != mCurrentUserId && !isUidALocationProvider(receiver.mUid)) { if (!isCurrentProfile(receiverUserId) && !isUidALocationProvider(receiver.mUid)) { if (D) { Log.d(TAG, "skipping loc update for background user " + receiverUserId + " (current user: " + mCurrentUserId + ", app: " + Loading Loading
services/core/java/com/android/server/LocationManagerService.java +55 −9 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.pm.Signature; import android.content.pm.UserInfo; import android.content.res.Resources; import android.database.ContentObserver; import android.location.Address; Loading @@ -55,10 +56,12 @@ import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.os.WorkSource; import android.provider.Settings; import android.util.Log; import android.util.Slog; import com.android.internal.content.PackageMonitor; import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; Loading Loading @@ -144,6 +147,7 @@ public class LocationManagerService extends ILocationManager.Stub { private GeofenceManager mGeofenceManager; private PackageManager mPackageManager; private PowerManager mPowerManager; private UserManager mUserManager; private GeocoderProxy mGeocodeProvider; private IGpsStatusProvider mGpsStatusProvider; private INetInitiatedListener mNetInitiatedListener; Loading Loading @@ -197,6 +201,7 @@ public class LocationManagerService extends ILocationManager.Stub { // current active user on the device - other users are denied location data private int mCurrentUserId = UserHandle.USER_OWNER; private int[] mCurrentUserProfiles = new int[] { UserHandle.USER_OWNER }; public LocationManagerService(Context context) { super(); Loading Loading @@ -241,6 +246,9 @@ public class LocationManagerService extends ILocationManager.Stub { }; mAppOps.startWatchingMode(AppOpsManager.OP_COARSE_LOCATION, null, callback); mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); updateUserProfiles(mCurrentUserId); // prepare providers loadProvidersLocked(); updateProvidersLocked(); Loading @@ -262,6 +270,8 @@ public class LocationManagerService extends ILocationManager.Stub { // listen for user change IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_SWITCHED); intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); mContext.registerReceiverAsUser(new BroadcastReceiver() { @Override Loading @@ -269,11 +279,46 @@ public class LocationManagerService extends ILocationManager.Stub { String action = intent.getAction(); if (Intent.ACTION_USER_SWITCHED.equals(action)) { switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); } else if (Intent.ACTION_MANAGED_PROFILE_ADDED.equals(action) || Intent.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) { updateUserProfiles(mCurrentUserId); } } }, UserHandle.ALL, intentFilter, null, mLocationHandler); } /** * Makes a list of userids that are related to the current user. This is * relevant when using managed profiles. Otherwise the list only contains * the current user. * * @param currentUserId the current user, who might have an alter-ego. */ void updateUserProfiles(int currentUserId) { List<UserInfo> profiles = mUserManager.getProfiles(currentUserId); synchronized (mLock) { mCurrentUserProfiles = new int[profiles.size()]; for (int i = 0; i < mCurrentUserProfiles.length; i++) { mCurrentUserProfiles[i] = profiles.get(i).id; } } } /** * Checks if the specified userId matches any of the current foreground * users stored in mCurrentUserProfiles. */ private boolean isCurrentProfile(int userId) { synchronized (mLock) { for (int i = 0; i < mCurrentUserProfiles.length; i++) { if (mCurrentUserProfiles[i] == userId) { return true; } } return false; } } private void ensureFallbackFusedProviderPresentLocked(ArrayList<String> pkgs) { PackageManager pm = mContext.getPackageManager(); String systemPackageName = mContext.getPackageName(); Loading Loading @@ -492,9 +537,10 @@ public class LocationManagerService extends ILocationManager.Stub { mLastLocation.clear(); mLastLocationCoarseInterval.clear(); for (LocationProviderInterface p : mProviders) { updateProviderListenersLocked(p.getName(), false, mCurrentUserId); updateProviderListenersLocked(p.getName(), false); } mCurrentUserId = userId; updateUserProfiles(userId); updateProvidersLocked(); } } Loading Loading @@ -894,7 +940,7 @@ public class LocationManagerService extends ILocationManager.Stub { * @return */ private boolean isAllowedByUserSettingsLocked(String provider, int uid) { if (UserHandle.getUserId(uid) != mCurrentUserId && !isUidALocationProvider(uid)) { if (!isCurrentProfile(UserHandle.getUserId(uid)) && !isUidALocationProvider(uid)) { return false; } return isAllowedByCurrentUserSettingsLocked(provider); Loading Loading @@ -1181,7 +1227,7 @@ public class LocationManagerService extends ILocationManager.Stub { String name = p.getName(); boolean shouldBeEnabled = isAllowedByCurrentUserSettingsLocked(name); if (isEnabled && !shouldBeEnabled) { updateProviderListenersLocked(name, false, mCurrentUserId); updateProviderListenersLocked(name, false); // If any provider has been disabled, clear all last locations for all providers. // This is to be on the safe side in case a provider has location derived from // this disabled provider. Loading @@ -1189,7 +1235,7 @@ public class LocationManagerService extends ILocationManager.Stub { mLastLocationCoarseInterval.clear(); changesMade = true; } else if (!isEnabled && shouldBeEnabled) { updateProviderListenersLocked(name, true, mCurrentUserId); updateProviderListenersLocked(name, true); changesMade = true; } } Loading @@ -1201,7 +1247,7 @@ public class LocationManagerService extends ILocationManager.Stub { } } private void updateProviderListenersLocked(String provider, boolean enabled, int userId) { private void updateProviderListenersLocked(String provider, boolean enabled) { int listeners = 0; LocationProviderInterface p = mProvidersByName.get(provider); Loading @@ -1214,7 +1260,7 @@ public class LocationManagerService extends ILocationManager.Stub { final int N = records.size(); for (int i = 0; i < N; i++) { UpdateRecord record = records.get(i); if (UserHandle.getUserId(record.mReceiver.mUid) == userId) { if (isCurrentProfile(UserHandle.getUserId(record.mReceiver.mUid))) { // Sends a notification message to the receiver if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) { if (deadReceivers == null) { Loading Loading @@ -1253,7 +1299,7 @@ public class LocationManagerService extends ILocationManager.Stub { if (records != null) { for (UpdateRecord record : records) { if (UserHandle.getUserId(record.mReceiver.mUid) == mCurrentUserId) { if (isCurrentProfile(UserHandle.getUserId(record.mReceiver.mUid))) { if (checkLocationAccess(record.mReceiver.mUid, record.mReceiver.mPackageName, record.mReceiver.mAllowedResolutionLevel)) { LocationRequest locationRequest = record.mRequest; Loading @@ -1274,7 +1320,7 @@ public class LocationManagerService extends ILocationManager.Stub { // under that threshold. long thresholdInterval = (providerRequest.interval + 1000) * 3 / 2; for (UpdateRecord record : records) { if (UserHandle.getUserId(record.mReceiver.mUid) == mCurrentUserId) { if (isCurrentProfile(UserHandle.getUserId(record.mReceiver.mUid))) { LocationRequest locationRequest = record.mRequest; if (locationRequest.getInterval() <= thresholdInterval) { if (record.mReceiver.mWorkSource != null Loading Loading @@ -2018,7 +2064,7 @@ public class LocationManagerService extends ILocationManager.Stub { boolean receiverDead = false; int receiverUserId = UserHandle.getUserId(receiver.mUid); if (receiverUserId != mCurrentUserId && !isUidALocationProvider(receiver.mUid)) { if (!isCurrentProfile(receiverUserId) && !isUidALocationProvider(receiver.mUid)) { if (D) { Log.d(TAG, "skipping loc update for background user " + receiverUserId + " (current user: " + mCurrentUserId + ", app: " + Loading