Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f792fc59 authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change 1150 into donut

* changes:
  location: Location Manager wakelock cleanup
parents a6706b3c 0528b9b2
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -44,6 +44,4 @@ interface ILocationProvider {
    boolean sendExtraCommand(String command, inout Bundle extras);
    void addListener(int uid);
    void removeListener(int uid);
    void wakeLockAcquired();
    void wakeLockReleased();
}
+18 −6
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.net.ConnectivityManager;
import android.net.SntpClient;
import android.os.Bundle;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -207,6 +208,10 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
    private int mSuplDataConnectionState;
    private final ConnectivityManager mConnMgr;

    // Wakelocks
    private final static String WAKELOCK_KEY = "GpsLocationProvider";
    private final PowerManager.WakeLock mWakeLock;

    // Alarms
    private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
    private final AlarmManager mAlarmManager;
@@ -307,6 +312,10 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
        mContext = context;
        mLocationManager = locationManager;

        // Create a wake lock
        PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);

        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
        mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);

@@ -574,12 +583,6 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
        }
    }

    public void wakeLockAcquired() {
    }

    public void wakeLockReleased() {
    }

    public void addListener(int uid) {
        mClientUids.put(uid, 0);
        if (mNavigating) {
@@ -767,6 +770,10 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
        mNavigating = (status == GPS_STATUS_SESSION_BEGIN);

        if (wasNavigating != mNavigating) {
            if (mNavigating) {
                if (DEBUG) Log.d(TAG, "Acquiring wakelock");
                 mWakeLock.acquire();
            }
            synchronized(mListeners) {
                int size = mListeners.size();
                for (int i = 0; i < size; i++) {
@@ -804,6 +811,11 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
            Intent intent = new Intent(GPS_ENABLED_CHANGE_ACTION);
            intent.putExtra(EXTRA_ENABLED, mNavigating);
            mContext.sendBroadcast(intent);

            if (!mNavigating) {
                if (DEBUG) Log.d(TAG, "Releasing wakelock");
                mWakeLock.release();
            }
        }
    }

+0 −16
Original line number Diff line number Diff line
@@ -231,20 +231,4 @@ public class LocationProviderProxy {
            Log.e(TAG, "removeListener failed", e);
        }
    }

    public void wakeLockAcquired() {
        try {
            mProvider.wakeLockAcquired();
        } catch (RemoteException e) {
            Log.e(TAG, "wakeLockAcquired failed", e);
        }
    }

    public void wakeLockReleased() {
        try {
            mProvider.wakeLockReleased();
        } catch (RemoteException e) {
            Log.e(TAG, "wakeLockReleased failed", e);
        }
    }
}
+0 −6
Original line number Diff line number Diff line
@@ -182,12 +182,6 @@ public class MockProvider extends ILocationProvider.Stub {
    public void removeListener(int uid) {
    }

    public void wakeLockAcquired() {
    }

    public void wakeLockReleased() {
    }

    public void dump(PrintWriter pw, String prefix) {
        pw.println(prefix + mName);
        pw.println(prefix + "mHasLocation=" + mHasLocation);
+63 −216
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ import java.util.Observer;
import java.util.Set;
import java.util.regex.Pattern;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentQueryMap;
@@ -132,16 +131,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
    // Handler messages
    private static final int MESSAGE_LOCATION_CHANGED = 1;

    // Alarm manager and wakelock variables
    private final static String ALARM_INTENT = "com.android.location.ALARM_INTENT";
    // wakelock variables
    private final static String WAKELOCK_KEY = "LocationManagerService";
    private AlarmManager mAlarmManager;
    private long mAlarmInterval = 0;
    private PowerManager.WakeLock mWakeLock = null;
    private int mPendingBroadcasts;
    private long mWakeLockAcquireTime = 0;
    private boolean mWakeLockGpsReceived = true;
    private boolean mWakeLockNetworkReceived = true;
    
    /**
     * List of all receivers.
@@ -388,32 +381,35 @@ public class LocationManagerService extends ILocationManager.Stub implements Run

        public void onSendFinished(PendingIntent pendingIntent, Intent intent,
                int resultCode, String resultData, Bundle resultExtras) {
            decrementPendingBroadcasts();
            synchronized (this) {
                decrementPendingBroadcastsLocked();
            }
        }

        // this must be called while synchronized by caller in a synchronized block
        // containing the sending of the broadcaset
        private void incrementPendingBroadcastsLocked() {
            if (mPendingBroadcasts++ == 0) {
                synchronized (mLock) {
                    LocationManagerService.this.incrementPendingBroadcastsLocked();
                }
                LocationManagerService.this.incrementPendingBroadcasts();
            }
        }

        private void decrementPendingBroadcasts() {
            synchronized (this) {
        private void decrementPendingBroadcastsLocked() {
            if (--mPendingBroadcasts == 0) {
                LocationManagerService.this.decrementPendingBroadcasts();
            }
        }
    }
    }

    public void locationCallbackFinished(ILocationListener listener) {
        Receiver receiver = getReceiver(listener);
        if (receiver != null) {
            receiver.decrementPendingBroadcasts();
            synchronized (receiver) {
                // so wakelock calls will succeed
                long identity = Binder.clearCallingIdentity();
                receiver.decrementPendingBroadcastsLocked();
                Binder.restoreCallingIdentity(identity);
           }
        }
    }

@@ -526,15 +522,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
        mProvidersByName.remove(provider.getName());
    }

    /**
     * Load providers from /data/location/<provider_name>/
     *                                                          class
     *                                                          kml
     *                                                          nmea
     *                                                          track
     *                                                          location
     *                                                          properties
     */
    private void loadProviders() {
        synchronized (mLock) {
            if (sProvidersLoaded) {
@@ -585,9 +572,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
    }

    private void initialize() {
        // Alarm manager, needs to be done before calling loadProviders() below
        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);

        // Create a wake lock, needs to be done before calling loadProviders() below
        PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
@@ -596,19 +580,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
        loadProviders();

        // Register for Network (Wifi or Mobile) updates
        NetworkStateBroadcastReceiver networkReceiver = new NetworkStateBroadcastReceiver();
        IntentFilter networkIntentFilter = new IntentFilter();
        networkIntentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        networkIntentFilter.addAction(GpsLocationProvider.GPS_ENABLED_CHANGE_ACTION);
        mContext.registerReceiver(networkReceiver, networkIntentFilter);

        // Register for power updates
        PowerStateBroadcastReceiver powerStateReceiver = new PowerStateBroadcastReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ALARM_INTENT);
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        // Register for Package Manager updates
        intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        intentFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
        mContext.registerReceiver(powerStateReceiver, intentFilter);
        mContext.registerReceiver(mBroadcastReceiver, intentFilter);

        // listen for settings changes
        ContentResolver resolver = mContext.getContentResolver();
@@ -825,12 +802,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
            if (listeners > 0) {
                p.setMinTime(getMinTimeLocked(provider));
                p.enableLocationTracking(true);
                updateWakelockStatusLocked();
            }
        } else {
            p.enableLocationTracking(false);
            p.disable();
            updateWakelockStatusLocked();
        }
    }

@@ -1020,7 +995,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
                long minTimeForProvider = getMinTimeLocked(provider);
                proxy.setMinTime(minTimeForProvider);
                proxy.enableLocationTracking(true);
                updateWakelockStatusLocked();
            } else {
                // Notify the listener that updates are currently disabled
                receiver.callProviderEnabledLocked(provider, false);
@@ -1109,8 +1083,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
                    }
                }
            }

            updateWakelockStatusLocked();
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
@@ -1258,13 +1230,13 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
                        Intent enteredIntent = new Intent();
                        enteredIntent.putExtra(LocationManager.KEY_PROXIMITY_ENTERING, true);
                        try {
                            synchronized (mLock) {
                                // synchronize to ensure incrementPendingBroadcastsLocked()
                            synchronized (this) {
                                // synchronize to ensure incrementPendingBroadcasts()
                                // is called before decrementPendingBroadcasts()
                                intent.send(mContext, 0, enteredIntent, this, mLocationHandler);
                                // call this after broadcasting so we do not increment
                                // if we throw an exeption.
                                incrementPendingBroadcastsLocked();
                                incrementPendingBroadcasts();
                            }
                        } catch (PendingIntent.CanceledException e) {
                            if (LOCAL_LOGV) {
@@ -1283,13 +1255,13 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
                        Intent exitedIntent = new Intent();
                        exitedIntent.putExtra(LocationManager.KEY_PROXIMITY_ENTERING, false);
                        try {
                            synchronized (mLock) {
                                // synchronize to ensure incrementPendingBroadcastsLocked()
                            synchronized (this) {
                                // synchronize to ensure incrementPendingBroadcasts()
                                // is called before decrementPendingBroadcasts()
                                intent.send(mContext, 0, exitedIntent, this, mLocationHandler);
                                // call this after broadcasting so we do not increment
                                // if we throw an exeption.
                                incrementPendingBroadcastsLocked();
                                incrementPendingBroadcasts();
                            }
                        } catch (PendingIntent.CanceledException e) {
                            if (LOCAL_LOGV) {
@@ -1346,9 +1318,13 @@ public class LocationManagerService extends ILocationManager.Stub implements Run

        public void onSendFinished(PendingIntent pendingIntent, Intent intent,
                int resultCode, String resultData, Bundle resultExtras) {
            // synchronize to ensure incrementPendingBroadcasts()
            // is called before decrementPendingBroadcasts()
            synchronized (this) {
                decrementPendingBroadcasts();
            }
        }
    }

    public void addProximityAlert(double latitude, double longitude,
        float radius, long expiration, PendingIntent intent) {
@@ -1581,11 +1557,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
        }
        writeLastKnownLocationLocked(provider, location);

        if (LocationManager.NETWORK_PROVIDER.equals(p.getName())) {
            mWakeLockNetworkReceived = true;
        }
        // Gps location received signal is in NetworkStateBroadcastReceiver

        // Fetch latest status update time
        long newStatusUpdateTime = p.getStatusUpdateTime();

@@ -1668,7 +1639,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
                        }

                        handleLocationChangedLocked(location);
                        updateWakelockStatusLocked();
                    }
                }
            } catch (Exception e) {
@@ -1678,20 +1648,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
        }
    }

    private class PowerStateBroadcastReceiver extends BroadcastReceiver {
        @Override public void onReceive(Context context, Intent intent) {
    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (action.equals(ALARM_INTENT)) {
                synchronized (mLock) {
                    log("PowerStateBroadcastReceiver: Alarm received");
                    // Have to do this immediately, rather than posting a
                    // message, so we execute our code while the system
                    // is holding a wake lock until the alarm broadcast
                    // is finished.
                    acquireWakeLockLocked();
                }
            } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
            if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
                    || action.equals(Intent.ACTION_PACKAGE_RESTARTED)) {
                synchronized (mLock) {
                    int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
@@ -1733,15 +1695,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
                        }
                    }
                }
            }
        }
    }

    private class NetworkStateBroadcastReceiver extends BroadcastReceiver {
        @Override public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
            } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                boolean noConnectivity =
                    intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
                if (!noConnectivity) {
@@ -1759,146 +1713,43 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
                        }
                    }
                }
            } else if (action.equals(GpsLocationProvider.GPS_ENABLED_CHANGE_ACTION)) {

                final boolean enabled = intent.getBooleanExtra(GpsLocationProvider.EXTRA_ENABLED,
                    false);

                synchronized (mLock) {
                    if (!enabled) {
                        // When GPS is disabled, we are OK to release wake-lock
                        mWakeLockGpsReceived = true;
                    }
                }
            }

            }
        }
    };

    // Wake locks

    private void updateWakelockStatusLocked() {
        log("updateWakelockStatus()");

        long callerId = Binder.clearCallingIdentity();
        
        boolean needsLock = (mPendingBroadcasts > 0);
        long minTime = Integer.MAX_VALUE;

        if (mNetworkLocationProvider != null && mNetworkLocationProvider.isLocationTracking()) {
            needsLock = true;
            minTime = Math.min(mNetworkLocationProvider.getMinTime(), minTime);
        }

        if (mGpsLocationProvider != null && mGpsLocationProvider.isLocationTracking()) {
            needsLock = true;
            minTime = Math.min(mGpsLocationProvider.getMinTime(), minTime);
        }

        PendingIntent sender =
            PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_INTENT), 0);

        // Cancel existing alarm
        log("Cancelling existing alarm");
        mAlarmManager.cancel(sender);

        if (needsLock) {
            long now = SystemClock.elapsedRealtime();
            mAlarmManager.set(
                AlarmManager.ELAPSED_REALTIME_WAKEUP, now + minTime, sender);
            mAlarmInterval = minTime;
            log("Creating a new wakelock alarm with minTime = " + minTime);
        } else {
            log("No need for alarm");
            mAlarmInterval = -1;

            releaseWakeLockLocked();
        }
        Binder.restoreCallingIdentity(callerId);
    }

    private void acquireWakeLockLocked() {
    private void incrementPendingBroadcasts() {
        synchronized (mWakeLock) {
            if (mPendingBroadcasts++ == 0) {
                try {
            acquireWakeLockXLocked();
        } catch (Exception e) {
            // This is to catch a runtime exception thrown when we try to release an
            // already released lock.
            Log.e(TAG, "exception in acquireWakeLock()", e);
        }
    }

    private void acquireWakeLockXLocked() {
        if (mWakeLock.isHeld()) {
            log("Must release wakelock before acquiring");
            mWakeLockAcquireTime = 0;
            mWakeLock.release();
        }

        boolean networkActive = (mNetworkLocationProvider != null)
                && mNetworkLocationProvider.isLocationTracking();
        boolean gpsActive = (mGpsLocationProvider != null)
                && mGpsLocationProvider.isLocationTracking();

        boolean needsLock = networkActive || gpsActive;
        if (!needsLock) {
            log("No need for Lock!");
            return;
        }

        mWakeLockGpsReceived = !gpsActive;
        mWakeLockNetworkReceived = !networkActive;

        // Acquire wake lock
                    mWakeLock.acquire();
        mWakeLockAcquireTime = SystemClock.elapsedRealtime();
                    log("Acquired wakelock");

        if (mNetworkLocationProvider != null) {
            mNetworkLocationProvider.wakeLockAcquired();
        }
        if (mGpsLocationProvider != null) {
            mGpsLocationProvider.wakeLockAcquired();
        }
    }

    private void releaseWakeLockLocked() {
        try {
            releaseWakeLockXLocked();
                } catch (Exception e) {
                    // This is to catch a runtime exception thrown when we try to release an
                    // already released lock.
            Log.e(TAG, "exception in releaseWakeLock()", e);
                    Log.e(TAG, "exception in acquireWakeLock()", e);
                }
            }

    private void releaseWakeLockXLocked() {
        if (mNetworkLocationProvider != null) {
            mNetworkLocationProvider.wakeLockReleased();
        }
        if (mGpsLocationProvider != null) {
            mGpsLocationProvider.wakeLockReleased();
    }

    private void decrementPendingBroadcasts() {
        synchronized (mWakeLock) {
            if (--mPendingBroadcasts == 0) {
                try {
                    // Release wake lock
        mWakeLockAcquireTime = 0;
                    if (mWakeLock.isHeld()) {
            log("Released wakelock");
                        mWakeLock.release();
                        log("Released wakelock");
                    } else {
                        log("Can't release wakelock again!");
                    }
                } catch (Exception e) {
                    // This is to catch a runtime exception thrown when we try to release an
                    // already released lock.
                    Log.e(TAG, "exception in releaseWakeLock()", e);
                }

    private void incrementPendingBroadcastsLocked() {
        if (mPendingBroadcasts++ == 0) {
            updateWakelockStatusLocked();
        }
    }

    private void decrementPendingBroadcasts() {
        synchronized (mLock) {
            if (--mPendingBroadcasts == 0) {
                updateWakelockStatusLocked();
            }
        }
    }
@@ -2069,7 +1920,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
    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 AlarmManager from from pid="
            pw.println("Permission Denial: can't dump LocationManagerService from from pid="
                    + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid());
            return;
@@ -2081,10 +1932,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
            pw.println("  mGpsLocationProvider=" + mGpsLocationProvider);
            pw.println("  mNetworkLocationProvider=" + mNetworkLocationProvider);
            pw.println("  mCollector=" + mCollector);
            pw.println("  mAlarmInterval=" + mAlarmInterval
                    + " mWakeLockAcquireTime=" + mWakeLockAcquireTime);
            pw.println("  mWakeLockGpsReceived=" + mWakeLockGpsReceived
                    + " mWakeLockNetworkReceived=" + mWakeLockNetworkReceived);
            pw.println("  Listeners:");
            int N = mReceivers.size();
            for (int i=0; i<N; i++) {
Loading