Extreme battery saver: Disable location when screen is off.

Bug: 68769804
Test: manual test
Change-Id: Id93e250e5d189136dd267b21a3977ac95392c50b
This commit is contained in:
Makoto Onuki
2017-11-29 13:51:01 -08:00
parent ef1037390a
commit 2b186fa214
3 changed files with 140 additions and 6 deletions

View File

@@ -49,11 +49,21 @@ public class BatterySaverPolicy extends ContentObserver {
public static final boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE.
// Value of batterySaverGpsMode such that GPS isn't affected by battery saver mode.
/** Value of batterySaverGpsMode such that GPS isn't affected by battery saver mode. */
public static final int GPS_MODE_NO_CHANGE = 0;
// Value of batterySaverGpsMode such that GPS is disabled when battery saver mode
// is enabled and the screen is off.
/**
* Value of batterySaverGpsMode such that GPS is disabled when battery saver mode
* is enabled and the screen is off.
*/
public static final int GPS_MODE_DISABLED_WHEN_SCREEN_OFF = 1;
/**
* Value of batterySaverGpsMode such that location should be disabled altogether
* when battery saver mode is enabled and the screen is off.
*/
public static final int GPS_MODE_ALL_DISABLED_WHEN_SCREEN_OFF = 2;
// Secure setting for GPS behavior when battery saver mode is on.
public static final String SECURE_KEY_GPS_MODE = "batterySaverGpsMode";
@@ -344,7 +354,7 @@ public class BatterySaverPolicy extends ContentObserver {
// Get default value from Settings.Secure
final int defaultGpsMode = Settings.Secure.getInt(mContentResolver, SECURE_KEY_GPS_MODE,
GPS_MODE_NO_CHANGE);
GPS_MODE_ALL_DISABLED_WHEN_SCREEN_OFF);
mGpsMode = parser.getInt(KEY_GPS_MODE, defaultGpsMode);
// Non-device-specific parameters.
@@ -446,6 +456,12 @@ public class BatterySaverPolicy extends ContentObserver {
}
}
public int getGpsMode() {
synchronized (mLock) {
return mGpsMode;
}
}
public ArrayMap<String, String> getFileValues(boolean interactive) {
synchronized (mLock) {
return interactive ? mFilesForInteractive : mFilesForNoninteractive;

View File

@@ -84,6 +84,23 @@ public class BatterySaverController implements BatterySaverPolicyListener {
*/
private boolean mPreviouslyEnabled;
@GuardedBy("mLock")
private boolean mIsInteractive;
/**
* Read-only list of plugins. No need for synchronization.
*/
private final Plugin[] mPlugins;
/**
* Plugin interface. All methods are guaranteed to be called on the same (handler) thread.
*/
public interface Plugin {
void onSystemReady(BatterySaverController caller);
void onBatterySaverChanged(BatterySaverController caller);
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -109,6 +126,12 @@ public class BatterySaverController implements BatterySaverPolicyListener {
mBatterySaverPolicy = policy;
mBatterySaverPolicy.addListener(this);
mFileUpdater = new FileUpdater(context);
// Initialize plugins.
final ArrayList<Plugin> plugins = new ArrayList<>();
plugins.add(new BatterySaverLocationPlugin(mContext));
mPlugins = plugins.toArray(new Plugin[plugins.size()]);
}
/**
@@ -121,7 +144,7 @@ public class BatterySaverController implements BatterySaverPolicyListener {
}
/**
* Called by {@link PowerManagerService} on system ready..
* Called by {@link PowerManagerService} on system ready.
*/
public void systemReady() {
final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
@@ -130,6 +153,7 @@ public class BatterySaverController implements BatterySaverPolicyListener {
mFileUpdater.systemReady(LocalServices.getService(ActivityManagerInternal.class)
.isRuntimeRestarted());
mHandler.postSystemReady();
}
private PowerManager getPowerManager() {
@@ -154,6 +178,8 @@ public class BatterySaverController implements BatterySaverPolicyListener {
private static final int ARG_DONT_SEND_BROADCAST = 0;
private static final int ARG_SEND_BROADCAST = 1;
private static final int MSG_SYSTEM_READY = 2;
public MyHandler(Looper looper) {
super(looper);
}
@@ -163,12 +189,22 @@ public class BatterySaverController implements BatterySaverPolicyListener {
ARG_SEND_BROADCAST : ARG_DONT_SEND_BROADCAST, 0).sendToTarget();
}
public void postSystemReady() {
obtainMessage(MSG_SYSTEM_READY, 0, 0).sendToTarget();
}
@Override
public void dispatchMessage(Message msg) {
switch (msg.what) {
case MSG_STATE_CHANGED:
handleBatterySaverStateChanged(msg.arg1 == ARG_SEND_BROADCAST);
break;
case MSG_SYSTEM_READY:
for (Plugin p : mPlugins) {
p.onSystemReady(BatterySaverController.this);
}
break;
}
}
}
@@ -188,12 +224,24 @@ public class BatterySaverController implements BatterySaverPolicyListener {
}
/** @return whether battery saver is enabled or not. */
boolean isEnabled() {
public boolean isEnabled() {
synchronized (mLock) {
return mEnabled;
}
}
/** @return whether device is in interactive state. */
public boolean isInteractive() {
synchronized (mLock) {
return mIsInteractive;
}
}
/** @return Battery saver policy. */
public BatterySaverPolicy getBatterySaverPolicy() {
return mBatterySaverPolicy;
}
/**
* @return true if launch boost should currently be disabled.
*/
@@ -230,6 +278,7 @@ public class BatterySaverController implements BatterySaverPolicyListener {
listeners = mListeners.toArray(new LowPowerModeListener[mListeners.size()]);
enabled = mEnabled;
mIsInteractive = isInteractive;
if (enabled) {
@@ -250,6 +299,10 @@ public class BatterySaverController implements BatterySaverPolicyListener {
mFileUpdater.writeFiles(fileValues);
}
for (Plugin p : mPlugins) {
p.onBatterySaverChanged(this);
}
if (sendBroadcast) {
if (enabled) {
// STOPSHIP Remove the toast.

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.power.batterysaver;
import android.content.Context;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.util.Slog;
import com.android.server.power.BatterySaverPolicy;
import com.android.server.power.batterysaver.BatterySaverController.Plugin;
public class BatterySaverLocationPlugin implements Plugin {
private static final String TAG = "BatterySaverLocationPlugin";
private static final boolean DEBUG = BatterySaverController.DEBUG;
private final Context mContext;
public BatterySaverLocationPlugin(Context context) {
mContext = context;
}
@Override
public void onBatterySaverChanged(BatterySaverController caller) {
if (DEBUG) {
Slog.d(TAG, "onBatterySaverChanged");
}
updateLocationState(caller);
}
@Override
public void onSystemReady(BatterySaverController caller) {
if (DEBUG) {
Slog.d(TAG, "onSystemReady");
}
updateLocationState(caller);
}
private void updateLocationState(BatterySaverController caller) {
final boolean kill =
(caller.getBatterySaverPolicy().getGpsMode()
== BatterySaverPolicy.GPS_MODE_ALL_DISABLED_WHEN_SCREEN_OFF) &&
caller.isEnabled() && !caller.isInteractive();
if (DEBUG) {
Slog.d(TAG, "Battery saver " + (kill ? "stopping" : "restoring") + " location.");
}
Settings.Global.putInt(mContext.getContentResolver(),
Global.LOCATION_GLOBAL_KILL_SWITCH, kill ? 1 : 0);
}
}