Merge "Multiuser love for LocationManager" into jb-mr1-dev

This commit is contained in:
Victoria Lease
2012-10-09 12:22:02 -07:00
committed by Android (Google) Code Review
9 changed files with 222 additions and 118 deletions

View File

@ -4052,7 +4052,20 @@ public final class Settings {
* @return true if the provider is enabled * @return true if the provider is enabled
*/ */
public static final boolean isLocationProviderEnabled(ContentResolver cr, String provider) { public static final boolean isLocationProviderEnabled(ContentResolver cr, String provider) {
String allowedProviders = Settings.Secure.getString(cr, LOCATION_PROVIDERS_ALLOWED); return isLocationProviderEnabledForUser(cr, provider, UserHandle.myUserId());
}
/**
* Helper method for determining if a location provider is enabled.
* @param cr the content resolver to use
* @param provider the location provider to query
* @param userId the userId to query
* @return true if the provider is enabled
* @hide
*/
public static final boolean isLocationProviderEnabledForUser(ContentResolver cr, String provider, int userId) {
String allowedProviders = Settings.Secure.getStringForUser(cr,
LOCATION_PROVIDERS_ALLOWED, userId);
return TextUtils.delimitedStringContains(allowedProviders, ',', provider); return TextUtils.delimitedStringContains(allowedProviders, ',', provider);
} }
@ -4064,6 +4077,19 @@ public final class Settings {
*/ */
public static final void setLocationProviderEnabled(ContentResolver cr, public static final void setLocationProviderEnabled(ContentResolver cr,
String provider, boolean enabled) { String provider, boolean enabled) {
setLocationProviderEnabledForUser(cr, provider, enabled, UserHandle.myUserId());
}
/**
* Thread-safe method for enabling or disabling a single location provider.
* @param cr the content resolver to use
* @param provider the location provider to enable or disable
* @param enabled true if the provider should be enabled
* @param userId the userId for which to enable/disable providers
* @hide
*/
public static final void setLocationProviderEnabledForUser(ContentResolver cr,
String provider, boolean enabled, int userId) {
// to ensure thread safety, we write the provider name with a '+' or '-' // to ensure thread safety, we write the provider name with a '+' or '-'
// and let the SettingsProvider handle it rather than reading and modifying // and let the SettingsProvider handle it rather than reading and modifying
// the list of enabled providers. // the list of enabled providers.
@ -4072,7 +4098,8 @@ public final class Settings {
} else { } else {
provider = "-" + provider; provider = "-" + provider;
} }
putString(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider); putStringForUser(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider,
userId);
} }
} }

View File

