Merge "Make LocationManagerService aware of user profiles"

This commit is contained in:
Amith Yamasani
2014-06-10 01:20:19 +00:00
committed by Android (Google) Code Review

View File

@@ -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;
@@ -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;
@@ -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;
@@ -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();
@@ -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();
@@ -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
@@ -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();
@@ -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();
}
}
@@ -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);
@@ -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.
@@ -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;
}
}
@@ -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);
@@ -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) {
@@ -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;
@@ -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
@@ -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: " +