Add smart battery page for battery settings

This page contains prefs for smart battery and app restriction.

Bug: 71502850
Test: RunSettingsRoboTests

Change-Id: I194af30cbc7b2496b10098fcb67f1116e0722310
This commit is contained in:
jackqdyulei
2018-01-05 14:33:38 -08:00
parent 87f7a1be1e
commit 131d3b3c2f
9 changed files with 391 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 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.
-->
<!-- Entity header -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/entity_header"
style="@style/EntityHeader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="200dp"
android:paddingBottom="32dp"
android:paddingStart="@dimen/preference_no_icon_padding_start"
android:paddingTop="24dp">
</LinearLayout>

View File

@@ -4773,6 +4773,19 @@
<string name="battery_tip_low_battery_title">Low battery capacity</string> <string name="battery_tip_low_battery_title">Low battery capacity</string>
<!-- Summary for the low battery tip [CHAR LIMIT=NONE] --> <!-- Summary for the low battery tip [CHAR LIMIT=NONE] -->
<string name="battery_tip_low_battery_summary">Battery can\'t provide good battery life</string> <string name="battery_tip_low_battery_summary">Battery can\'t provide good battery life</string>
<!-- Title for the smart battery manager preference [CHAR LIMIT=NONE] -->
<string name="smart_battery_manager_title">Smart battery manager</string>
<!-- Title for the smart battery toggle [CHAR LIMIT=NONE] -->
<string name="smart_battery_title">Auto-manage battery</string>
<!-- Summary for the smart battery toggle [CHAR LIMIT=NONE] -->
<string name="smart_battery_summary">Automatically adjust power usage by apps based on usage</string>
<!-- Title for restricted app preference, clicking it will goes to restricted app list [CHAR LIMIT=NONE] -->
<string name="restricted_app_title">Restricted apps</string>
<!-- Summary for restricted app preference, clicking it will goes to restricted app list [CHAR LIMIT=NONE] -->
<plurals name="restricted_app_summary">
<item quantity="one">%1$d app</item>
<item quantity="other">%1$d apps</item>
</plurals>
<!-- Title for force stop dialog [CHAR LIMIT=30] --> <!-- Title for force stop dialog [CHAR LIMIT=30] -->
<string name="dialog_stop_title">Stop app?</string> <string name="dialog_stop_title">Stop app?</string>

View File

@@ -38,6 +38,11 @@
android:key="battery_saver_summary" android:key="battery_saver_summary"
android:title="@string/battery_saver"/> android:title="@string/battery_saver"/>
<Preference
android:fragment="com.android.settings.fuelgauge.SmartBatterySettings"
android:key="smart_battery_manager"
android:title="@string/smart_battery_manager_title"/>
<SwitchPreference <SwitchPreference
android:key="battery_percentage" android:key="battery_percentage"
android:title="@string/battery_percentage" android:title="@string/battery_percentage"

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/smart_battery_manager_title">
<!-- TODO(b/71722498): Add header back, otherwise also remove smart_battery_header
<com.android.settings.applications.LayoutPreference
android:key="header_view"
android:layout="@layout/smart_battery_header"
android:selectable="false"
android:order="-10000"/>
-->
<SwitchPreference
android:key="smart_battery"
android:title="@string/smart_battery_title"
android:summary="@string/smart_battery_summary"/>
<Preference
android:key="restricted_app"
android:title="@string/restricted_app_title"/>
</PreferenceScreen>

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2018 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.settings.fuelgauge;
import android.app.AppOpsManager;
import android.content.Context;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import com.android.settings.R;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.core.BasePreferenceController;
import java.util.List;
/**
* Controller to change and update the smart battery toggle
*/
public class RestrictAppPreferenceController extends BasePreferenceController {
@VisibleForTesting
static final String KEY_RESTRICT_APP = "restricted_app";
private AppOpsManager mAppOpsManager;
private List<AppOpsManager.PackageOps> mPackageOps;
public RestrictAppPreferenceController(Context context) {
super(context, KEY_RESTRICT_APP);
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
mPackageOps = mAppOpsManager.getPackagesForOps(
new int[]{AppOpsManager.OP_RUN_ANY_IN_BACKGROUND});
final int num = mPackageOps != null ? mPackageOps.size() : 0;
preference.setSummary(
mContext.getResources().getQuantityString(R.plurals.restricted_app_summary, num,
num));
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2018 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.settings.fuelgauge;
import android.content.Context;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.core.BasePreferenceController;
/**
* Controller to change and update the smart battery toggle
*/
public class SmartBatteryPreferenceController extends BasePreferenceController implements
Preference.OnPreferenceChangeListener {
private static final String KEY_SMART_BATTERY = "smart_battery";
public SmartBatteryPreferenceController(Context context) {
super(context, KEY_SMART_BATTERY);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean smartBatteryOn = (Boolean) newValue;
//TODO(b/71502850): use smart battery API here to update the state
return true;
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright (C) 2018 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.settings.fuelgauge;
import android.content.Context;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.widget.FooterPreferenceMixin;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Fragment to show smart battery and restricted app controls
*/
public class SmartBatterySettings extends DashboardFragment {
public static final String TAG = "SmartBatterySettings";
private final FooterPreferenceMixin mFooterPreferenceMixin =
new FooterPreferenceMixin(this, getLifecycle());
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mFooterPreferenceMixin.createFooterPreference().setTitle(R.string.battery_footer_summary);
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.FUELGAUGE_SMART_BATTERY;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.smart_battery_detail;
}
@Override
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
return buildPreferenceControllers(context);
}
private static List<AbstractPreferenceController> buildPreferenceControllers(
Context context) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new SmartBatteryPreferenceController(context));
controllers.add(new RestrictAppPreferenceController(context));
return controllers;
}
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.smart_battery_detail;
return Arrays.asList(sir);
}
@Override
public List<String> getNonIndexableKeys(Context context) {
return super.getNonIndexableKeys(context);
}
@Override
public List<AbstractPreferenceController> getPreferenceControllers(
Context context) {
return buildPreferenceControllers(context);
}
};
}