@ -226,7 +226,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
updateProvidersLocked(); updateProvidersLocked();
} }
} }
}); }, UserHandle.USER_ALL);
mPackageMonitor.register(mContext, Looper.myLooper(), true); mPackageMonitor.register(mContext, Looper.myLooper(), true);
// listen for user change // listen for user change
@ -289,7 +289,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
mContext, mContext,
LocationManager.NETWORK_PROVIDER, LocationManager.NETWORK_PROVIDER,
NETWORK_LOCATION_SERVICE_ACTION, NETWORK_LOCATION_SERVICE_ACTION,
providerPackageNames, mLocationHandler); providerPackageNames, mLocationHandler, mCurrentUserId);
if (networkProvider != null) { if (networkProvider != null) {
mRealProviders.put(LocationManager.NETWORK_PROVIDER, networkProvider); mRealProviders.put(LocationManager.NETWORK_PROVIDER, networkProvider);
mProxyProviders.add(networkProvider); mProxyProviders.add(networkProvider);
@ -303,7 +303,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
mContext, mContext,
LocationManager.FUSED_PROVIDER, LocationManager.FUSED_PROVIDER,
FUSED_LOCATION_SERVICE_ACTION, FUSED_LOCATION_SERVICE_ACTION,
providerPackageNames, mLocationHandler); providerPackageNames, mLocationHandler, mCurrentUserId);
if (fusedLocationProvider != null) { if (fusedLocationProvider != null) {
addProviderLocked(fusedLocationProvider); addProviderLocked(fusedLocationProvider);
mProxyProviders.add(fusedLocationProvider); mProxyProviders.add(fusedLocationProvider);
@ -314,7 +314,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
} }
// bind to geocoder provider // bind to geocoder provider
mGeocodeProvider = GeocoderProxy.createAndBind(mContext, providerPackageNames); mGeocodeProvider = GeocoderProxy.createAndBind(mContext, providerPackageNames,
mCurrentUserId);
if (mGeocodeProvider == null) { if (mGeocodeProvider == null) {
Slog.e(TAG, "no geocoder provider found"); Slog.e(TAG, "no geocoder provider found");
} }
@ -326,11 +327,14 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
*/ */
private void switchUser(int userId) { private void switchUser(int userId) {
mBlacklist.switchUser(userId); mBlacklist.switchUser(userId);
//Log.d("LocationManagerService", "switchUser(" + mCurrentUserId + " -> " + userId + ")"); // TODO: remove this
synchronized (mLock) { synchronized (mLock) {
// TODO: inform previous user's Receivers that they will no longer receive updates mLastLocation.clear();
for (LocationProviderInterface p : mProviders) {
updateProviderListenersLocked(p.getName(), false, mCurrentUserId);
p.switchUser(userId);
}
mCurrentUserId = userId; mCurrentUserId = userId;
// TODO: inform new user's Receivers that they are back on the update train updateProvidersLocked();
} }
} }
@ -587,7 +591,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
} }
private boolean isAllowedBySettingsLocked(String provider) { private boolean isAllowedBySettingsLocked(String provider, int userId) {
if (userId != mCurrentUserId) {
return false;
}
if (mEnabledProviders.contains(provider)) { if (mEnabledProviders.contains(provider)) {
return true; return true;
} }
@ -597,7 +604,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// Use system settings // Use system settings
ContentResolver resolver = mContext.getContentResolver(); ContentResolver resolver = mContext.getContentResolver();
return Settings.Secure.isLocationProviderEnabled(resolver, provider); return Settings.Secure.isLocationProviderEnabledForUser(resolver, provider, mCurrentUserId);
} }
/** /**
@ -695,24 +702,30 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
@Override @Override
public List<String> getProviders(Criteria criteria, boolean enabledOnly) { public List<String> getProviders(Criteria criteria, boolean enabledOnly) {
ArrayList<String> out; ArrayList<String> out;
synchronized (mLock) { int callingUserId = UserHandle.getCallingUserId();
out = new ArrayList<String>(mProviders.size()); long identity = Binder.clearCallingIdentity();
for (LocationProviderInterface provider : mProviders) { try {
String name = provider.getName(); synchronized (mLock) {
if (LocationManager.FUSED_PROVIDER.equals(name)) { out = new ArrayList<String>(mProviders.size());
continue; for (LocationProviderInterface provider : mProviders) {
} String name = provider.getName();
if (isAllowedProviderSafe(name)) { if (LocationManager.FUSED_PROVIDER.equals(name)) {
if (enabledOnly && !isAllowedBySettingsLocked(name)) {
continue; continue;
} }
if (criteria != null && !LocationProvider.propertiesMeetCriteria( if (isAllowedProviderSafe(name)) {
name, provider.getProperties(), criteria)) { if (enabledOnly && !isAllowedBySettingsLocked(name, callingUserId)) {
continue; continue;
}
if (criteria != null && !LocationProvider.propertiesMeetCriteria(
name, provider.getProperties(), criteria)) {
continue;
}
out.add(name);
} }
out.add(name);
} }
} }
} finally {
Binder.restoreCallingIdentity(identity);
} }
if (D) Log.d(TAG, "getProviders()=" + out); if (D) Log.d(TAG, "getProviders()=" + out);
@ -778,12 +791,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
LocationProviderInterface p = mProviders.get(i); LocationProviderInterface p = mProviders.get(i);
boolean isEnabled = p.isEnabled(); boolean isEnabled = p.isEnabled();
String name = p.getName(); String name = p.getName();
boolean shouldBeEnabled = isAllowedBySettingsLocked(name); boolean shouldBeEnabled = isAllowedBySettingsLocked(name, mCurrentUserId);
if (isEnabled && !shouldBeEnabled) { if (isEnabled && !shouldBeEnabled) {
updateProviderListenersLocked(name, false); updateProviderListenersLocked(name, false, mCurrentUserId);
changesMade = true; changesMade = true;
} else if (!isEnabled && shouldBeEnabled) { } else if (!isEnabled && shouldBeEnabled) {
updateProviderListenersLocked(name, true); updateProviderListenersLocked(name, true, mCurrentUserId);
changesMade = true; changesMade = true;
} }
} }
@ -793,7 +806,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
} }
} }
private void updateProviderListenersLocked(String provider, boolean enabled) { private void updateProviderListenersLocked(String provider, boolean enabled, int userId) {
int listeners = 0; int listeners = 0;
LocationProviderInterface p = mProvidersByName.get(provider); LocationProviderInterface p = mProvidersByName.get(provider);
@ -806,14 +819,16 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
final int N = records.size(); final int N = records.size();
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
UpdateRecord record = records.get(i); UpdateRecord record = records.get(i);
// Sends a notification message to the receiver if (UserHandle.getUserId(record.mReceiver.mUid) == userId) {
if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) { // Sends a notification message to the receiver
if (deadReceivers == null) { if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) {
deadReceivers = new ArrayList<Receiver>(); if (deadReceivers == null) {
deadReceivers = new ArrayList<Receiver>();
}
deadReceivers.add(record.mReceiver);
} }
deadReceivers.add(record.mReceiver); listeners++;
} }
listeners++;
} }
} }
@ -843,12 +858,13 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
if (records != null) { if (records != null) {
for (UpdateRecord record : records) { for (UpdateRecord record : records) {
LocationRequest locationRequest = record.mRequest; if (UserHandle.getUserId(record.mReceiver.mUid) == mCurrentUserId) {
LocationRequest locationRequest = record.mRequest;
providerRequest.locationRequests.add(locationRequest); providerRequest.locationRequests.add(locationRequest);
if (locationRequest.getInterval() < providerRequest.interval) { if (locationRequest.getInterval() < providerRequest.interval) {
providerRequest.reportLocation = true; providerRequest.reportLocation = true;
providerRequest.interval = locationRequest.getInterval(); providerRequest.interval = locationRequest.getInterval();
}
} }
} }
@ -860,9 +876,11 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// under that threshold. // under that threshold.
long thresholdInterval = (providerRequest.interval + 1000) * 3 / 2; long thresholdInterval = (providerRequest.interval + 1000) * 3 / 2;
for (UpdateRecord record : records) { for (UpdateRecord record : records) {
LocationRequest locationRequest = record.mRequest; if (UserHandle.getUserId(record.mReceiver.mUid) == mCurrentUserId) {
if (locationRequest.getInterval() <= thresholdInterval) { LocationRequest locationRequest = record.mRequest;
worksource.add(record.mReceiver.mUid); if (locationRequest.getInterval() <= thresholdInterval) {
worksource.add(record.mReceiver.mUid);
}
} }
} }
} }
@ -1084,7 +1102,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
oldRecord.disposeLocked(false); oldRecord.disposeLocked(false);
} }
boolean isProviderEnabled = isAllowedBySettingsLocked(name); boolean isProviderEnabled = isAllowedBySettingsLocked(name, UserHandle.getUserId(uid));
if (isProviderEnabled) { if (isProviderEnabled) {
applyRequirementsLocked(name); applyRequirementsLocked(name);
} else { } else {
@ -1141,7 +1159,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// update provider // update provider
for (String provider : providers) { for (String provider : providers) {
// If provider is already disabled, don't need to do anything // If provider is already disabled, don't need to do anything
if (!isAllowedBySettingsLocked(provider)) { if (!isAllowedBySettingsLocked(provider, mCurrentUserId)) {
continue; continue;
} }
@ -1156,36 +1174,41 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
String perm = checkPermissionAndRequest(request); String perm = checkPermissionAndRequest(request);
checkPackageName(packageName); checkPackageName(packageName);
if (mBlacklist.isBlacklisted(packageName)) { long identity = Binder.clearCallingIdentity();
if (D) Log.d(TAG, "not returning last loc for blacklisted app: " + try {
packageName); if (mBlacklist.isBlacklisted(packageName)) {
return null; if (D) Log.d(TAG, "not returning last loc for blacklisted app: " +
} packageName);
synchronized (mLock) {
// Figure out the provider. Either its explicitly request (deprecated API's),
// or use the fused provider
String name = request.getProvider();
if (name == null) name = LocationManager.FUSED_PROVIDER;
LocationProviderInterface provider = mProvidersByName.get(name);
if (provider == null) return null;
if (!isAllowedBySettingsLocked(name)) return null;
Location location = mLastLocation.get(name);
if (location == null) {
return null; return null;
} }
if (ACCESS_FINE_LOCATION.equals(perm)) {
return location; synchronized (mLock) {
} else { // Figure out the provider. Either its explicitly request (deprecated API's),
Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); // or use the fused provider
if (noGPSLocation != null) { String name = request.getProvider();
return mLocationFudger.getOrCreate(noGPSLocation); if (name == null) name = LocationManager.FUSED_PROVIDER;
LocationProviderInterface provider = mProvidersByName.get(name);
if (provider == null) return null;
if (!isAllowedBySettingsLocked(name, mCurrentUserId)) return null;
Location location = mLastLocation.get(name);
if (location == null) {
return null;
}
if (ACCESS_FINE_LOCATION.equals(perm)) {
return location;
} else {
Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION);
if (noGPSLocation != null) {
return mLocationFudger.getOrCreate(noGPSLocation);
}
} }
} }
return null;
} finally {
Binder.restoreCallingIdentity(identity);
} }
return null;
} }
@Override @Override
@ -1321,11 +1344,16 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
"\" provider requires ACCESS_FINE_LOCATION permission"); "\" provider requires ACCESS_FINE_LOCATION permission");
} }
synchronized (mLock) { long identity = Binder.clearCallingIdentity();
LocationProviderInterface p = mProvidersByName.get(provider); try {
if (p == null) return false; synchronized (mLock) {
LocationProviderInterface p = mProvidersByName.get(provider);
if (p == null) return false;
return isAllowedBySettingsLocked(provider); return isAllowedBySettingsLocked(provider, mCurrentUserId);
}
} finally {
Binder.restoreCallingIdentity(identity);
} }
} }
@ -1461,6 +1489,16 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
Receiver receiver = r.mReceiver; Receiver receiver = r.mReceiver;
boolean receiverDead = false; boolean receiverDead = false;
int receiverUserId = UserHandle.getUserId(receiver.mUid);
if (receiverUserId != mCurrentUserId) {
if (D) {
Log.d(TAG, "skipping loc update for background user " + receiverUserId +
" (current user: " + mCurrentUserId + ", app: " +
receiver.mPackageName + ")");
}
continue;
}
if (mBlacklist.isBlacklisted(receiver.mPackageName)) { if (mBlacklist.isBlacklisted(receiver.mPackageName)) {
if (D) Log.d(TAG, "skipping loc update for blacklisted app: " + if (D) Log.d(TAG, "skipping loc update for blacklisted app: " +
receiver.mPackageName); receiver.mPackageName);
@ -1551,7 +1589,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
} }
synchronized (mLock) { synchronized (mLock) {
if (isAllowedBySettingsLocked(provider)) { if (isAllowedBySettingsLocked(provider, mCurrentUserId)) {
handleLocationChangedLocked(location, passive); handleLocationChangedLocked(location, passive);
} }
} }

View File

@ -27,6 +27,7 @@ import android.content.pm.ResolveInfo;
import android.content.pm.Signature; import android.content.pm.Signature;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.UserHandle;
import android.util.Log; import android.util.Log;
import com.android.internal.content.PackageMonitor; import com.android.internal.content.PackageMonitor;
@ -58,15 +59,17 @@ public class ServiceWatcher implements ServiceConnection {
private IBinder mBinder; // connected service private IBinder mBinder; // connected service
private String mPackageName; // current best package private String mPackageName; // current best package
private int mVersion; // current best version private int mVersion; // current best version
private int mCurrentUserId;
public ServiceWatcher(Context context, String logTag, String action, public ServiceWatcher(Context context, String logTag, String action,
List<String> initialPackageNames, Runnable newServiceWork, Handler handler) { List<String> initialPackageNames, Runnable newServiceWork, Handler handler, int userId) {
mContext = context; mContext = context;
mTag = logTag; mTag = logTag;
mAction = action; mAction = action;
mPm = mContext.getPackageManager(); mPm = mContext.getPackageManager();
mNewServiceWork = newServiceWork; mNewServiceWork = newServiceWork;
mHandler = handler; mHandler = handler;
mCurrentUserId = userId;
mSignatureSets = new ArrayList<HashSet<Signature>>(); mSignatureSets = new ArrayList<HashSet<Signature>>();
for (int i=0; i < initialPackageNames.size(); i++) { for (int i=0; i < initialPackageNames.size(); i++) {
@ -85,9 +88,11 @@ public class ServiceWatcher implements ServiceConnection {
} }
public boolean start() { public boolean start() {
if (!bindBestPackage(null)) return false; synchronized (mLock) {
if (!bindBestPackageLocked(null)) return false;
}
mPackageMonitor.register(mContext, null, true); mPackageMonitor.register(mContext, null, UserHandle.ALL, true);
return true; return true;
} }
@ -98,13 +103,13 @@ public class ServiceWatcher implements ServiceConnection {
* is null. * is null.
* Return true if a new package was found to bind to. * Return true if a new package was found to bind to.
*/ */
private boolean bindBestPackage(String justCheckThisPackage) { private boolean bindBestPackageLocked(String justCheckThisPackage) {
Intent intent = new Intent(mAction); Intent intent = new Intent(mAction);
if (justCheckThisPackage != null) { if (justCheckThisPackage != null) {
intent.setPackage(justCheckThisPackage); intent.setPackage(justCheckThisPackage);
} }
List<ResolveInfo> rInfos = mPm.queryIntentServices(new Intent(mAction), List<ResolveInfo> rInfos = mPm.queryIntentServicesAsUser(new Intent(mAction),
PackageManager.GET_META_DATA); PackageManager.GET_META_DATA, mCurrentUserId);
int bestVersion = Integer.MIN_VALUE; int bestVersion = Integer.MIN_VALUE;
String bestPackage = null; String bestPackage = null;
for (ResolveInfo rInfo : rInfos) { for (ResolveInfo rInfo : rInfos) {
@ -141,36 +146,32 @@ public class ServiceWatcher implements ServiceConnection {
(bestPackage == null ? "no new best package" : "new best packge: " + bestPackage))); (bestPackage == null ? "no new best package" : "new best packge: " + bestPackage)));
if (bestPackage != null) { if (bestPackage != null) {
bindToPackage(bestPackage, bestVersion); bindToPackageLocked(bestPackage, bestVersion);
return true; return true;
} }
return false; return false;
} }
private void unbind() { private void unbindLocked() {
String pkg; String pkg;
synchronized (mLock) { pkg = mPackageName;
pkg = mPackageName; mPackageName = null;
mPackageName = null; mVersion = Integer.MIN_VALUE;
mVersion = Integer.MIN_VALUE;
}
if (pkg != null) { if (pkg != null) {
if (D) Log.d(mTag, "unbinding " + pkg); if (D) Log.d(mTag, "unbinding " + pkg);
mContext.unbindService(this); mContext.unbindService(this);
} }
} }
private void bindToPackage(String packageName, int version) { private void bindToPackageLocked(String packageName, int version) {
unbind(); unbindLocked();
Intent intent = new Intent(mAction); Intent intent = new Intent(mAction);
intent.setPackage(packageName); intent.setPackage(packageName);
synchronized (mLock) { mPackageName = packageName;
mPackageName = packageName; mVersion = version;
mVersion = version;
}
if (D) Log.d(mTag, "binding " + packageName + " (version " + version + ")"); if (D) Log.d(mTag, "binding " + packageName + " (version " + version + ")");
mContext.bindService(intent, this, Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND mContext.bindService(intent, this, Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
| Context.BIND_ALLOW_OOM_MANAGEMENT | Context.BIND_NOT_VISIBLE); | Context.BIND_ALLOW_OOM_MANAGEMENT | Context.BIND_NOT_VISIBLE, mCurrentUserId);
} }
private boolean isSignatureMatch(Signature[] signatures) { private boolean isSignatureMatch(Signature[] signatures) {
@ -197,31 +198,37 @@ public class ServiceWatcher implements ServiceConnection {
*/ */
@Override @Override
public void onPackageUpdateFinished(String packageName, int uid) { public void onPackageUpdateFinished(String packageName, int uid) {
if (packageName.equals(mPackageName)) { synchronized (mLock) {
// package updated, make sure to rebind if (packageName.equals(mPackageName)) {
unbind(); // package updated, make sure to rebind
unbindLocked();
}
// check the updated package in case it is better
bindBestPackageLocked(packageName);
} }
// check the updated package in case it is better
bindBestPackage(packageName);
} }
@Override @Override
public void onPackageAdded(String packageName, int uid) { public void onPackageAdded(String packageName, int uid) {
if (packageName.equals(mPackageName)) { synchronized (mLock) {
// package updated, make sure to rebind if (packageName.equals(mPackageName)) {
unbind(); // package updated, make sure to rebind
unbindLocked();
}
// check the new package is case it is better
bindBestPackageLocked(packageName);
} }
// check the new package is case it is better
bindBestPackage(packageName);
} }
@Override @Override
public void onPackageRemoved(String packageName, int uid) { public void onPackageRemoved(String packageName, int uid) {
if (packageName.equals(mPackageName)) { synchronized (mLock) {
unbind(); if (packageName.equals(mPackageName)) {
// the currently bound package was removed, unbindLocked();
// need to search for a new package // the currently bound package was removed,
bindBestPackage(null); // need to search for a new package
bindBestPackageLocked(null);
}
} }
} }
}; };
@ -271,4 +278,12 @@ public class ServiceWatcher implements ServiceConnection {
return mBinder; return mBinder;
} }
} }
public void switchUser(int userId) {
synchronized (mLock) {
unbindLocked();
mCurrentUserId = userId;
bindBestPackageLocked(null);
}
}
} }

