use of com.android.server.location.LocationProviderInterface in project platform_frameworks_base by android.
the class LocationManagerService method addTestProvider.
@Override
public void addTestProvider(String name, ProviderProperties properties, String opPackageName) {
if (!canCallerAccessMockLocation(opPackageName)) {
return;
}
if (LocationManager.PASSIVE_PROVIDER.equals(name)) {
throw new IllegalArgumentException("Cannot mock the passive location provider");
}
long identity = Binder.clearCallingIdentity();
synchronized (mLock) {
// remove the real provider if we are replacing GPS or network provider
if (LocationManager.GPS_PROVIDER.equals(name) || LocationManager.NETWORK_PROVIDER.equals(name) || LocationManager.FUSED_PROVIDER.equals(name)) {
LocationProviderInterface p = mProvidersByName.get(name);
if (p != null) {
removeProviderLocked(p);
}
}
addTestProviderLocked(name, properties);
updateProvidersLocked();
}
Binder.restoreCallingIdentity(identity);
}
use of com.android.server.location.LocationProviderInterface in project platform_frameworks_base by android.
the class LocationManagerService method handleLocationChangedLocked.
private void handleLocationChangedLocked(Location location, boolean passive) {
if (D)
Log.d(TAG, "incoming location: " + location);
long now = SystemClock.elapsedRealtime();
String provider = (passive ? LocationManager.PASSIVE_PROVIDER : location.getProvider());
// Skip if the provider is unknown.
LocationProviderInterface p = mProvidersByName.get(provider);
if (p == null)
return;
// Update last known locations
Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION);
Location lastNoGPSLocation = null;
Location lastLocation = mLastLocation.get(provider);
if (lastLocation == null) {
lastLocation = new Location(provider);
mLastLocation.put(provider, lastLocation);
} else {
lastNoGPSLocation = lastLocation.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION);
if (noGPSLocation == null && lastNoGPSLocation != null) {
// New location has no no-GPS location: adopt last no-GPS location. This is set
// directly into location because we do not want to notify COARSE clients.
location.setExtraLocation(Location.EXTRA_NO_GPS_LOCATION, lastNoGPSLocation);
}
}
lastLocation.set(location);
// Update last known coarse interval location if enough time has passed.
Location lastLocationCoarseInterval = mLastLocationCoarseInterval.get(provider);
if (lastLocationCoarseInterval == null) {
lastLocationCoarseInterval = new Location(location);
mLastLocationCoarseInterval.put(provider, lastLocationCoarseInterval);
}
long timeDiffNanos = location.getElapsedRealtimeNanos() - lastLocationCoarseInterval.getElapsedRealtimeNanos();
if (timeDiffNanos > LocationFudger.FASTEST_INTERVAL_MS * NANOS_PER_MILLI) {
lastLocationCoarseInterval.set(location);
}
// Don't ever return a coarse location that is more recent than the allowed update
// interval (i.e. don't allow an app to keep registering and unregistering for
// location updates to overcome the minimum interval).
noGPSLocation = lastLocationCoarseInterval.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION);
// Skip if there are no UpdateRecords for this provider.
ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
if (records == null || records.size() == 0)
return;
// Fetch coarse location
Location coarseLocation = null;
if (noGPSLocation != null) {
coarseLocation = mLocationFudger.getOrCreate(noGPSLocation);
}
// Fetch latest status update time
long newStatusUpdateTime = p.getStatusUpdateTime();
// Get latest status
Bundle extras = new Bundle();
int status = p.getStatus(extras);
ArrayList<Receiver> deadReceivers = null;
ArrayList<UpdateRecord> deadUpdateRecords = null;
// Broadcast location or status to all listeners
for (UpdateRecord r : records) {
Receiver receiver = r.mReceiver;
boolean receiverDead = false;
int receiverUserId = UserHandle.getUserId(receiver.mUid);
if (!isCurrentProfile(receiverUserId) && !isUidALocationProvider(receiver.mUid)) {
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 (D)
Log.d(TAG, "skipping loc update for blacklisted app: " + receiver.mPackageName);
continue;
}
if (!reportLocationAccessNoThrow(receiver.mPid, receiver.mUid, receiver.mPackageName, receiver.mAllowedResolutionLevel)) {
if (D)
Log.d(TAG, "skipping loc update for no op app: " + receiver.mPackageName);
continue;
}
Location notifyLocation = null;
if (receiver.mAllowedResolutionLevel < RESOLUTION_LEVEL_FINE) {
// use coarse location
notifyLocation = coarseLocation;
} else {
// use fine location
notifyLocation = lastLocation;
}
if (notifyLocation != null) {
Location lastLoc = r.mLastFixBroadcast;
if ((lastLoc == null) || shouldBroadcastSafe(notifyLocation, lastLoc, r, now)) {
if (lastLoc == null) {
lastLoc = new Location(notifyLocation);
r.mLastFixBroadcast = lastLoc;
} else {
lastLoc.set(notifyLocation);
}
if (!receiver.callLocationChangedLocked(notifyLocation)) {
Slog.w(TAG, "RemoteException calling onLocationChanged on " + receiver);
receiverDead = true;
}
r.mRequest.decrementNumUpdates();
}
}
long prevStatusUpdateTime = r.mLastStatusBroadcast;
if ((newStatusUpdateTime > prevStatusUpdateTime) && (prevStatusUpdateTime != 0 || status != LocationProvider.AVAILABLE)) {
r.mLastStatusBroadcast = newStatusUpdateTime;
if (!receiver.callStatusChangedLocked(provider, status, extras)) {
receiverDead = true;
Slog.w(TAG, "RemoteException calling onStatusChanged on " + receiver);
}
}
// track expired records
if (r.mRequest.getNumUpdates() <= 0 || r.mRequest.getExpireAt() < now) {
if (deadUpdateRecords == null) {
deadUpdateRecords = new ArrayList<UpdateRecord>();
}
deadUpdateRecords.add(r);
}
// track dead receivers
if (receiverDead) {
if (deadReceivers == null) {
deadReceivers = new ArrayList<Receiver>();
}
if (!deadReceivers.contains(receiver)) {
deadReceivers.add(receiver);
}
}
}
// remove dead records and receivers outside the loop
if (deadReceivers != null) {
for (Receiver receiver : deadReceivers) {
removeUpdatesLocked(receiver);
}
}
if (deadUpdateRecords != null) {
for (UpdateRecord r : deadUpdateRecords) {
r.disposeLocked(true);
}
applyRequirementsLocked(provider);
}
}
use of com.android.server.location.LocationProviderInterface in project platform_frameworks_base by android.
the class LocationManagerService method switchUser.
/**
* Called when the device's active user changes.
* @param userId the new active user's UserId
*/
private void switchUser(int userId) {
if (mCurrentUserId == userId) {
return;
}
mBlacklist.switchUser(userId);
mLocationHandler.removeMessages(MSG_LOCATION_CHANGED);
synchronized (mLock) {
mLastLocation.clear();
mLastLocationCoarseInterval.clear();
for (LocationProviderInterface p : mProviders) {
updateProviderListenersLocked(p.getName(), false);
}
mCurrentUserId = userId;
updateUserProfiles(userId);
updateProvidersLocked();
}
}
use of com.android.server.location.LocationProviderInterface in project platform_frameworks_base by android.
the class LocationManagerService method dump.
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) {
pw.println("Permission Denial: can't dump LocationManagerService from from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
return;
}
synchronized (mLock) {
pw.println("Current Location Manager state:");
pw.println(" Location Listeners:");
for (Receiver receiver : mReceivers.values()) {
pw.println(" " + receiver);
}
pw.println(" Active Records by Provider:");
for (Map.Entry<String, ArrayList<UpdateRecord>> entry : mRecordsByProvider.entrySet()) {
pw.println(" " + entry.getKey() + ":");
for (UpdateRecord record : entry.getValue()) {
pw.println(" " + record);
}
}
pw.println(" Historical Records by Provider:");
for (Map.Entry<PackageProviderKey, PackageStatistics> entry : mRequestStatistics.statistics.entrySet()) {
PackageProviderKey key = entry.getKey();
PackageStatistics stats = entry.getValue();
pw.println(" " + key.packageName + ": " + key.providerName + ": " + stats);
}
pw.println(" Last Known Locations:");
for (Map.Entry<String, Location> entry : mLastLocation.entrySet()) {
String provider = entry.getKey();
Location location = entry.getValue();
pw.println(" " + provider + ": " + location);
}
pw.println(" Last Known Locations Coarse Intervals:");
for (Map.Entry<String, Location> entry : mLastLocationCoarseInterval.entrySet()) {
String provider = entry.getKey();
Location location = entry.getValue();
pw.println(" " + provider + ": " + location);
}
mGeofenceManager.dump(pw);
if (mEnabledProviders.size() > 0) {
pw.println(" Enabled Providers:");
for (String i : mEnabledProviders) {
pw.println(" " + i);
}
}
if (mDisabledProviders.size() > 0) {
pw.println(" Disabled Providers:");
for (String i : mDisabledProviders) {
pw.println(" " + i);
}
}
pw.append(" ");
mBlacklist.dump(pw);
if (mMockProviders.size() > 0) {
pw.println(" Mock Providers:");
for (Map.Entry<String, MockProvider> i : mMockProviders.entrySet()) {
i.getValue().dump(pw, " ");
}
}
pw.append(" fudger: ");
mLocationFudger.dump(fd, pw, args);
if (args.length > 0 && "short".equals(args[0])) {
return;
}
for (LocationProviderInterface provider : mProviders) {
pw.print(provider.getName() + " Internal State");
if (provider instanceof LocationProviderProxy) {
LocationProviderProxy proxy = (LocationProviderProxy) provider;
pw.print(" (" + proxy.getConnectedPackageName() + ")");
}
pw.println(":");
provider.dump(fd, pw, args);
}
}
}
use of com.android.server.location.LocationProviderInterface in project platform_frameworks_base by android.
the class LocationManagerService method shutdownComponents.
/**
* Provides a way for components held by the {@link LocationManagerService} to clean-up
* gracefully on system's shutdown.
*
* NOTES:
* 1) Only provides a chance to clean-up on an opt-in basis. This guarantees back-compat
* support for components that do not wish to handle such event.
*/
private void shutdownComponents() {
if (D)
Log.d(TAG, "Shutting down components...");
LocationProviderInterface gpsProvider = mProvidersByName.get(LocationManager.GPS_PROVIDER);
if (gpsProvider != null && gpsProvider.isEnabled()) {
gpsProvider.disable();
}
// avoids an exception to be thrown by the singleton factory method
if (FlpHardwareProvider.isSupported()) {
FlpHardwareProvider flpHardwareProvider = FlpHardwareProvider.getInstance(mContext);
flpHardwareProvider.cleanup();
}
}
Aggregations