View File

@@ -50,6 +50,7 @@ import com.android.settings.enterprise.EnterprisePrivacySettings;
import com.android.settings.fuelgauge.BatterySaverSettings; import com.android.settings.fuelgauge.BatterySaverSettings;
import com.android.settings.fuelgauge.PowerUsageAdvanced; import com.android.settings.fuelgauge.PowerUsageAdvanced;
import com.android.settings.fuelgauge.PowerUsageSummary; import com.android.settings.fuelgauge.PowerUsageSummary;
import com.android.settings.fuelgauge.SmartBatterySettings;
import com.android.settings.gestures.AssistGestureSettings; import com.android.settings.gestures.AssistGestureSettings;
import com.android.settings.gestures.DoubleTapPowerSettings; import com.android.settings.gestures.DoubleTapPowerSettings;
import com.android.settings.gestures.DoubleTapScreenSettings; import com.android.settings.gestures.DoubleTapScreenSettings;
@@ -174,6 +175,7 @@ public final class SearchIndexableResources {
addIndex(ZenModeBehaviorSettings.class); addIndex(ZenModeBehaviorSettings.class);
addIndex(ZenModeAutomationSettings.class); addIndex(ZenModeAutomationSettings.class);
addIndex(NightDisplaySettings.class); addIndex(NightDisplaySettings.class);
addIndex(SmartBatterySettings.class);
} }
private SearchIndexableResources() { private SearchIndexableResources() {

View File

@@ -0,0 +1,88 @@
/*
* Copyright (C) 2018 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.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import android.app.AppOpsManager;
import android.content.Context;
import android.support.v7.preference.Preference;
import com.android.settings.TestConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class RestrictAppPreferenceControllerTest {
@Mock
private AppOpsManager mAppOpsManager;
@Mock
private AppOpsManager.PackageOps mPackageOps;
private List<AppOpsManager.PackageOps> mPackageOpsList;
private RestrictAppPreferenceController mRestrictAppPreferenceController;
private Preference mPreference;
private Context mContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
doReturn(mAppOpsManager).when(mContext).getSystemService(Context.APP_OPS_SERVICE);
mRestrictAppPreferenceController = new RestrictAppPreferenceController(mContext);
mPackageOpsList = new ArrayList<>();
mPreference = new Preference(mContext);
}
@Test
public void testUpdateState_oneApp_showCorrectSummary() {
mPackageOpsList.add(mPackageOps);
doReturn(mPackageOpsList).when(mAppOpsManager).getPackagesForOps(any());
mRestrictAppPreferenceController.updateState(mPreference);
assertThat(mPreference.getSummary()).isEqualTo("1 app");
}
@Test
public void testUpdateState_twoApps_showCorrectSummary() {
mPackageOpsList.add(mPackageOps);
mPackageOpsList.add(mPackageOps);
doReturn(mPackageOpsList).when(mAppOpsManager).getPackagesForOps(any());
mRestrictAppPreferenceController.updateState(mPreference);
assertThat(mPreference.getSummary()).isEqualTo("2 apps");
}
}