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

Commit 0aa28602 authored by Victoria Lease's avatar Victoria Lease
Browse files

break up LocationManagerService's WakeLock

This commit splits LocationManagerService's monolithic WakeLock into
per-LocationManagerService.Receiver WakeLocks, for better WorkSource
accounting. This should make it easier to debug location-related
power issues.

Change-Id: I0d2897c305a38099f9663dc1bc9354ce4bbe1077
parent 579c00ef
Loading
Loading
Loading
Loading
+23 −55
Original line number Diff line number Diff line
@@ -135,8 +135,8 @@ public class LocationManagerService extends ILocationManager.Stub {
    // --- fields below are final after systemReady() ---
    private LocationFudger mLocationFudger;
    private GeofenceManager mGeofenceManager;
    private PowerManager.WakeLock mWakeLock;
    private PackageManager mPackageManager;
    private PowerManager mPowerManager;
    private GeocoderProxy mGeocodeProvider;
    private IGpsStatusProvider mGpsStatusProvider;
    private INetInitiatedListener mNetInitiatedListener;
@@ -144,9 +144,6 @@ public class LocationManagerService extends ILocationManager.Stub {
    private PassiveProvider mPassiveProvider;  // track passive provider for special cases
    private LocationBlacklist mBlacklist;

    // --- fields below are protected by mWakeLock ---
    private int mPendingBroadcasts;

    // --- fields below are protected by mLock ---
    // Set of providers that are explicitly enabled
    private final Set<String> mEnabledProviders = new HashSet<String>();
@@ -209,10 +206,8 @@ public class LocationManagerService extends ILocationManager.Stub {
            // fetch package manager
            mPackageManager = mContext.getPackageManager();

            // prepare wake lock
            PowerManager powerManager =
                    (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
            mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
            // fetch power manager
            mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);

            // prepare worker thread
            mLocationHandler = new LocationWorkerHandler(BackgroundThread.get().getLooper());
@@ -466,6 +461,7 @@ public class LocationManagerService extends ILocationManager.Stub {
        final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>();

        int mPendingBroadcasts;
        PowerManager.WakeLock mWakeLock;

        Receiver(ILocationListener listener, PendingIntent intent, int pid, int uid,
                String packageName) {
@@ -480,6 +476,10 @@ public class LocationManagerService extends ILocationManager.Stub {
            mUid = uid;
            mPid = pid;
            mPackageName = packageName;

            // construct/configure wakelock
            mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
            mWakeLock.setWorkSource(new WorkSource(mUid, mPackageName));
        }

        @Override
@@ -642,10 +642,7 @@ public class LocationManagerService extends ILocationManager.Stub {
                removeUpdatesLocked(this);
            }
            synchronized (this) {
                if (mPendingBroadcasts > 0) {
                    LocationManagerService.this.decrementPendingBroadcasts();
                    mPendingBroadcasts = 0;
                }
                clearPendingBroadcastsLocked();
            }
        }

@@ -661,13 +658,24 @@ public class LocationManagerService extends ILocationManager.Stub {
        // containing the sending of the broadcaset
        private void incrementPendingBroadcastsLocked() {
            if (mPendingBroadcasts++ == 0) {
                LocationManagerService.this.incrementPendingBroadcasts();
                mWakeLock.acquire();
            }
        }

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

        public void clearPendingBroadcastsLocked() {
            if (mPendingBroadcasts > 0) {
                mPendingBroadcasts = 0;
                if (mWakeLock.isHeld()) {
                    mWakeLock.release();
                }
            }
        }
    }
@@ -1349,10 +1357,7 @@ public class LocationManagerService extends ILocationManager.Stub {
        if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) {
            receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
            synchronized (receiver) {
                if (receiver.mPendingBroadcasts > 0) {
                    decrementPendingBroadcasts();
                    receiver.mPendingBroadcasts = 0;
                }
                receiver.clearPendingBroadcastsLocked();
            }
        }

@@ -1954,43 +1959,6 @@ public class LocationManagerService extends ILocationManager.Stub {
        }
    };

    // Wake locks

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

    private void decrementPendingBroadcasts() {
        synchronized (mWakeLock) {
            if (--mPendingBroadcasts == 0) {
                try {
                    // Release wake lock
                    if (mWakeLock.isHeld()) {
                        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.
                    Slog.e(TAG, "exception in releaseWakeLock()", e);
                }
            }
        }
    }

    // Geocoder

    @Override