View File

@ -21,6 +21,7 @@ import android.location.Address;
import android.location.GeocoderParams; import android.location.GeocoderParams;
import android.location.IGeocodeProvider; import android.location.IGeocodeProvider;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log; import android.util.Log;
import com.android.server.ServiceWatcher; import com.android.server.ServiceWatcher;
@ -38,8 +39,8 @@ public class GeocoderProxy {
private final ServiceWatcher mServiceWatcher; private final ServiceWatcher mServiceWatcher;
public static GeocoderProxy createAndBind(Context context, public static GeocoderProxy createAndBind(Context context,
List<String> initialPackageNames) { List<String> initialPackageNames, int userId) {
GeocoderProxy proxy = new GeocoderProxy(context, initialPackageNames); GeocoderProxy proxy = new GeocoderProxy(context, initialPackageNames, userId);
if (proxy.bind()) { if (proxy.bind()) {
return proxy; return proxy;
} else { } else {
@ -47,11 +48,11 @@ public class GeocoderProxy {
} }
} }
public GeocoderProxy(Context context, List<String> initialPackageNames) { public GeocoderProxy(Context context, List<String> initialPackageNames, int userId) {
mContext = context; mContext = context;
mServiceWatcher = new ServiceWatcher(mContext, TAG, SERVICE_ACTION, initialPackageNames, mServiceWatcher = new ServiceWatcher(mContext, TAG, SERVICE_ACTION, initialPackageNames,
null, null); null, null, userId);
} }
private boolean bind () { private boolean bind () {

View File

@ -783,6 +783,11 @@ public class GpsLocationProvider implements LocationProviderInterface {
sendMessage(SET_REQUEST, 0, new GpsRequest(request, source)); sendMessage(SET_REQUEST, 0, new GpsRequest(request, source));
} }
@Override
public void switchUser(int userId) {
// nothing to do here
}
private void handleSetRequest(ProviderRequest request, WorkSource source) { private void handleSetRequest(ProviderRequest request, WorkSource source) {
if (DEBUG) Log.d(TAG, "setRequest " + request); if (DEBUG) Log.d(TAG, "setRequest " + request);

View File

@ -38,6 +38,8 @@ public interface LocationProviderInterface {
public boolean isEnabled(); public boolean isEnabled();
public void setRequest(ProviderRequest request, WorkSource source); public void setRequest(ProviderRequest request, WorkSource source);
public void switchUser(int userId);
public void dump(FileDescriptor fd, PrintWriter pw, String[] args); public void dump(FileDescriptor fd, PrintWriter pw, String[] args);
// --- deprecated (but still supported) --- // --- deprecated (but still supported) ---

View File

@ -25,6 +25,7 @@ import android.location.LocationProvider;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.UserHandle;
import android.os.WorkSource; import android.os.WorkSource;
import android.util.Log; import android.util.Log;
@ -54,9 +55,9 @@ public class LocationProviderProxy implements LocationProviderInterface {
private WorkSource mWorksource = new WorkSource(); private WorkSource mWorksource = new WorkSource();
public static LocationProviderProxy createAndBind(Context context, String name, String action, public static LocationProviderProxy createAndBind(Context context, String name, String action,
List<String> initialPackageNames, Handler handler) { List<String> initialPackageNames, Handler handler, int userId) {
LocationProviderProxy proxy = new LocationProviderProxy(context, name, action, LocationProviderProxy proxy = new LocationProviderProxy(context, name, action,
initialPackageNames, handler); initialPackageNames, handler, userId);
if (proxy.bind()) { if (proxy.bind()) {
return proxy; return proxy;
} else { } else {
@ -65,11 +66,11 @@ public class LocationProviderProxy implements LocationProviderInterface {
} }
private LocationProviderProxy(Context context, String name, String action, private LocationProviderProxy(Context context, String name, String action,
List<String> initialPackageNames, Handler handler) { List<String> initialPackageNames, Handler handler, int userId) {
mContext = context; mContext = context;
mName = name; mName = name;
mServiceWatcher = new ServiceWatcher(mContext, TAG, action, initialPackageNames, mServiceWatcher = new ServiceWatcher(mContext, TAG, action, initialPackageNames,
mNewServiceWork, handler); mNewServiceWork, handler, userId);
} }
private boolean bind () { private boolean bind () {
@ -210,6 +211,11 @@ public class LocationProviderProxy implements LocationProviderInterface {
} }
} }
@Override
public void switchUser(int userId) {
mServiceWatcher.switchUser(userId);
}
@Override @Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.append("REMOTE SERVICE"); pw.append("REMOTE SERVICE");

View File

@ -155,6 +155,11 @@ public class MockProvider implements LocationProviderInterface {
@Override @Override
public void setRequest(ProviderRequest request, WorkSource source) { } public void setRequest(ProviderRequest request, WorkSource source) { }
@Override
public void switchUser(int userId) {
// nothing to do here
}
@Override @Override
public boolean sendExtraCommand(String command, Bundle extras) { public boolean sendExtraCommand(String command, Bundle extras) {
return false; return false;

View File

@ -96,6 +96,11 @@ public class PassiveProvider implements LocationProviderInterface {
mReportLocation = request.reportLocation; mReportLocation = request.reportLocation;
} }
@Override
public void switchUser(int userId) {
// nothing to do here
}
public void updateLocation(Location location) { public void updateLocation(Location location) {
if (mReportLocation) { if (mReportLocation) {
try { try {