Add high power whitelist for apps
- Strings not final! - New UX for power usage details (more preferency) - Add high power apps list shows on/off and screen to change (when possible) - Link from power usage summary to high power list - Link from advanced apps to high power list Bug: 19991702 Change-Id: I97c927ed82d3b89041e4429b427508545763d66c
This commit is contained in:
@@ -923,6 +923,15 @@
|
|||||||
android:value="true" />
|
android:value="true" />
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity android:name="Settings$HighPowerApplicationsActivity"
|
||||||
|
android:label="@string/high_power_apps"
|
||||||
|
android:taskAffinity="">
|
||||||
|
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
|
||||||
|
android:value="com.android.settings.applications.ManageApplications" />
|
||||||
|
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
|
||||||
|
android:value="true" />
|
||||||
|
</activity>
|
||||||
|
|
||||||
<!-- Keep compatibility with old shortcuts. -->
|
<!-- Keep compatibility with old shortcuts. -->
|
||||||
<activity-alias android:name=".applications.ManageApplications"
|
<activity-alias android:name=".applications.ManageApplications"
|
||||||
android:label="@string/applications_settings"
|
android:label="@string/applications_settings"
|
||||||
|
43
res/layout/horizontal_preference.xml
Normal file
43
res/layout/horizontal_preference.xml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2015 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingTop="3dp"
|
||||||
|
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||||
|
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@android:id/title"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@android:id/summary"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="end" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
@@ -1,54 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2009 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:paddingStart="4dip"
|
|
||||||
android:focusable="true"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingEnd="?android:attr/scrollbarSize">
|
|
||||||
|
|
||||||
<TextView android:id="@+id/summary"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="2dip"
|
|
||||||
android:paddingBottom="4dip"
|
|
||||||
android:ellipsize="marquee"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
<!-- Spacer -->
|
|
||||||
<View
|
|
||||||
android:id="@+id/buttons_spacer_left"
|
|
||||||
android:layout_width="0dip"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="0.7"
|
|
||||||
android:visibility="invisible" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/action_button"
|
|
||||||
android:layout_width="150dip"
|
|
||||||
android:paddingEnd="6dip"
|
|
||||||
android:layout_weight="0.3"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
@@ -1,48 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2009 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<!--Label for the item-->
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/label"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:ellipsize="middle"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_toStartOf="@+id/value"
|
|
||||||
android:layout_marginBottom="4dip"
|
|
||||||
android:layout_marginTop="4dip"
|
|
||||||
android:layout_marginEnd="4dip"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/value"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
|
||||||
android:textStyle="normal"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:layout_marginBottom="4dip"
|
|
||||||
android:layout_marginTop="4dip" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
@@ -1,111 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2009 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<ScrollView
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:clipToPadding="false"
|
|
||||||
android:scrollbarStyle="@integer/preference_scrollbar_style">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/all_details"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
|
||||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
|
||||||
android:paddingTop="5dip"
|
|
||||||
android:paddingBottom="5dip"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<include layout="@layout/app_percentage_item" />
|
|
||||||
|
|
||||||
<!-- Force stop and report buttons -->
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/two_buttons_panel"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingBottom="6dip"
|
|
||||||
android:orientation="vertical">
|
|
||||||
<include
|
|
||||||
layout="@layout/two_buttons_panel"/>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
style="?android:attr/listSeparatorTextViewStyle"
|
|
||||||
android:text="@string/details_subtitle" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/details"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingStart="6dip"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<!-- Insert detail items here -->
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/controls"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/controls_title"
|
|
||||||
style="?android:attr/listSeparatorTextViewStyle"
|
|
||||||
android:layout_marginTop="6dip"
|
|
||||||
android:text="@string/controls_subtitle" />
|
|
||||||
|
|
||||||
<!-- Controls go here ... -->
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/messages"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/messages_title"
|
|
||||||
style="?android:attr/listSeparatorTextViewStyle"
|
|
||||||
android:layout_marginTop="6dip" />
|
|
||||||
|
|
||||||
<!-- Messages go here ... -->
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/packages_section_title"
|
|
||||||
style="?android:attr/listSeparatorTextViewStyle"
|
|
||||||
android:layout_marginTop="6dip"
|
|
||||||
android:text="@string/packages_subtitle" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/packages_section"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingStart="6dip"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<!-- Insert detail items here -->
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
@@ -1,27 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2014 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/message"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="2dip"
|
|
||||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
|
||||||
android:paddingStart="4dip"
|
|
||||||
android:paddingEnd="?android:attr/scrollbarSize"
|
|
||||||
android:paddingBottom="4dip"
|
|
||||||
android:ellipsize="marquee"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
|
@@ -1,36 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2014 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:minHeight="@dimen/battery_history_chart_height">
|
|
||||||
|
|
||||||
<include layout="@layout/battery_history_chart" />
|
|
||||||
|
|
||||||
<TextView android:id="@+id/labelsHeader"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
|
||||||
android:textSize="14sp"
|
|
||||||
android:textColor="?android:attr/colorControlActivated"
|
|
||||||
android:gravity="start|center_vertical"
|
|
||||||
android:text="@string/power_usage_list_summary"
|
|
||||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
|
||||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
@@ -6642,4 +6642,31 @@
|
|||||||
<!-- Label for process [CHAR LIMIT=25] -->
|
<!-- Label for process [CHAR LIMIT=25] -->
|
||||||
<string name="process_format">Process <xliff:g id="count" example="3">%1$d</xliff:g></string>
|
<string name="process_format">Process <xliff:g id="count" example="3">%1$d</xliff:g></string>
|
||||||
|
|
||||||
|
<!-- Label for whether app is allowed to use a lot ef power [CHAR LIMIT=25]-->
|
||||||
|
<string name="high_power" translatable="false">High power</string>
|
||||||
|
|
||||||
|
<!-- List of apps that are allowed to use a lot of power [CHAR LIMIT=25]-->
|
||||||
|
<string name="high_power_apps" translatable="false">High power apps</string>
|
||||||
|
|
||||||
|
<!-- Summary of app allowed to use a lot of power [CHAR LIMIT=25] -->
|
||||||
|
<string name="high_power_on">On</string>
|
||||||
|
|
||||||
|
<!-- Summary of app not allowed to use a lot of power [CHAR LIMIT=25] -->
|
||||||
|
<string name="high_power_off">Off</string>
|
||||||
|
|
||||||
|
<!-- Description of high power switch [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="high_power_desc" translatable="false">High powered apps description text goes here. This is a placeholder.</string>
|
||||||
|
|
||||||
|
<!-- Description of number of apps with high power turned on [CHAR LIMIT=NONE] -->
|
||||||
|
<plurals name="high_power_count" translatable="false">
|
||||||
|
<item quantity="one">1 app is allowed to ignore restrictions like battery saver mode, sync etc.</item>
|
||||||
|
<item quantity="other"><xliff:g id="count" example="10">%d</xliff:g> apps is allowed to ignore restrictions like battery saver mode, sync etc.</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
|
<!-- Summary of power usage for an app [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="battery_summary" translatable="false"><xliff:g id="percentage" example="2">%1$d</xliff:g>%% use since last full charge</string>
|
||||||
|
|
||||||
|
<!-- Summary for app with no battery usage [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="no_battery_summary" translatable="false">No battery use since last full charge</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -25,12 +25,6 @@
|
|||||||
android:title="@string/default_apps_title"
|
android:title="@string/default_apps_title"
|
||||||
settings:keywords="@string/keywords_default_apps" />
|
settings:keywords="@string/keywords_default_apps" />
|
||||||
|
|
||||||
<PreferenceScreen
|
|
||||||
android:key="manage_perms"
|
|
||||||
android:fragment="com.android.settings.applications.ManagePermissions"
|
|
||||||
android:title="@string/app_permissions"
|
|
||||||
settings:keywords="@string/keywords_app_permissions" />
|
|
||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
android:key="domain_urls"
|
android:key="domain_urls"
|
||||||
android:title="@string/domain_urls_title"
|
android:title="@string/domain_urls_title"
|
||||||
@@ -40,4 +34,19 @@
|
|||||||
android:value="com.android.settings.Settings$DomainsURLsAppListActivity" />
|
android:value="com.android.settings.Settings$DomainsURLsAppListActivity" />
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|
||||||
|
<PreferenceScreen
|
||||||
|
android:key="manage_perms"
|
||||||
|
android:fragment="com.android.settings.applications.ManagePermissions"
|
||||||
|
android:title="@string/app_permissions"
|
||||||
|
settings:keywords="@string/keywords_app_permissions" />
|
||||||
|
|
||||||
|
<PreferenceScreen
|
||||||
|
android:key="high_power_apps"
|
||||||
|
android:title="@string/high_power_apps"
|
||||||
|
android:fragment="com.android.settings.applications.ManageApplications">
|
||||||
|
<extra
|
||||||
|
android:name="classname"
|
||||||
|
android:value="com.android.settings.Settings$HighPowerApplicationsActivity" />
|
||||||
|
</PreferenceScreen>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Copyright (C) 2009 The Android Open Source Project
|
<!-- Copyright (C) 2015 The Android Open Source Project
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -14,13 +14,16 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<TextView
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
|
||||||
android:id="@+id/label"
|
android:title="@string/high_power">
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
<SwitchPreference
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
android:key="high_power_switch"
|
||||||
android:singleLine="true"
|
android:title="@string/high_power" />
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_marginBottom="2dip"
|
<Preference
|
||||||
android:layout_marginTop="2dip" />
|
android:summary="@string/high_power_desc"
|
||||||
|
android:selectable="false" />
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
@@ -18,7 +18,8 @@
|
|||||||
android:title="@string/application_info_label">
|
android:title="@string/application_info_label">
|
||||||
<com.android.settings.applications.LayoutPreference
|
<com.android.settings.applications.LayoutPreference
|
||||||
android:key="header_view"
|
android:key="header_view"
|
||||||
android:layout="@layout/installed_app_details" />
|
android:layout="@layout/installed_app_details"
|
||||||
|
android:selectable="false" />
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
android:key="storage_settings"
|
android:key="storage_settings"
|
||||||
@@ -44,4 +45,10 @@
|
|||||||
android:key="preferred_settings"
|
android:key="preferred_settings"
|
||||||
android:title="@string/launch_by_default"
|
android:title="@string/launch_by_default"
|
||||||
android:selectable="true" />
|
android:selectable="true" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="battery"
|
||||||
|
android:title="@string/power_usage_summary_title"
|
||||||
|
android:selectable="true" />
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
47
res/xml/power_usage_details.xml
Normal file
47
res/xml/power_usage_details.xml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2015 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"
|
||||||
|
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
|
||||||
|
|
||||||
|
<com.android.settings.fuelgauge.BatteryHistoryPreference
|
||||||
|
android:key="battery_history" />
|
||||||
|
|
||||||
|
<com.android.settings.applications.LayoutPreference
|
||||||
|
android:key="two_buttons"
|
||||||
|
android:layout="@layout/two_buttons_panel"
|
||||||
|
android:selectable="false" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="high_power"
|
||||||
|
android:title="@string/high_power" />
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="details_parent"
|
||||||
|
android:title="@string/details_subtitle" />
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="controls_parent"
|
||||||
|
android:title="@string/controls_subtitle" />
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="messages_parent" />
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="packages_parent"
|
||||||
|
android:title="@string/packages_subtitle" />
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
@@ -17,6 +17,13 @@
|
|||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
|
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
|
||||||
android:title="@string/power_usage_summary_title"
|
android:title="@string/power_usage_summary_title"
|
||||||
settings:keywords="@string/keywords_battery"
|
settings:keywords="@string/keywords_battery">
|
||||||
android:key="app_list">
|
|
||||||
|
<com.android.settings.fuelgauge.BatteryHistoryPreference
|
||||||
|
android:key="battery_history" />
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="app_list"
|
||||||
|
android:title="@string/power_usage_list_summary" />
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
@@ -18,6 +18,7 @@ package com.android.settings;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.res.ColorStateList;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
@@ -29,6 +30,11 @@ public class AppHeader {
|
|||||||
|
|
||||||
public static void createAppHeader(final Activity activity, Drawable icon, CharSequence label,
|
public static void createAppHeader(final Activity activity, Drawable icon, CharSequence label,
|
||||||
final Intent settingsIntent) {
|
final Intent settingsIntent) {
|
||||||
|
createAppHeader(activity, icon, label, settingsIntent, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createAppHeader(final Activity activity, Drawable icon, CharSequence label,
|
||||||
|
final Intent settingsIntent, int tintColorRes) {
|
||||||
final View content = activity.findViewById(R.id.main_content);
|
final View content = activity.findViewById(R.id.main_content);
|
||||||
final ViewGroup contentParent = (ViewGroup) content.getParent();
|
final ViewGroup contentParent = (ViewGroup) content.getParent();
|
||||||
final View bar = activity.getLayoutInflater().inflate(R.layout.app_header,
|
final View bar = activity.getLayoutInflater().inflate(R.layout.app_header,
|
||||||
@@ -36,6 +42,9 @@ public class AppHeader {
|
|||||||
|
|
||||||
final ImageView appIcon = (ImageView) bar.findViewById(R.id.app_icon);
|
final ImageView appIcon = (ImageView) bar.findViewById(R.id.app_icon);
|
||||||
appIcon.setImageDrawable(icon);
|
appIcon.setImageDrawable(icon);
|
||||||
|
if (tintColorRes != 0) {
|
||||||
|
appIcon.setImageTintList(ColorStateList.valueOf(activity.getColor(tintColorRes)));
|
||||||
|
}
|
||||||
|
|
||||||
final TextView appName = (TextView) bar.findViewById(R.id.app_name);
|
final TextView appName = (TextView) bar.findViewById(R.id.app_name);
|
||||||
appName.setText(label);
|
appName.setText(label);
|
||||||
|
@@ -29,6 +29,8 @@ public abstract class InstrumentedFragment extends PreferenceFragment {
|
|||||||
public static final int VIEW_CATEGORY_DEFAULT_APPS = VIEW_CATEGORY_UNDECLARED + 1;
|
public static final int VIEW_CATEGORY_DEFAULT_APPS = VIEW_CATEGORY_UNDECLARED + 1;
|
||||||
public static final int VIEW_CATEGORY_STORAGE_APPS = VIEW_CATEGORY_UNDECLARED + 2;
|
public static final int VIEW_CATEGORY_STORAGE_APPS = VIEW_CATEGORY_UNDECLARED + 2;
|
||||||
public static final int VIEW_CATEGORY_USAGE_ACCESS_DETAIL = VIEW_CATEGORY_UNDECLARED + 3;
|
public static final int VIEW_CATEGORY_USAGE_ACCESS_DETAIL = VIEW_CATEGORY_UNDECLARED + 3;
|
||||||
|
public static final int VIEW_CATEGORY_HIGH_POWER_DETAILS = VIEW_CATEGORY_UNDECLARED + 4;
|
||||||
|
public static final int VIEW_CATEGORY_HIGH_POWER_APPS = VIEW_CATEGORY_UNDECLARED + 5;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare the view of this category.
|
* Declare the view of this category.
|
||||||
|
@@ -51,6 +51,7 @@ public class Settings extends SettingsActivity {
|
|||||||
public static class ApplicationSettingsActivity extends SettingsActivity { /* empty */ }
|
public static class ApplicationSettingsActivity extends SettingsActivity { /* empty */ }
|
||||||
public static class ManageApplicationsActivity extends SettingsActivity { /* empty */ }
|
public static class ManageApplicationsActivity extends SettingsActivity { /* empty */ }
|
||||||
public static class AllApplicationsActivity extends SettingsActivity { /* empty */ }
|
public static class AllApplicationsActivity extends SettingsActivity { /* empty */ }
|
||||||
|
public static class HighPowerApplicationsActivity extends SettingsActivity { /* empty */ }
|
||||||
public static class AppOpsSummaryActivity extends SettingsActivity {
|
public static class AppOpsSummaryActivity extends SettingsActivity {
|
||||||
@Override
|
@Override
|
||||||
public boolean isValidFragment(String className) {
|
public boolean isValidFragment(String className) {
|
||||||
|
@@ -89,6 +89,7 @@ import com.android.settings.deviceinfo.PublicVolumeSettings;
|
|||||||
import com.android.settings.deviceinfo.StorageSettings;
|
import com.android.settings.deviceinfo.StorageSettings;
|
||||||
import com.android.settings.deviceinfo.UsbSettings;
|
import com.android.settings.deviceinfo.UsbSettings;
|
||||||
import com.android.settings.fuelgauge.BatterySaverSettings;
|
import com.android.settings.fuelgauge.BatterySaverSettings;
|
||||||
|
import com.android.settings.fuelgauge.PowerUsageDetail;
|
||||||
import com.android.settings.fuelgauge.PowerUsageSummary;
|
import com.android.settings.fuelgauge.PowerUsageSummary;
|
||||||
import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
|
import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
|
||||||
import com.android.settings.inputmethod.KeyboardLayoutPickerFragment;
|
import com.android.settings.inputmethod.KeyboardLayoutPickerFragment;
|
||||||
@@ -347,6 +348,7 @@ public class SettingsActivity extends Activity
|
|||||||
ZenModeEventRuleSettings.class.getName(),
|
ZenModeEventRuleSettings.class.getName(),
|
||||||
ZenModeExternalRuleSettings.class.getName(),
|
ZenModeExternalRuleSettings.class.getName(),
|
||||||
ProcessStatsUi.class.getName(),
|
ProcessStatsUi.class.getName(),
|
||||||
|
PowerUsageDetail.class.getName(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -26,6 +26,7 @@ import com.android.settings.R;
|
|||||||
import com.android.settings.SettingsPreferenceFragment;
|
import com.android.settings.SettingsPreferenceFragment;
|
||||||
import com.android.settings.applications.ApplicationsState.AppEntry;
|
import com.android.settings.applications.ApplicationsState.AppEntry;
|
||||||
import com.android.settings.applications.ApplicationsState.Session;
|
import com.android.settings.applications.ApplicationsState.Session;
|
||||||
|
import com.android.settings.fuelgauge.PowerWhitelistBackend;
|
||||||
import com.android.settingslib.applications.PermissionsInfo;
|
import com.android.settingslib.applications.PermissionsInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -38,11 +39,13 @@ public class AdvancedAppSettings extends SettingsPreferenceFragment implements
|
|||||||
|
|
||||||
private static final String KEY_APP_PERM = "manage_perms";
|
private static final String KEY_APP_PERM = "manage_perms";
|
||||||
private static final String KEY_APP_DOMAIN_URLS = "domain_urls";
|
private static final String KEY_APP_DOMAIN_URLS = "domain_urls";
|
||||||
|
private static final String KEY_HIGH_POWER_APPS = "high_power_apps";
|
||||||
|
|
||||||
private ApplicationsState mApplicationsState;
|
private ApplicationsState mApplicationsState;
|
||||||
private Session mSession;
|
private Session mSession;
|
||||||
private Preference mAppPermsPreference;
|
private Preference mAppPermsPreference;
|
||||||
private Preference mAppDomainURLsPreference;
|
private Preference mAppDomainURLsPreference;
|
||||||
|
private Preference mHighPowerPreference;
|
||||||
private PermissionsInfo mPermissionsInfo;
|
private PermissionsInfo mPermissionsInfo;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -55,6 +58,7 @@ public class AdvancedAppSettings extends SettingsPreferenceFragment implements
|
|||||||
|
|
||||||
mAppPermsPreference = findPreference(KEY_APP_PERM);
|
mAppPermsPreference = findPreference(KEY_APP_PERM);
|
||||||
mAppDomainURLsPreference = findPreference(KEY_APP_DOMAIN_URLS);
|
mAppDomainURLsPreference = findPreference(KEY_APP_DOMAIN_URLS);
|
||||||
|
mHighPowerPreference = findPreference(KEY_HIGH_POWER_APPS);
|
||||||
updateUI();
|
updateUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,6 +74,10 @@ public class AdvancedAppSettings extends SettingsPreferenceFragment implements
|
|||||||
String summary = getResources().getQuantityString(
|
String summary = getResources().getQuantityString(
|
||||||
R.plurals.domain_urls_apps_summary, countAppWithDomainURLs, countAppWithDomainURLs);
|
R.plurals.domain_urls_apps_summary, countAppWithDomainURLs, countAppWithDomainURLs);
|
||||||
mAppDomainURLsPreference.setSummary(summary);
|
mAppDomainURLsPreference.setSummary(summary);
|
||||||
|
|
||||||
|
int highPowerCount = PowerWhitelistBackend.getInstance().getWhitelistSize();
|
||||||
|
mHighPowerPreference.setSummary(getResources().getQuantityString(R.plurals.high_power_count,
|
||||||
|
highPowerCount, highPowerCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -20,6 +20,7 @@ import android.app.Activity;
|
|||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.DialogFragment;
|
import android.app.DialogFragment;
|
||||||
|
import android.app.Fragment;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -36,6 +37,7 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.android.settings.InstrumentedPreferenceFragment;
|
import com.android.settings.InstrumentedPreferenceFragment;
|
||||||
import com.android.settings.SettingsActivity;
|
import com.android.settings.SettingsActivity;
|
||||||
|
import com.android.settings.Utils;
|
||||||
import com.android.settings.applications.ApplicationsState.AppEntry;
|
import com.android.settings.applications.ApplicationsState.AppEntry;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -194,6 +196,17 @@ public abstract class AppInfoBase extends InstrumentedPreferenceFragment
|
|||||||
refreshUi();
|
refreshUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void startAppInfoFragment(Class<? extends AppInfoBase> fragment, int titleRes,
|
||||||
|
String pkg, int uid, Fragment source, int request) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString(AppInfoBase.ARG_PACKAGE_NAME, pkg);
|
||||||
|
|
||||||
|
Intent intent = Utils.onBuildStartFragmentIntent(source.getActivity(), fragment.getName(),
|
||||||
|
args, null, titleRes, null, false);
|
||||||
|
source.getActivity().startActivityForResultAsUser(intent, request,
|
||||||
|
new UserHandle(UserHandle.getUserId(uid)));
|
||||||
|
}
|
||||||
|
|
||||||
public class MyAlertDialogFragment extends DialogFragment {
|
public class MyAlertDialogFragment extends DialogFragment {
|
||||||
public MyAlertDialogFragment(int id, int errorCode) {
|
public MyAlertDialogFragment(int id, int errorCode) {
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
|
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 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.applications;
|
||||||
|
|
||||||
|
import com.android.settings.applications.ApplicationsState.AppEntry;
|
||||||
|
import com.android.settings.applications.ApplicationsState.AppFilter;
|
||||||
|
import com.android.settings.fuelgauge.PowerWhitelistBackend;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects data from the PowerWhitelistBackend to ApplicationsState.
|
||||||
|
*/
|
||||||
|
public class AppStatePowerBridge extends AppStateBaseBridge {
|
||||||
|
|
||||||
|
private final PowerWhitelistBackend mBackend = PowerWhitelistBackend.getInstance();
|
||||||
|
|
||||||
|
public AppStatePowerBridge(ApplicationsState appState, Callback callback) {
|
||||||
|
super(appState, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void loadAllExtraInfo() {
|
||||||
|
ArrayList<AppEntry> apps = mAppSession.getAllApps();
|
||||||
|
final int N = apps.size();
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
AppEntry app = apps.get(i);
|
||||||
|
app.extraInfo = mBackend.isWhitelisted(app.info.packageName)
|
||||||
|
? Boolean.TRUE : Boolean.FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateExtraInfo(AppEntry app, String pkg, int uid) {
|
||||||
|
app.extraInfo = mBackend.isWhitelisted(pkg) ? Boolean.TRUE : Boolean.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class HighPowerState {
|
||||||
|
public boolean isHighPower;
|
||||||
|
public boolean isSystemHighPower;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final AppFilter FILTER_POWER_WHITELISTED = new AppFilter() {
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean filterApp(AppEntry info) {
|
||||||
|
return info.extraInfo == Boolean.TRUE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final AppFilter FILTER_POWER_NOT_WHITELISTED = new AppFilter() {
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean filterApp(AppEntry info) {
|
||||||
|
return info.extraInfo == Boolean.FALSE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@@ -38,6 +38,7 @@ import android.net.NetworkTemplate;
|
|||||||
import android.net.TrafficStats;
|
import android.net.TrafficStats;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
import android.os.BatteryStats;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
@@ -57,12 +58,16 @@ import android.widget.ImageView;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.internal.logging.MetricsLogger;
|
import com.android.internal.logging.MetricsLogger;
|
||||||
|
import com.android.internal.os.BatterySipper;
|
||||||
|
import com.android.internal.os.BatteryStatsHelper;
|
||||||
import com.android.settings.DataUsageSummary;
|
import com.android.settings.DataUsageSummary;
|
||||||
import com.android.settings.DataUsageSummary.AppItem;
|
import com.android.settings.DataUsageSummary.AppItem;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.SettingsActivity;
|
import com.android.settings.SettingsActivity;
|
||||||
import com.android.settings.Utils;
|
import com.android.settings.Utils;
|
||||||
import com.android.settings.applications.ApplicationsState.AppEntry;
|
import com.android.settings.applications.ApplicationsState.AppEntry;
|
||||||
|
import com.android.settings.fuelgauge.BatteryEntry;
|
||||||
|
import com.android.settings.fuelgauge.PowerUsageDetail;
|
||||||
import com.android.settings.net.ChartData;
|
import com.android.settings.net.ChartData;
|
||||||
import com.android.settings.net.ChartDataLoader;
|
import com.android.settings.net.ChartDataLoader;
|
||||||
import com.android.settings.notification.NotificationBackend;
|
import com.android.settings.notification.NotificationBackend;
|
||||||
@@ -108,6 +113,7 @@ public class InstalledAppDetails extends AppInfoBase
|
|||||||
private static final String KEY_PERMISSION = "permission_settings";
|
private static final String KEY_PERMISSION = "permission_settings";
|
||||||
private static final String KEY_DATA = "data_settings";
|
private static final String KEY_DATA = "data_settings";
|
||||||
private static final String KEY_LAUNCH = "preferred_settings";
|
private static final String KEY_LAUNCH = "preferred_settings";
|
||||||
|
private static final String KEY_BATTERY = "battery";
|
||||||
|
|
||||||
private final HashSet<String> mHomePackages = new HashSet<String>();
|
private final HashSet<String> mHomePackages = new HashSet<String>();
|
||||||
|
|
||||||
@@ -131,6 +137,11 @@ public class InstalledAppDetails extends AppInfoBase
|
|||||||
private ChartData mChartData;
|
private ChartData mChartData;
|
||||||
private INetworkStatsSession mStatsSession;
|
private INetworkStatsSession mStatsSession;
|
||||||
|
|
||||||
|
private Preference mBatteryPreference;
|
||||||
|
|
||||||
|
private BatteryStatsHelper mBatteryHelper;
|
||||||
|
private BatterySipper mSipper;
|
||||||
|
|
||||||
private boolean handleDisableable(Button button) {
|
private boolean handleDisableable(Button button) {
|
||||||
boolean disableable = false;
|
boolean disableable = false;
|
||||||
// Try to prevent the user from bricking their phone
|
// Try to prevent the user from bricking their phone
|
||||||
@@ -221,6 +232,7 @@ public class InstalledAppDetails extends AppInfoBase
|
|||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
mBatteryHelper = new BatteryStatsHelper(getActivity(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -236,6 +248,7 @@ public class InstalledAppDetails extends AppInfoBase
|
|||||||
getLoaderManager().restartLoader(LOADER_CHART_DATA,
|
getLoaderManager().restartLoader(LOADER_CHART_DATA,
|
||||||
ChartDataLoader.buildArgs(NetworkTemplate.buildTemplateMobileWildcard(), app),
|
ChartDataLoader.buildArgs(NetworkTemplate.buildTemplateMobileWildcard(), app),
|
||||||
mDataCallbacks);
|
mDataCallbacks);
|
||||||
|
new BatteryUpdater().execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -263,6 +276,9 @@ public class InstalledAppDetails extends AppInfoBase
|
|||||||
mPermissionsPreference.setOnPreferenceClickListener(this);
|
mPermissionsPreference.setOnPreferenceClickListener(this);
|
||||||
mDataPreference = findPreference(KEY_DATA);
|
mDataPreference = findPreference(KEY_DATA);
|
||||||
mDataPreference.setOnPreferenceClickListener(this);
|
mDataPreference.setOnPreferenceClickListener(this);
|
||||||
|
mBatteryPreference = findPreference(KEY_BATTERY);
|
||||||
|
mBatteryPreference.setEnabled(false);
|
||||||
|
mBatteryPreference.setOnPreferenceClickListener(this);
|
||||||
|
|
||||||
mLaunchPreference = findPreference(KEY_LAUNCH);
|
mLaunchPreference = findPreference(KEY_LAUNCH);
|
||||||
if ((mAppEntry.info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
|
if ((mAppEntry.info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
|
||||||
@@ -434,6 +450,8 @@ public class InstalledAppDetails extends AppInfoBase
|
|||||||
mBackend));
|
mBackend));
|
||||||
mDataPreference.setSummary(getDataSummary());
|
mDataPreference.setSummary(getDataSummary());
|
||||||
|
|
||||||
|
updateBattery();
|
||||||
|
|
||||||
if (!mInitialized) {
|
if (!mInitialized) {
|
||||||
// First time init: are we displaying an uninstalled app?
|
// First time init: are we displaying an uninstalled app?
|
||||||
mInitialized = true;
|
mInitialized = true;
|
||||||
@@ -459,6 +477,20 @@ public class InstalledAppDetails extends AppInfoBase
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateBattery() {
|
||||||
|
if (mSipper != null) {
|
||||||
|
mBatteryPreference.setEnabled(true);
|
||||||
|
int dischargeAmount = mBatteryHelper.getStats().getDischargeAmount(
|
||||||
|
BatteryStats.STATS_SINCE_CHARGED);
|
||||||
|
final int percentOfMax = (int) ((mSipper.totalPowerMah)
|
||||||
|
/ mBatteryHelper.getTotalPower() * dischargeAmount + .5f);
|
||||||
|
mBatteryPreference.setSummary(getString(R.string.battery_summary, percentOfMax));
|
||||||
|
} else {
|
||||||
|
mBatteryPreference.setEnabled(false);
|
||||||
|
mBatteryPreference.setSummary(getString(R.string.no_battery_summary));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private CharSequence getDataSummary() {
|
private CharSequence getDataSummary() {
|
||||||
if (mChartData != null) {
|
if (mChartData != null) {
|
||||||
long totalBytes = mChartData.detail.getTotalBytes();
|
long totalBytes = mChartData.detail.getTotalBytes();
|
||||||
@@ -656,6 +688,10 @@ public class InstalledAppDetails extends AppInfoBase
|
|||||||
SettingsActivity sa = (SettingsActivity) getActivity();
|
SettingsActivity sa = (SettingsActivity) getActivity();
|
||||||
sa.startPreferencePanel(DataUsageSummary.class.getName(), args, -1,
|
sa.startPreferencePanel(DataUsageSummary.class.getName(), args, -1,
|
||||||
getString(R.string.app_data_usage), this, SUB_INFO_FRAGMENT);
|
getString(R.string.app_data_usage), this, SUB_INFO_FRAGMENT);
|
||||||
|
} else if (preference == mBatteryPreference) {
|
||||||
|
BatteryEntry entry = new BatteryEntry(getActivity(), null, mUserManager, mSipper);
|
||||||
|
PowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
|
||||||
|
mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry, true);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -700,7 +736,31 @@ public class InstalledAppDetails extends AppInfoBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DisableChanger extends AsyncTask<Object, Object, Object> {
|
private class BatteryUpdater extends AsyncTask<Void, Void, Void> {
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground(Void... params) {
|
||||||
|
mBatteryHelper.create((Bundle) null);
|
||||||
|
mBatteryHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED,
|
||||||
|
mUserManager.getUserProfiles());
|
||||||
|
List<BatterySipper> usageList = mBatteryHelper.getUsageList();
|
||||||
|
final int N = usageList.size();
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
BatterySipper sipper = usageList.get(i);
|
||||||
|
if (sipper.getUid() == mPackageInfo.applicationInfo.uid) {
|
||||||
|
mSipper = sipper;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Void result) {
|
||||||
|
refreshUi();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DisableChanger extends AsyncTask<Object, Object, Object> {
|
||||||
final PackageManager mPm;
|
final PackageManager mPm;
|
||||||
final WeakReference<InstalledAppDetails> mActivity;
|
final WeakReference<InstalledAppDetails> mActivity;
|
||||||
final ApplicationInfo mInfo;
|
final ApplicationInfo mInfo;
|
||||||
|
@@ -45,7 +45,9 @@ public class LayoutPreference extends Preference {
|
|||||||
.inflate(layoutResource, null, false);
|
.inflate(layoutResource, null, false);
|
||||||
|
|
||||||
final ViewGroup allDetails = (ViewGroup) view.findViewById(R.id.all_details);
|
final ViewGroup allDetails = (ViewGroup) view.findViewById(R.id.all_details);
|
||||||
|
if (allDetails != null) {
|
||||||
Utils.forceCustomPadding(allDetails, true /* additive padding */);
|
Utils.forceCustomPadding(allDetails, true /* additive padding */);
|
||||||
|
}
|
||||||
mRootView = view;
|
mRootView = view;
|
||||||
setShouldDisableView(false);
|
setShouldDisableView(false);
|
||||||
}
|
}
|
||||||
|
@@ -55,6 +55,7 @@ import com.android.settings.InstrumentedFragment;
|
|||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.Settings.AllApplicationsActivity;
|
import com.android.settings.Settings.AllApplicationsActivity;
|
||||||
import com.android.settings.Settings.DomainsURLsAppListActivity;
|
import com.android.settings.Settings.DomainsURLsAppListActivity;
|
||||||
|
import com.android.settings.Settings.HighPowerApplicationsActivity;
|
||||||
import com.android.settings.Settings.NotificationAppListActivity;
|
import com.android.settings.Settings.NotificationAppListActivity;
|
||||||
import com.android.settings.Settings.StorageUseActivity;
|
import com.android.settings.Settings.StorageUseActivity;
|
||||||
import com.android.settings.Settings.UsageAccessSettingsActivity;
|
import com.android.settings.Settings.UsageAccessSettingsActivity;
|
||||||
@@ -65,6 +66,7 @@ import com.android.settings.applications.ApplicationsState.AppEntry;
|
|||||||
import com.android.settings.applications.ApplicationsState.AppFilter;
|
import com.android.settings.applications.ApplicationsState.AppFilter;
|
||||||
import com.android.settings.applications.ApplicationsState.CompoundFilter;
|
import com.android.settings.applications.ApplicationsState.CompoundFilter;
|
||||||
import com.android.settings.applications.ApplicationsState.VolumeFilter;
|
import com.android.settings.applications.ApplicationsState.VolumeFilter;
|
||||||
|
import com.android.settings.fuelgauge.HighPowerDetail;
|
||||||
import com.android.settings.notification.NotificationBackend;
|
import com.android.settings.notification.NotificationBackend;
|
||||||
import com.android.settings.notification.NotificationBackend.AppRow;
|
import com.android.settings.notification.NotificationBackend.AppRow;
|
||||||
|
|
||||||
@@ -117,6 +119,8 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
public static final int FILTER_APPS_WORK = 8;
|
public static final int FILTER_APPS_WORK = 8;
|
||||||
public static final int FILTER_APPS_WITH_DOMAIN_URLS = 9;
|
public static final int FILTER_APPS_WITH_DOMAIN_URLS = 9;
|
||||||
public static final int FILTER_APPS_USAGE_ACCESS = 10;
|
public static final int FILTER_APPS_USAGE_ACCESS = 10;
|
||||||
|
public static final int FILTER_APPS_POWER_WHITELIST = 11;
|
||||||
|
public static final int FILTER_APPS_POWER_NO_WHITELIST = 12;
|
||||||
|
|
||||||
// This is the string labels for the filter modes above, the order must be kept in sync.
|
// This is the string labels for the filter modes above, the order must be kept in sync.
|
||||||
public static final int[] FILTER_LABELS = new int[] {
|
public static final int[] FILTER_LABELS = new int[] {
|
||||||
@@ -131,6 +135,8 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
R.string.filter_work_apps, // Work
|
R.string.filter_work_apps, // Work
|
||||||
R.string.filter_with_domain_urls_apps, // Domain URLs
|
R.string.filter_with_domain_urls_apps, // Domain URLs
|
||||||
R.string.filter_all_apps, // Usage access screen, never displayed
|
R.string.filter_all_apps, // Usage access screen, never displayed
|
||||||
|
R.string.high_power_on, // High power whitelist, on
|
||||||
|
R.string.high_power_off, // High power whitelist, off
|
||||||
};
|
};
|
||||||
// This is the actual mapping to filters from FILTER_ constants above, the order must
|
// This is the actual mapping to filters from FILTER_ constants above, the order must
|
||||||
// be kept in sync.
|
// be kept in sync.
|
||||||
@@ -146,6 +152,8 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
ApplicationsState.FILTER_WORK, // Work
|
ApplicationsState.FILTER_WORK, // Work
|
||||||
ApplicationsState.FILTER_WITH_DOMAIN_URLS, // Apps with Domain URLs
|
ApplicationsState.FILTER_WITH_DOMAIN_URLS, // Apps with Domain URLs
|
||||||
AppStateUsageBridge.FILTER_APP_USAGE, // Apps with Domain URLs
|
AppStateUsageBridge.FILTER_APP_USAGE, // Apps with Domain URLs
|
||||||
|
AppStatePowerBridge.FILTER_POWER_WHITELISTED, // High power whitelist, on
|
||||||
|
AppStatePowerBridge.FILTER_POWER_NOT_WHITELISTED, // High power whitelist, off
|
||||||
};
|
};
|
||||||
|
|
||||||
// sort order
|
// sort order
|
||||||
@@ -185,6 +193,7 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
public static final int LIST_TYPE_DOMAINS_URLS = 2;
|
public static final int LIST_TYPE_DOMAINS_URLS = 2;
|
||||||
public static final int LIST_TYPE_STORAGE = 3;
|
public static final int LIST_TYPE_STORAGE = 3;
|
||||||
public static final int LIST_TYPE_USAGE_ACCESS = 4;
|
public static final int LIST_TYPE_USAGE_ACCESS = 4;
|
||||||
|
public static final int LIST_TYPE_HIGH_POWER = 5;
|
||||||
|
|
||||||
private View mRootView;
|
private View mRootView;
|
||||||
|
|
||||||
@@ -228,6 +237,8 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
} else if (className.equals(UsageAccessSettingsActivity.class.getName())) {
|
} else if (className.equals(UsageAccessSettingsActivity.class.getName())) {
|
||||||
mListType = LIST_TYPE_USAGE_ACCESS;
|
mListType = LIST_TYPE_USAGE_ACCESS;
|
||||||
getActivity().getActionBar().setTitle(R.string.usage_access_title);
|
getActivity().getActionBar().setTitle(R.string.usage_access_title);
|
||||||
|
} else if (className.equals(HighPowerApplicationsActivity.class.getName())) {
|
||||||
|
mListType = LIST_TYPE_HIGH_POWER;
|
||||||
} else {
|
} else {
|
||||||
mListType = LIST_TYPE_MAIN;
|
mListType = LIST_TYPE_MAIN;
|
||||||
}
|
}
|
||||||
@@ -310,6 +321,9 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
mFilterAdapter.enableFilter(FILTER_APPS_SENSITIVE);
|
mFilterAdapter.enableFilter(FILTER_APPS_SENSITIVE);
|
||||||
mFilterAdapter.enableFilter(FILTER_APPS_NO_PEEKING);
|
mFilterAdapter.enableFilter(FILTER_APPS_NO_PEEKING);
|
||||||
}
|
}
|
||||||
|
if (mListType == LIST_TYPE_HIGH_POWER) {
|
||||||
|
mFilterAdapter.enableFilter(FILTER_APPS_POWER_NO_WHITELIST);
|
||||||
|
}
|
||||||
if (mListType == LIST_TYPE_STORAGE) {
|
if (mListType == LIST_TYPE_STORAGE) {
|
||||||
mApplications.setOverrideFilter(new VolumeFilter(mVolumeUuid));
|
mApplications.setOverrideFilter(new VolumeFilter(mVolumeUuid));
|
||||||
}
|
}
|
||||||
@@ -325,12 +339,12 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
|
|
||||||
private int getDefaultFilter() {
|
private int getDefaultFilter() {
|
||||||
switch (mListType) {
|
switch (mListType) {
|
||||||
case LIST_TYPE_MAIN:
|
|
||||||
return FILTER_APPS_ALL;
|
|
||||||
case LIST_TYPE_DOMAINS_URLS:
|
case LIST_TYPE_DOMAINS_URLS:
|
||||||
return FILTER_APPS_WITH_DOMAIN_URLS;
|
return FILTER_APPS_WITH_DOMAIN_URLS;
|
||||||
case LIST_TYPE_USAGE_ACCESS:
|
case LIST_TYPE_USAGE_ACCESS:
|
||||||
return FILTER_APPS_USAGE_ACCESS;
|
return FILTER_APPS_USAGE_ACCESS;
|
||||||
|
case LIST_TYPE_HIGH_POWER:
|
||||||
|
return FILTER_APPS_POWER_WHITELIST;
|
||||||
default:
|
default:
|
||||||
return FILTER_APPS_ALL;
|
return FILTER_APPS_ALL;
|
||||||
}
|
}
|
||||||
@@ -349,6 +363,8 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
return InstrumentedFragment.VIEW_CATEGORY_STORAGE_APPS;
|
return InstrumentedFragment.VIEW_CATEGORY_STORAGE_APPS;
|
||||||
case LIST_TYPE_USAGE_ACCESS:
|
case LIST_TYPE_USAGE_ACCESS:
|
||||||
return MetricsLogger.USAGE_ACCESS;
|
return MetricsLogger.USAGE_ACCESS;
|
||||||
|
case LIST_TYPE_HIGH_POWER:
|
||||||
|
return InstrumentedFragment.VIEW_CATEGORY_HIGH_POWER_APPS;
|
||||||
default:
|
default:
|
||||||
return MetricsLogger.VIEW_UNKNOWN;
|
return MetricsLogger.VIEW_UNKNOWN;
|
||||||
}
|
}
|
||||||
@@ -426,6 +442,9 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
case LIST_TYPE_STORAGE:
|
case LIST_TYPE_STORAGE:
|
||||||
startAppInfoFragment(AppStorageSettings.class, R.string.storage_settings);
|
startAppInfoFragment(AppStorageSettings.class, R.string.storage_settings);
|
||||||
break;
|
break;
|
||||||
|
case LIST_TYPE_HIGH_POWER:
|
||||||
|
startAppInfoFragment(HighPowerDetail.class, R.string.high_power);
|
||||||
|
break;
|
||||||
// TODO: Figure out if there is a way where we can spin up the profile's settings
|
// TODO: Figure out if there is a way where we can spin up the profile's settings
|
||||||
// process ahead of time, to avoid a long load of data when user clicks on a managed app.
|
// process ahead of time, to avoid a long load of data when user clicks on a managed app.
|
||||||
// Maybe when they load the list of apps that contains managed profile apps.
|
// Maybe when they load the list of apps that contains managed profile apps.
|
||||||
@@ -436,13 +455,8 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startAppInfoFragment(Class<? extends AppInfoBase> fragment, int titleRes) {
|
private void startAppInfoFragment(Class<? extends AppInfoBase> fragment, int titleRes) {
|
||||||
Bundle args = new Bundle();
|
AppInfoBase.startAppInfoFragment(fragment, titleRes, mCurrentPkgName, mCurrentUid, this,
|
||||||
args.putString(AppInfoBase.ARG_PACKAGE_NAME, mCurrentPkgName);
|
INSTALLED_APP_DETAILS);
|
||||||
|
|
||||||
Intent intent = Utils.onBuildStartFragmentIntent(getActivity(), fragment.getName(), args,
|
|
||||||
null, titleRes, null, false);
|
|
||||||
getActivity().startActivityForResultAsUser(intent, INSTALLED_APP_DETAILS,
|
|
||||||
new UserHandle(UserHandle.getUserId(mCurrentUid)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -685,6 +699,8 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
mState, this, manageApplications.mNotifBackend);
|
mState, this, manageApplications.mNotifBackend);
|
||||||
} else if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) {
|
} else if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) {
|
||||||
mExtraInfoBridge = new AppStateUsageBridge(mContext, mState, this);
|
mExtraInfoBridge = new AppStateUsageBridge(mContext, mState, this);
|
||||||
|
} else if (mManageApplications.mListType == LIST_TYPE_HIGH_POWER) {
|
||||||
|
mExtraInfoBridge = new AppStatePowerBridge(mState, this);
|
||||||
} else {
|
} else {
|
||||||
mExtraInfoBridge = null;
|
mExtraInfoBridge = null;
|
||||||
}
|
}
|
||||||
@@ -994,6 +1010,10 @@ public class ManageApplications extends InstrumentedFragment
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LIST_TYPE_HIGH_POWER:
|
||||||
|
holder.summary.setText(HighPowerDetail.getSummary(mContext, holder.entry));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
holder.updateSizeText(mManageApplications.mInvalidSizeStr, mWhichSize);
|
holder.updateSizeText(mManageApplications.mInvalidSizeStr, mWhichSize);
|
||||||
break;
|
break;
|
||||||
|
@@ -19,10 +19,16 @@ package com.android.settings.fuelgauge;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.BatteryStats;
|
import android.os.BatteryStats;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
|
import android.preference.PreferenceScreen;
|
||||||
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import com.android.internal.os.BatteryStatsHelper;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.SettingsActivity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom preference for displaying power consumption as a bar and an icon on the left for the
|
* Custom preference for displaying power consumption as a bar and an icon on the left for the
|
||||||
@@ -31,38 +37,60 @@ import com.android.settings.R;
|
|||||||
*/
|
*/
|
||||||
public class BatteryHistoryPreference extends Preference {
|
public class BatteryHistoryPreference extends Preference {
|
||||||
|
|
||||||
final private BatteryStats mStats;
|
protected static final String BATTERY_HISTORY_FILE = "tmp_bat_history.bin";
|
||||||
final private Intent mBatteryBroadcast;
|
|
||||||
|
private BatteryStats mStats;
|
||||||
|
private Intent mBatteryBroadcast;
|
||||||
|
|
||||||
private boolean mHideLabels;
|
|
||||||
private View mLabelHeader;
|
|
||||||
private BatteryHistoryChart mChart;
|
private BatteryHistoryChart mChart;
|
||||||
|
private BatteryStatsHelper mHelper;
|
||||||
|
|
||||||
public BatteryHistoryPreference(Context context, BatteryStats stats, Intent batteryBroadcast) {
|
public BatteryHistoryPreference(Context context, AttributeSet attrs) {
|
||||||
super(context);
|
super(context, attrs);
|
||||||
setLayoutResource(R.layout.preference_batteryhistory);
|
}
|
||||||
mStats = stats;
|
|
||||||
mBatteryBroadcast = batteryBroadcast;
|
@Override
|
||||||
|
public void performClick(PreferenceScreen preferenceScreen) {
|
||||||
|
if (!isEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mHelper.storeStatsHistoryInFile(BATTERY_HISTORY_FILE);
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString(BatteryHistoryDetail.EXTRA_STATS, BATTERY_HISTORY_FILE);
|
||||||
|
args.putParcelable(BatteryHistoryDetail.EXTRA_BROADCAST,
|
||||||
|
mHelper.getBatteryBroadcast());
|
||||||
|
if (getContext() instanceof SettingsActivity) {
|
||||||
|
SettingsActivity sa = (SettingsActivity) getContext();
|
||||||
|
sa.startPreferencePanel(BatteryHistoryDetail.class.getName(), args,
|
||||||
|
R.string.history_details_title, null, null, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStats(BatteryStatsHelper batteryStats) {
|
||||||
|
// Clear out the chart to receive new data.
|
||||||
|
mChart = null;
|
||||||
|
mHelper = batteryStats;
|
||||||
|
mStats = batteryStats.getStats();
|
||||||
|
mBatteryBroadcast = batteryStats.getBatteryBroadcast();
|
||||||
|
if (getLayoutResource() != R.layout.battery_history_chart) {
|
||||||
|
// Now we should have some data, set the layout we want.
|
||||||
|
setLayoutResource(R.layout.battery_history_chart);
|
||||||
|
}
|
||||||
|
notifyChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
BatteryStats getStats() {
|
BatteryStats getStats() {
|
||||||
return mStats;
|
return mStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHideLabels(boolean hide) {
|
|
||||||
if (mHideLabels != hide) {
|
|
||||||
mHideLabels = hide;
|
|
||||||
if (mLabelHeader != null) {
|
|
||||||
mLabelHeader.setVisibility(hide ? View.GONE : View.VISIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onBindView(View view) {
|
protected void onBindView(View view) {
|
||||||
super.onBindView(view);
|
super.onBindView(view);
|
||||||
|
|
||||||
BatteryHistoryChart chart = (BatteryHistoryChart)view.findViewById(
|
if (mStats == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BatteryHistoryChart chart = (BatteryHistoryChart) view.findViewById(
|
||||||
R.id.battery_history_chart);
|
R.id.battery_history_chart);
|
||||||
if (mChart == null) {
|
if (mChart == null) {
|
||||||
// First time: use and initialize this chart.
|
// First time: use and initialize this chart.
|
||||||
@@ -71,15 +99,13 @@ public class BatteryHistoryPreference extends Preference {
|
|||||||
} else {
|
} else {
|
||||||
// All future times: forget the newly inflated chart, re-use the
|
// All future times: forget the newly inflated chart, re-use the
|
||||||
// already initialized chart from last time.
|
// already initialized chart from last time.
|
||||||
ViewGroup parent = (ViewGroup)chart.getParent();
|
ViewGroup parent = (ViewGroup) chart.getParent();
|
||||||
int index = parent.indexOfChild(chart);
|
int index = parent.indexOfChild(chart);
|
||||||
parent.removeViewAt(index);
|
parent.removeViewAt(index);
|
||||||
if (mChart.getParent() != null) {
|
if (mChart.getParent() != null) {
|
||||||
((ViewGroup)mChart.getParent()).removeView(mChart);
|
((ViewGroup) mChart.getParent()).removeView(mChart);
|
||||||
}
|
}
|
||||||
parent.addView(mChart, index);
|
parent.addView(mChart, index);
|
||||||
}
|
}
|
||||||
mLabelHeader = view.findViewById(R.id.labelsHeader);
|
|
||||||
mLabelHeader.setVisibility(mHideLabels ? View.GONE : View.VISIBLE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
84
src/com/android/settings/fuelgauge/HighPowerDetail.java
Normal file
84
src/com/android/settings/fuelgauge/HighPowerDetail.java
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 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.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.preference.Preference;
|
||||||
|
import android.preference.Preference.OnPreferenceChangeListener;
|
||||||
|
import android.preference.SwitchPreference;
|
||||||
|
|
||||||
|
import com.android.settings.InstrumentedFragment;
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.applications.AppInfoWithHeader;
|
||||||
|
import com.android.settings.applications.ApplicationsState.AppEntry;
|
||||||
|
|
||||||
|
public class HighPowerDetail extends AppInfoWithHeader implements OnPreferenceChangeListener {
|
||||||
|
|
||||||
|
private static final String KEY_HIGH_POWER_SWITCH = "high_power_switch";
|
||||||
|
|
||||||
|
private final PowerWhitelistBackend mBackend = PowerWhitelistBackend.getInstance();
|
||||||
|
|
||||||
|
private SwitchPreference mUsageSwitch;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
addPreferencesFromResource(R.xml.high_power_details);
|
||||||
|
mUsageSwitch = (SwitchPreference) findPreference(KEY_HIGH_POWER_SWITCH);
|
||||||
|
mUsageSwitch.setOnPreferenceChangeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean refreshUi() {
|
||||||
|
mUsageSwitch.setEnabled(!mBackend.isSysWhitelisted(mPackageName));
|
||||||
|
mUsageSwitch.setChecked(mBackend.isWhitelisted(mPackageName));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
if (newValue == Boolean.TRUE) {
|
||||||
|
mBackend.addApp(mPackageName);
|
||||||
|
} else {
|
||||||
|
mBackend.removeApp(mPackageName);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AlertDialog createDialog(int id, int errorCode) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getMetricsCategory() {
|
||||||
|
return InstrumentedFragment.VIEW_CATEGORY_HIGH_POWER_DETAILS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CharSequence getSummary(Context context, AppEntry entry) {
|
||||||
|
return getSummary(context, entry.info.packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CharSequence getSummary(Context context, String pkg) {
|
||||||
|
return context.getString(PowerWhitelistBackend.getInstance().isWhitelisted(pkg)
|
||||||
|
? R.string.high_power_on : R.string.high_power_off);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
172
src/com/android/settings/fuelgauge/PowerUsageBase.java
Normal file
172
src/com/android/settings/fuelgauge/PowerUsageBase.java
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 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.Activity;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.os.BatteryStats;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.UserManager;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import com.android.internal.os.BatteryStatsHelper;
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.SettingsPreferenceFragment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common base class for things that need to show the battery usage graph.
|
||||||
|
*/
|
||||||
|
public abstract class PowerUsageBase extends SettingsPreferenceFragment {
|
||||||
|
|
||||||
|
// +1 to allow ordering for PowerUsageSummary.
|
||||||
|
private static final int MENU_STATS_REFRESH = Menu.FIRST + 1;
|
||||||
|
|
||||||
|
protected BatteryStatsHelper mStatsHelper;
|
||||||
|
protected UserManager mUm;
|
||||||
|
|
||||||
|
private String mBatteryLevel;
|
||||||
|
private String mBatteryStatus;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Activity activity) {
|
||||||
|
super.onAttach(activity);
|
||||||
|
mUm = (UserManager) activity.getSystemService(Context.USER_SERVICE);
|
||||||
|
mStatsHelper = new BatteryStatsHelper(activity, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle icicle) {
|
||||||
|
super.onCreate(icicle);
|
||||||
|
mStatsHelper.create(icicle);
|
||||||
|
setHasOptionsMenu(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
mStatsHelper.clearStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
BatteryStatsHelper.dropFile(getActivity(), BatteryHistoryPreference.BATTERY_HISTORY_FILE);
|
||||||
|
updateBatteryStatus(getActivity().registerReceiver(mBatteryInfoReceiver,
|
||||||
|
new IntentFilter(Intent.ACTION_BATTERY_CHANGED)));
|
||||||
|
if (mHandler.hasMessages(MSG_REFRESH_STATS)) {
|
||||||
|
mHandler.removeMessages(MSG_REFRESH_STATS);
|
||||||
|
mStatsHelper.clearStats();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
getActivity().unregisterReceiver(mBatteryInfoReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
mHandler.removeMessages(MSG_REFRESH_STATS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if (getActivity().isChangingConfigurations()) {
|
||||||
|
mStatsHelper.storeState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
|
MenuItem refresh = menu.add(0, MENU_STATS_REFRESH, 0, R.string.menu_stats_refresh)
|
||||||
|
.setIcon(com.android.internal.R.drawable.ic_menu_refresh)
|
||||||
|
.setAlphabeticShortcut('r');
|
||||||
|
refresh.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM |
|
||||||
|
MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case MENU_STATS_REFRESH:
|
||||||
|
mStatsHelper.clearStats();
|
||||||
|
refreshStats();
|
||||||
|
mHandler.removeMessages(MSG_REFRESH_STATS);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void refreshStats() {
|
||||||
|
mStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, mUm.getUserProfiles());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updatePreference(BatteryHistoryPreference historyPref) {
|
||||||
|
historyPref.setStats(mStatsHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateBatteryStatus(Intent intent) {
|
||||||
|
if (intent != null) {
|
||||||
|
String batteryLevel = com.android.settings.Utils.getBatteryPercentage(intent);
|
||||||
|
String batteryStatus = com.android.settings.Utils.getBatteryStatus(getResources(),
|
||||||
|
intent);
|
||||||
|
if (!batteryLevel.equals(mBatteryLevel) || !batteryStatus.equals(mBatteryStatus)) {
|
||||||
|
mBatteryLevel = batteryLevel;
|
||||||
|
mBatteryStatus = batteryStatus;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static final int MSG_REFRESH_STATS = 100;
|
||||||
|
|
||||||
|
private final Handler mHandler = new Handler() {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case MSG_REFRESH_STATS:
|
||||||
|
mStatsHelper.clearStats();
|
||||||
|
refreshStats();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
String action = intent.getAction();
|
||||||
|
if (Intent.ACTION_BATTERY_CHANGED.equals(action)
|
||||||
|
&& updateBatteryStatus(intent)) {
|
||||||
|
if (!mHandler.hasMessages(MSG_REFRESH_STATS)) {
|
||||||
|
mHandler.sendEmptyMessageDelayed(MSG_REFRESH_STATS, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.android.settings.fuelgauge;
|
package com.android.settings.fuelgauge;
|
||||||
|
|
||||||
import static com.android.settings.Utils.prepareCustomPreferencesList;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.ApplicationErrorReport;
|
import android.app.ApplicationErrorReport;
|
||||||
@@ -30,33 +28,34 @@ import android.content.pm.ApplicationInfo;
|
|||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.BatteryStats;
|
import android.os.BatteryStats;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
import android.preference.Preference;
|
||||||
|
import android.preference.Preference.OnPreferenceClickListener;
|
||||||
|
import android.preference.PreferenceCategory;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.LayoutInflater;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.ProgressBar;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.android.internal.logging.MetricsLogger;
|
import com.android.internal.logging.MetricsLogger;
|
||||||
import com.android.internal.os.BatterySipper;
|
import com.android.internal.os.BatterySipper;
|
||||||
|
import com.android.internal.os.BatterySipper.DrainType;
|
||||||
import com.android.internal.os.BatteryStatsHelper;
|
import com.android.internal.os.BatteryStatsHelper;
|
||||||
import com.android.internal.util.FastPrintWriter;
|
import com.android.internal.util.FastPrintWriter;
|
||||||
|
import com.android.settings.AppHeader;
|
||||||
import com.android.settings.DisplaySettings;
|
import com.android.settings.DisplaySettings;
|
||||||
import com.android.settings.InstrumentedFragment;
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.SettingsActivity;
|
import com.android.settings.SettingsActivity;
|
||||||
import com.android.settings.Utils;
|
import com.android.settings.Utils;
|
||||||
import com.android.settings.WirelessSettings;
|
import com.android.settings.WirelessSettings;
|
||||||
|
import com.android.settings.applications.AppInfoBase;
|
||||||
import com.android.settings.applications.InstalledAppDetails;
|
import com.android.settings.applications.InstalledAppDetails;
|
||||||
|
import com.android.settings.applications.LayoutPreference;
|
||||||
import com.android.settings.bluetooth.BluetoothSettings;
|
import com.android.settings.bluetooth.BluetoothSettings;
|
||||||
import com.android.settings.location.LocationSettings;
|
import com.android.settings.location.LocationSettings;
|
||||||
import com.android.settings.wifi.WifiSettings;
|
import com.android.settings.wifi.WifiSettings;
|
||||||
@@ -65,7 +64,7 @@ import java.io.PrintWriter;
|
|||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
|
||||||
public class PowerUsageDetail extends InstrumentedFragment implements Button.OnClickListener {
|
public class PowerUsageDetail extends PowerUsageBase implements Button.OnClickListener {
|
||||||
|
|
||||||
// Note: Must match the sequence of the DrainType
|
// Note: Must match the sequence of the DrainType
|
||||||
private static int[] sDrainTypeDesciptions = new int[] {
|
private static int[] sDrainTypeDesciptions = new int[] {
|
||||||
@@ -292,51 +291,57 @@ public class PowerUsageDetail extends InstrumentedFragment implements Button.OnC
|
|||||||
public static final String EXTRA_ICON_ID = "iconId"; // Int
|
public static final String EXTRA_ICON_ID = "iconId"; // Int
|
||||||
public static final String EXTRA_SHOW_LOCATION_BUTTON = "showLocationButton"; // Boolean
|
public static final String EXTRA_SHOW_LOCATION_BUTTON = "showLocationButton"; // Boolean
|
||||||
|
|
||||||
|
private static final String TAG = "PowerUsageDetail";
|
||||||
|
|
||||||
|
private static final String KEY_DETAILS_PARENT = "details_parent";
|
||||||
|
private static final String KEY_CONTROLS_PARENT = "controls_parent";
|
||||||
|
private static final String KEY_MESSAGES_PARENT = "messages_parent";
|
||||||
|
private static final String KEY_PACKAGES_PARENT = "packages_parent";
|
||||||
|
private static final String KEY_BATTERY_HISTORY = "battery_history";
|
||||||
|
private static final String KEY_TWO_BUTTONS = "two_buttons";
|
||||||
|
private static final String KEY_HIGH_POWER = "high_power";
|
||||||
|
|
||||||
private PackageManager mPm;
|
private PackageManager mPm;
|
||||||
private DevicePolicyManager mDpm;
|
private DevicePolicyManager mDpm;
|
||||||
private String mTitle;
|
|
||||||
private int mUsageSince;
|
private int mUsageSince;
|
||||||
private int[] mTypes;
|
private int[] mTypes;
|
||||||
private int mUid;
|
private int mUid;
|
||||||
private double[] mValues;
|
private double[] mValues;
|
||||||
private View mRootView;
|
|
||||||
private TextView mTitleView;
|
|
||||||
private ViewGroup mTwoButtonsPanel;
|
|
||||||
private Button mForceStopButton;
|
private Button mForceStopButton;
|
||||||
private Button mReportButton;
|
private Button mReportButton;
|
||||||
private ViewGroup mDetailsParent;
|
|
||||||
private ViewGroup mControlsParent;
|
|
||||||
private ViewGroup mMessagesParent;
|
|
||||||
private long mStartTime;
|
private long mStartTime;
|
||||||
private BatterySipper.DrainType mDrainType;
|
private BatterySipper.DrainType mDrainType;
|
||||||
private Drawable mAppIcon;
|
|
||||||
private double mNoCoverage; // Percentage of time that there was no coverage
|
private double mNoCoverage; // Percentage of time that there was no coverage
|
||||||
|
|
||||||
|
private BatteryHistoryPreference mHistPref;
|
||||||
|
private PreferenceCategory mDetailsParent;
|
||||||
|
private PreferenceCategory mControlsParent;
|
||||||
|
private PreferenceCategory mMessagesParent;
|
||||||
|
private PreferenceCategory mPackagesParent;
|
||||||
|
|
||||||
private boolean mUsesGps;
|
private boolean mUsesGps;
|
||||||
private boolean mShowLocationButton;
|
private boolean mShowLocationButton;
|
||||||
|
|
||||||
private static final String TAG = "PowerUsageDetail";
|
|
||||||
private String[] mPackages;
|
private String[] mPackages;
|
||||||
|
|
||||||
ApplicationInfo mApp;
|
ApplicationInfo mApp;
|
||||||
ComponentName mInstaller;
|
ComponentName mInstaller;
|
||||||
|
private Preference mHighPower;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
mPm = getActivity().getPackageManager();
|
mPm = getActivity().getPackageManager();
|
||||||
mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
|
mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
addPreferencesFromResource(R.xml.power_usage_details);
|
||||||
public View onCreateView(
|
mHistPref = (BatteryHistoryPreference) findPreference(KEY_BATTERY_HISTORY);
|
||||||
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
mDetailsParent = (PreferenceCategory) findPreference(KEY_DETAILS_PARENT);
|
||||||
final View view = inflater.inflate(R.layout.power_usage_details, container, false);
|
mControlsParent = (PreferenceCategory) findPreference(KEY_CONTROLS_PARENT);
|
||||||
prepareCustomPreferencesList(container, view, view, false);
|
mMessagesParent = (PreferenceCategory) findPreference(KEY_MESSAGES_PARENT);
|
||||||
|
mPackagesParent = (PreferenceCategory) findPreference(KEY_PACKAGES_PARENT);
|
||||||
|
|
||||||
mRootView = view;
|
|
||||||
createDetails();
|
createDetails();
|
||||||
return view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -349,76 +354,31 @@ public class PowerUsageDetail extends InstrumentedFragment implements Button.OnC
|
|||||||
super.onResume();
|
super.onResume();
|
||||||
mStartTime = android.os.Process.getElapsedCpuTime();
|
mStartTime = android.os.Process.getElapsedCpuTime();
|
||||||
checkForceStop();
|
checkForceStop();
|
||||||
|
if (mHighPower != null) {
|
||||||
|
mHighPower.setSummary(HighPowerDetail.getSummary(getActivity(), mApp.packageName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createDetails() {
|
private void createDetails() {
|
||||||
final Bundle args = getArguments();
|
final Bundle args = getArguments();
|
||||||
mTitle = args.getString(EXTRA_TITLE);
|
Context context = getActivity();
|
||||||
final int percentage = args.getInt(EXTRA_PERCENT, 1);
|
|
||||||
final int gaugeValue = args.getInt(EXTRA_GAUGE, 1);
|
|
||||||
mUsageSince = args.getInt(EXTRA_USAGE_SINCE, USAGE_SINCE_UNPLUGGED);
|
mUsageSince = args.getInt(EXTRA_USAGE_SINCE, USAGE_SINCE_UNPLUGGED);
|
||||||
mUid = args.getInt(EXTRA_UID, 0);
|
mUid = args.getInt(EXTRA_UID, 0);
|
||||||
|
mPackages = context.getPackageManager().getPackagesForUid(mUid);
|
||||||
mDrainType = (BatterySipper.DrainType) args.getSerializable(EXTRA_DRAIN_TYPE);
|
mDrainType = (BatterySipper.DrainType) args.getSerializable(EXTRA_DRAIN_TYPE);
|
||||||
mNoCoverage = args.getDouble(EXTRA_NO_COVERAGE, 0);
|
mNoCoverage = args.getDouble(EXTRA_NO_COVERAGE, 0);
|
||||||
String iconPackage = args.getString(EXTRA_ICON_PACKAGE);
|
|
||||||
int iconId = args.getInt(EXTRA_ICON_ID, 0);
|
|
||||||
mShowLocationButton = args.getBoolean(EXTRA_SHOW_LOCATION_BUTTON);
|
mShowLocationButton = args.getBoolean(EXTRA_SHOW_LOCATION_BUTTON);
|
||||||
if (!TextUtils.isEmpty(iconPackage)) {
|
|
||||||
try {
|
|
||||||
final PackageManager pm = getActivity().getPackageManager();
|
|
||||||
ApplicationInfo ai = pm.getPackageInfo(iconPackage, 0).applicationInfo;
|
|
||||||
if (ai != null) {
|
|
||||||
mAppIcon = ai.loadIcon(pm);
|
|
||||||
}
|
|
||||||
} catch (NameNotFoundException nnfe) {
|
|
||||||
// Use default icon
|
|
||||||
}
|
|
||||||
} else if (iconId != 0) {
|
|
||||||
mAppIcon = getActivity().getDrawable(iconId);
|
|
||||||
}
|
|
||||||
if (mAppIcon == null) {
|
|
||||||
mAppIcon = getActivity().getPackageManager().getDefaultActivityIcon();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the description
|
setupHeader();
|
||||||
final TextView summary = (TextView) mRootView.findViewById(android.R.id.summary);
|
|
||||||
summary.setText(getDescriptionForDrainType());
|
|
||||||
summary.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
mTypes = args.getIntArray(EXTRA_DETAIL_TYPES);
|
mTypes = args.getIntArray(EXTRA_DETAIL_TYPES);
|
||||||
mValues = args.getDoubleArray(EXTRA_DETAIL_VALUES);
|
mValues = args.getDoubleArray(EXTRA_DETAIL_VALUES);
|
||||||
|
|
||||||
mTitleView = (TextView) mRootView.findViewById(android.R.id.title);
|
LayoutPreference twoButtons = (LayoutPreference) findPreference(KEY_TWO_BUTTONS);
|
||||||
mTitleView.setText(mTitle);
|
mForceStopButton = (Button) twoButtons.findViewById(R.id.left_button);
|
||||||
|
mReportButton = (Button) twoButtons.findViewById(R.id.right_button);
|
||||||
final TextView text1 = (TextView)mRootView.findViewById(android.R.id.text1);
|
|
||||||
text1.setText(Utils.formatPercentage(percentage));
|
|
||||||
|
|
||||||
mTwoButtonsPanel = (ViewGroup)mRootView.findViewById(R.id.two_buttons_panel);
|
|
||||||
mForceStopButton = (Button)mRootView.findViewById(R.id.left_button);
|
|
||||||
mReportButton = (Button)mRootView.findViewById(R.id.right_button);
|
|
||||||
mForceStopButton.setEnabled(false);
|
mForceStopButton.setEnabled(false);
|
||||||
|
|
||||||
final ProgressBar progress = (ProgressBar) mRootView.findViewById(android.R.id.progress);
|
|
||||||
progress.setProgress(gaugeValue);
|
|
||||||
|
|
||||||
final ImageView icon = (ImageView) mRootView.findViewById(android.R.id.icon);
|
|
||||||
icon.setImageDrawable(mAppIcon);
|
|
||||||
|
|
||||||
mDetailsParent = (ViewGroup)mRootView.findViewById(R.id.details);
|
|
||||||
mControlsParent = (ViewGroup)mRootView.findViewById(R.id.controls);
|
|
||||||
mMessagesParent = (ViewGroup)mRootView.findViewById(R.id.messages);
|
|
||||||
|
|
||||||
fillDetailsSection();
|
|
||||||
fillPackagesSection(mUid);
|
|
||||||
fillControlsSection(mUid);
|
|
||||||
fillMessagesSection(mUid);
|
|
||||||
|
|
||||||
if (mUid >= Process.FIRST_APPLICATION_UID) {
|
if (mUid >= Process.FIRST_APPLICATION_UID) {
|
||||||
mForceStopButton.setText(R.string.force_stop);
|
mForceStopButton.setText(R.string.force_stop);
|
||||||
mForceStopButton.setTag(ACTION_FORCE_STOP);
|
mForceStopButton.setTag(ACTION_FORCE_STOP);
|
||||||
@@ -427,26 +387,85 @@ public class PowerUsageDetail extends InstrumentedFragment implements Button.OnC
|
|||||||
mReportButton.setTag(ACTION_REPORT);
|
mReportButton.setTag(ACTION_REPORT);
|
||||||
mReportButton.setOnClickListener(this);
|
mReportButton.setOnClickListener(this);
|
||||||
|
|
||||||
// check if error reporting is enabled in secure settings
|
|
||||||
int enabled = android.provider.Settings.Global.getInt(getActivity().getContentResolver(),
|
|
||||||
android.provider.Settings.Global.SEND_ACTION_APP_ERROR, 0);
|
|
||||||
if (enabled != 0) {
|
|
||||||
if (mPackages != null && mPackages.length > 0) {
|
if (mPackages != null && mPackages.length > 0) {
|
||||||
try {
|
try {
|
||||||
mApp = getActivity().getPackageManager().getApplicationInfo(
|
mApp = context.getPackageManager().getApplicationInfo(
|
||||||
mPackages[0], 0);
|
mPackages[0], 0);
|
||||||
mInstaller = ApplicationErrorReport.getErrorReportReceiver(
|
|
||||||
getActivity(), mPackages[0], mApp.flags);
|
|
||||||
} catch (NameNotFoundException e) {
|
} catch (NameNotFoundException e) {
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "No packages!!");
|
||||||
|
}
|
||||||
|
// check if error reporting is enabled in secure settings
|
||||||
|
int enabled = android.provider.Settings.Global.getInt(context.getContentResolver(),
|
||||||
|
android.provider.Settings.Global.SEND_ACTION_APP_ERROR, 0);
|
||||||
|
if (enabled != 0) {
|
||||||
|
if (mApp != null) {
|
||||||
|
mInstaller = ApplicationErrorReport.getErrorReportReceiver(
|
||||||
|
context, mPackages[0], mApp.flags);
|
||||||
}
|
}
|
||||||
mReportButton.setEnabled(mInstaller != null);
|
mReportButton.setEnabled(mInstaller != null);
|
||||||
} else {
|
} else {
|
||||||
mTwoButtonsPanel.setVisibility(View.GONE);
|
removePreference(KEY_TWO_BUTTONS);
|
||||||
|
}
|
||||||
|
if (mApp != null) {
|
||||||
|
mHighPower = findPreference(KEY_HIGH_POWER);
|
||||||
|
mHighPower.setOnPreferenceClickListener(new OnPreferenceClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
|
AppInfoBase.startAppInfoFragment(HighPowerDetail.class, R.string.high_power,
|
||||||
|
mApp.packageName, mApp.uid, PowerUsageDetail.this, 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
removePreference(KEY_HIGH_POWER);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mTwoButtonsPanel.setVisibility(View.GONE);
|
removePreference(KEY_TWO_BUTTONS);
|
||||||
|
removePreference(KEY_HIGH_POWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refreshStats();
|
||||||
|
|
||||||
|
fillDetailsSection();
|
||||||
|
fillPackagesSection(mUid);
|
||||||
|
fillControlsSection(mUid);
|
||||||
|
fillMessagesSection(mUid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void refreshStats() {
|
||||||
|
super.refreshStats();
|
||||||
|
updatePreference(mHistPref);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupHeader() {
|
||||||
|
final Bundle args = getArguments();
|
||||||
|
String title = args.getString(EXTRA_TITLE);
|
||||||
|
String iconPackage = args.getString(EXTRA_ICON_PACKAGE);
|
||||||
|
int iconId = args.getInt(EXTRA_ICON_ID, 0);
|
||||||
|
Drawable appIcon = null;
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(iconPackage)) {
|
||||||
|
try {
|
||||||
|
final PackageManager pm = getActivity().getPackageManager();
|
||||||
|
ApplicationInfo ai = pm.getPackageInfo(iconPackage, 0).applicationInfo;
|
||||||
|
if (ai != null) {
|
||||||
|
appIcon = ai.loadIcon(pm);
|
||||||
|
}
|
||||||
|
} catch (NameNotFoundException nnfe) {
|
||||||
|
// Use default icon
|
||||||
|
}
|
||||||
|
} else if (iconId != 0) {
|
||||||
|
appIcon = getActivity().getDrawable(iconId);
|
||||||
|
}
|
||||||
|
if (appIcon == null) {
|
||||||
|
appIcon = getActivity().getPackageManager().getDefaultActivityIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
AppHeader.createAppHeader(getActivity(), appIcon, title, null,
|
||||||
|
mDrainType != DrainType.APP ? android.R.color.white : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
@@ -500,7 +519,6 @@ public class PowerUsageDetail extends InstrumentedFragment implements Button.OnC
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void fillDetailsSection() {
|
private void fillDetailsSection() {
|
||||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
|
||||||
if (mTypes != null && mValues != null) {
|
if (mTypes != null && mValues != null) {
|
||||||
for (int i = 0; i < mTypes.length; i++) {
|
for (int i = 0; i < mTypes.length; i++) {
|
||||||
// Only add an item if the time is greater than zero
|
// Only add an item if the time is greater than zero
|
||||||
@@ -530,17 +548,21 @@ public class PowerUsageDetail extends InstrumentedFragment implements Button.OnC
|
|||||||
default:
|
default:
|
||||||
value = Utils.formatElapsedTime(getActivity(), mValues[i], true);
|
value = Utils.formatElapsedTime(getActivity(), mValues[i], true);
|
||||||
}
|
}
|
||||||
ViewGroup item = (ViewGroup) inflater.inflate(R.layout.power_usage_detail_item_text,
|
addHorizontalPreference(mDetailsParent, label, value);
|
||||||
null);
|
|
||||||
mDetailsParent.addView(item);
|
|
||||||
TextView labelView = (TextView) item.findViewById(R.id.label);
|
|
||||||
TextView valueView = (TextView) item.findViewById(R.id.value);
|
|
||||||
labelView.setText(label);
|
|
||||||
valueView.setText(value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addHorizontalPreference(PreferenceCategory parent, CharSequence title,
|
||||||
|
CharSequence summary) {
|
||||||
|
Preference pref = new Preference(getActivity());
|
||||||
|
pref.setLayoutResource(R.layout.horizontal_preference);
|
||||||
|
pref.setTitle(title);
|
||||||
|
pref.setSummary(summary);
|
||||||
|
pref.setSelectable(false);
|
||||||
|
parent.addPreference(pref);
|
||||||
|
}
|
||||||
|
|
||||||
private void fillControlsSection(int uid) {
|
private void fillControlsSection(int uid) {
|
||||||
PackageManager pm = getActivity().getPackageManager();
|
PackageManager pm = getActivity().getPackageManager();
|
||||||
String[] packages = pm.getPackagesForUid(uid);
|
String[] packages = pm.getPackagesForUid(uid);
|
||||||
@@ -597,21 +619,22 @@ public class PowerUsageDetail extends InstrumentedFragment implements Button.OnC
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (removeHeader) {
|
if (removeHeader) {
|
||||||
mControlsParent.setVisibility(View.GONE);
|
mControlsParent.setTitle(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addControl(int title, int summary, int action) {
|
private void addControl(int pageSummary, int actionTitle, final int action) {
|
||||||
final Resources res = getResources();
|
Preference pref = new Preference(getActivity());
|
||||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
pref.setTitle(actionTitle);
|
||||||
ViewGroup item = (ViewGroup) inflater.inflate(R.layout.power_usage_action_item,null);
|
pref.setSummary(pageSummary);
|
||||||
mControlsParent.addView(item);
|
pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
|
||||||
Button actionButton = (Button) item.findViewById(R.id.action_button);
|
@Override
|
||||||
TextView summaryView = (TextView) item.findViewById(R.id.summary);
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
actionButton.setText(res.getString(title));
|
doAction(action);
|
||||||
summaryView.setText(res.getString(summary));
|
return true;
|
||||||
actionButton.setOnClickListener(this);
|
}
|
||||||
actionButton.setTag(new Integer(action));
|
});
|
||||||
|
mControlsParent.addPreference(pref);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillMessagesSection(int uid) {
|
private void fillMessagesSection(int uid) {
|
||||||
@@ -623,27 +646,16 @@ public class PowerUsageDetail extends InstrumentedFragment implements Button.OnC
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (removeHeader) {
|
if (removeHeader) {
|
||||||
mMessagesParent.setVisibility(View.GONE);
|
mMessagesParent.setTitle(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMessage(int message) {
|
private void addMessage(int message) {
|
||||||
final Resources res = getResources();
|
addHorizontalPreference(mMessagesParent, getString(message), null);
|
||||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
|
||||||
View item = inflater.inflate(R.layout.power_usage_message_item, null);
|
|
||||||
mMessagesParent.addView(item);
|
|
||||||
TextView messageView = (TextView) item.findViewById(R.id.message);
|
|
||||||
messageView.setText(res.getText(message));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removePackagesSection() {
|
private void removePackagesSection() {
|
||||||
View view;
|
getPreferenceScreen().removePreference(mPackagesParent);
|
||||||
if ((view = mRootView.findViewById(R.id.packages_section_title)) != null) {
|
|
||||||
view.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
if ((view = mRootView.findViewById(R.id.packages_section)) != null) {
|
|
||||||
view.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void killProcesses() {
|
private void killProcesses() {
|
||||||
@@ -725,40 +737,23 @@ public class PowerUsageDetail extends InstrumentedFragment implements Button.OnC
|
|||||||
removePackagesSection();
|
removePackagesSection();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ViewGroup packagesParent = (ViewGroup)mRootView.findViewById(R.id.packages_section);
|
|
||||||
if (packagesParent == null) return;
|
|
||||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
|
||||||
|
|
||||||
PackageManager pm = getActivity().getPackageManager();
|
|
||||||
//final Drawable defaultActivityIcon = pm.getDefaultActivityIcon();
|
|
||||||
mPackages = pm.getPackagesForUid(uid);
|
|
||||||
if (mPackages == null || mPackages.length < 2) {
|
if (mPackages == null || mPackages.length < 2) {
|
||||||
removePackagesSection();
|
removePackagesSection();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PackageManager pm = getPackageManager();
|
||||||
// Convert package names to user-facing labels where possible
|
// Convert package names to user-facing labels where possible
|
||||||
for (int i = 0; i < mPackages.length; i++) {
|
for (int i = 0; i < mPackages.length; i++) {
|
||||||
try {
|
try {
|
||||||
ApplicationInfo ai = pm.getApplicationInfo(mPackages[i], 0);
|
ApplicationInfo ai = pm.getApplicationInfo(mPackages[i], 0);
|
||||||
CharSequence label = ai.loadLabel(pm);
|
CharSequence label = ai.loadLabel(pm);
|
||||||
//Drawable icon = defaultActivityIcon;
|
|
||||||
if (label != null) {
|
if (label != null) {
|
||||||
mPackages[i] = label.toString();
|
mPackages[i] = label.toString();
|
||||||
}
|
}
|
||||||
//if (ai.icon != 0) {
|
addHorizontalPreference(mPackagesParent, mPackages[i], null);
|
||||||
// icon = ai.loadIcon(pm);
|
|
||||||
//}
|
|
||||||
View item = inflater.inflate(R.layout.power_usage_package_item, null);
|
|
||||||
packagesParent.addView(item);
|
|
||||||
TextView labelView = (TextView) item.findViewById(R.id.label);
|
|
||||||
labelView.setText(mPackages[i]);
|
|
||||||
} catch (NameNotFoundException e) {
|
} catch (NameNotFoundException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDescriptionForDrainType() {
|
|
||||||
return getResources().getString(sDrainTypeDesciptions[mDrainType.ordinal()]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -17,10 +17,6 @@
|
|||||||
package com.android.settings.fuelgauge;
|
package com.android.settings.fuelgauge;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.BatteryStats;
|
import android.os.BatteryStats;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@@ -28,7 +24,6 @@ import android.os.Bundle;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceGroup;
|
import android.preference.PreferenceGroup;
|
||||||
import android.preference.PreferenceScreen;
|
import android.preference.PreferenceScreen;
|
||||||
@@ -39,12 +34,12 @@ import android.view.MenuItem;
|
|||||||
|
|
||||||
import com.android.internal.logging.MetricsLogger;
|
import com.android.internal.logging.MetricsLogger;
|
||||||
import com.android.internal.os.BatterySipper;
|
import com.android.internal.os.BatterySipper;
|
||||||
import com.android.internal.os.BatteryStatsHelper;
|
|
||||||
import com.android.internal.os.PowerProfile;
|
import com.android.internal.os.PowerProfile;
|
||||||
import com.android.settings.HelpUtils;
|
import com.android.settings.HelpUtils;
|
||||||
import com.android.settings.InstrumentedPreferenceFragment;
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.Settings.HighPowerApplicationsActivity;
|
||||||
import com.android.settings.SettingsActivity;
|
import com.android.settings.SettingsActivity;
|
||||||
|
import com.android.settings.applications.ManageApplications;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -52,27 +47,22 @@ import java.util.List;
|
|||||||
* Displays a list of apps and subsystems that consume power, ordered by how much power was
|
* Displays a list of apps and subsystems that consume power, ordered by how much power was
|
||||||
* consumed since the last time it was unplugged.
|
* consumed since the last time it was unplugged.
|
||||||
*/
|
*/
|
||||||
public class PowerUsageSummary extends InstrumentedPreferenceFragment {
|
public class PowerUsageSummary extends PowerUsageBase {
|
||||||
|
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
static final String TAG = "PowerUsageSummary";
|
static final String TAG = "PowerUsageSummary";
|
||||||
|
|
||||||
private static final String KEY_APP_LIST = "app_list";
|
private static final String KEY_APP_LIST = "app_list";
|
||||||
|
private static final String KEY_BATTERY_HISTORY = "battery_history";
|
||||||
private static final String BATTERY_HISTORY_FILE = "tmp_bat_history.bin";
|
|
||||||
|
|
||||||
private static final int MENU_STATS_TYPE = Menu.FIRST;
|
private static final int MENU_STATS_TYPE = Menu.FIRST;
|
||||||
private static final int MENU_STATS_REFRESH = Menu.FIRST + 1;
|
|
||||||
private static final int MENU_BATTERY_SAVER = Menu.FIRST + 2;
|
private static final int MENU_BATTERY_SAVER = Menu.FIRST + 2;
|
||||||
private static final int MENU_HELP = Menu.FIRST + 3;
|
private static final int MENU_HIGH_POWER_APPS = Menu.FIRST + 3;
|
||||||
|
private static final int MENU_HELP = Menu.FIRST + 4;
|
||||||
private UserManager mUm;
|
|
||||||
|
|
||||||
private BatteryHistoryPreference mHistPref;
|
private BatteryHistoryPreference mHistPref;
|
||||||
private PreferenceGroup mAppListGroup;
|
private PreferenceGroup mAppListGroup;
|
||||||
private String mBatteryLevel;
|
|
||||||
private String mBatteryStatus;
|
|
||||||
|
|
||||||
private int mStatsType = BatteryStats.STATS_SINCE_CHARGED;
|
private int mStatsType = BatteryStats.STATS_SINCE_CHARGED;
|
||||||
|
|
||||||
@@ -81,43 +71,13 @@ public class PowerUsageSummary extends InstrumentedPreferenceFragment {
|
|||||||
private static final int MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP = 10;
|
private static final int MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP = 10;
|
||||||
private static final int SECONDS_IN_HOUR = 60 * 60;
|
private static final int SECONDS_IN_HOUR = 60 * 60;
|
||||||
|
|
||||||
private BatteryStatsHelper mStatsHelper;
|
|
||||||
|
|
||||||
private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
String action = intent.getAction();
|
|
||||||
if (Intent.ACTION_BATTERY_CHANGED.equals(action)
|
|
||||||
&& updateBatteryStatus(intent)) {
|
|
||||||
if (!mHandler.hasMessages(MSG_REFRESH_STATS)) {
|
|
||||||
mHandler.sendEmptyMessageDelayed(MSG_REFRESH_STATS, 500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttach(Activity activity) {
|
|
||||||
super.onAttach(activity);
|
|
||||||
mUm = (UserManager) activity.getSystemService(Context.USER_SERVICE);
|
|
||||||
mStatsHelper = new BatteryStatsHelper(activity, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
mStatsHelper.create(icicle);
|
|
||||||
|
|
||||||
addPreferencesFromResource(R.xml.power_usage_summary);
|
addPreferencesFromResource(R.xml.power_usage_summary);
|
||||||
|
mHistPref = (BatteryHistoryPreference) findPreference(KEY_BATTERY_HISTORY);
|
||||||
mAppListGroup = (PreferenceGroup) findPreference(KEY_APP_LIST);
|
mAppListGroup = (PreferenceGroup) findPreference(KEY_APP_LIST);
|
||||||
setHasOptionsMenu(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
mStatsHelper.clearStats();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -128,13 +88,6 @@ public class PowerUsageSummary extends InstrumentedPreferenceFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
BatteryStatsHelper.dropFile(getActivity(), BATTERY_HISTORY_FILE);
|
|
||||||
updateBatteryStatus(getActivity().registerReceiver(mBatteryInfoReceiver,
|
|
||||||
new IntentFilter(Intent.ACTION_BATTERY_CHANGED)));
|
|
||||||
if (mHandler.hasMessages(MSG_REFRESH_STATS)) {
|
|
||||||
mHandler.removeMessages(MSG_REFRESH_STATS);
|
|
||||||
mStatsHelper.clearStats();
|
|
||||||
}
|
|
||||||
refreshStats();
|
refreshStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,38 +95,19 @@ public class PowerUsageSummary extends InstrumentedPreferenceFragment {
|
|||||||
public void onPause() {
|
public void onPause() {
|
||||||
BatteryEntry.stopRequestQueue();
|
BatteryEntry.stopRequestQueue();
|
||||||
mHandler.removeMessages(BatteryEntry.MSG_UPDATE_NAME_ICON);
|
mHandler.removeMessages(BatteryEntry.MSG_UPDATE_NAME_ICON);
|
||||||
getActivity().unregisterReceiver(mBatteryInfoReceiver);
|
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
mHandler.removeMessages(MSG_REFRESH_STATS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
if (getActivity().isChangingConfigurations()) {
|
if (getActivity().isChangingConfigurations()) {
|
||||||
mStatsHelper.storeState();
|
|
||||||
BatteryEntry.clearUidCache();
|
BatteryEntry.clearUidCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
|
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
|
||||||
if (preference instanceof BatteryHistoryPreference) {
|
|
||||||
mStatsHelper.storeStatsHistoryInFile(BATTERY_HISTORY_FILE);
|
|
||||||
Bundle args = new Bundle();
|
|
||||||
args.putString(BatteryHistoryDetail.EXTRA_STATS, BATTERY_HISTORY_FILE);
|
|
||||||
args.putParcelable(BatteryHistoryDetail.EXTRA_BROADCAST,
|
|
||||||
mStatsHelper.getBatteryBroadcast());
|
|
||||||
SettingsActivity sa = (SettingsActivity) getActivity();
|
|
||||||
sa.startPreferencePanel(BatteryHistoryDetail.class.getName(), args,
|
|
||||||
R.string.history_details_title, null, null, 0);
|
|
||||||
return super.onPreferenceTreeClick(preferenceScreen, preference);
|
|
||||||
}
|
|
||||||
if (!(preference instanceof PowerGaugePreference)) {
|
if (!(preference instanceof PowerGaugePreference)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -186,20 +120,18 @@ public class PowerUsageSummary extends InstrumentedPreferenceFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
menu.add(0, MENU_STATS_TYPE, 0, R.string.menu_stats_total)
|
menu.add(0, MENU_STATS_TYPE, 0, R.string.menu_stats_total)
|
||||||
.setIcon(com.android.internal.R.drawable.ic_menu_info_details)
|
.setIcon(com.android.internal.R.drawable.ic_menu_info_details)
|
||||||
.setAlphabeticShortcut('t');
|
.setAlphabeticShortcut('t');
|
||||||
}
|
}
|
||||||
MenuItem refresh = menu.add(0, MENU_STATS_REFRESH, 0, R.string.menu_stats_refresh)
|
|
||||||
.setIcon(com.android.internal.R.drawable.ic_menu_refresh)
|
|
||||||
.setAlphabeticShortcut('r');
|
|
||||||
refresh.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM |
|
|
||||||
MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
|
||||||
|
|
||||||
MenuItem batterySaver = menu.add(0, MENU_BATTERY_SAVER, 0, R.string.battery_saver);
|
MenuItem batterySaver = menu.add(0, MENU_BATTERY_SAVER, 0, R.string.battery_saver);
|
||||||
batterySaver.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
|
batterySaver.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
|
||||||
|
|
||||||
|
menu.add(0, MENU_HIGH_POWER_APPS, 0, R.string.high_power_apps);
|
||||||
|
|
||||||
String helpUrl;
|
String helpUrl;
|
||||||
if (!TextUtils.isEmpty(helpUrl = getResources().getString(R.string.help_url_battery))) {
|
if (!TextUtils.isEmpty(helpUrl = getResources().getString(R.string.help_url_battery))) {
|
||||||
final MenuItem help = menu.add(0, MENU_HELP, 0, R.string.help_label);
|
final MenuItem help = menu.add(0, MENU_HELP, 0, R.string.help_label);
|
||||||
@@ -209,6 +141,7 @@ public class PowerUsageSummary extends InstrumentedPreferenceFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
final SettingsActivity sa = (SettingsActivity) getActivity();
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case MENU_STATS_TYPE:
|
case MENU_STATS_TYPE:
|
||||||
if (mStatsType == BatteryStats.STATS_SINCE_CHARGED) {
|
if (mStatsType == BatteryStats.STATS_SINCE_CHARGED) {
|
||||||
@@ -218,59 +151,40 @@ public class PowerUsageSummary extends InstrumentedPreferenceFragment {
|
|||||||
}
|
}
|
||||||
refreshStats();
|
refreshStats();
|
||||||
return true;
|
return true;
|
||||||
case MENU_STATS_REFRESH:
|
|
||||||
mStatsHelper.clearStats();
|
|
||||||
refreshStats();
|
|
||||||
mHandler.removeMessages(MSG_REFRESH_STATS);
|
|
||||||
return true;
|
|
||||||
case MENU_BATTERY_SAVER:
|
case MENU_BATTERY_SAVER:
|
||||||
final SettingsActivity sa = (SettingsActivity) getActivity();
|
|
||||||
sa.startPreferencePanel(BatterySaverSettings.class.getName(), null,
|
sa.startPreferencePanel(BatterySaverSettings.class.getName(), null,
|
||||||
R.string.battery_saver, null, null, 0);
|
R.string.battery_saver, null, null, 0);
|
||||||
return true;
|
return true;
|
||||||
|
case MENU_HIGH_POWER_APPS:
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString(ManageApplications.EXTRA_CLASSNAME,
|
||||||
|
HighPowerApplicationsActivity.class.getName());
|
||||||
|
sa.startPreferencePanel(ManageApplications.class.getName(), args,
|
||||||
|
R.string.high_power_apps, null, null, 0);
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addNotAvailableMessage() {
|
private void addNotAvailableMessage() {
|
||||||
Preference notAvailable = new Preference(getActivity());
|
Preference notAvailable = new Preference(getActivity());
|
||||||
notAvailable.setTitle(R.string.power_usage_not_available);
|
notAvailable.setTitle(R.string.power_usage_not_available);
|
||||||
mHistPref.setHideLabels(true);
|
|
||||||
mAppListGroup.addPreference(notAvailable);
|
mAppListGroup.addPreference(notAvailable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean updateBatteryStatus(Intent intent) {
|
protected void refreshStats() {
|
||||||
if (intent != null) {
|
super.refreshStats();
|
||||||
String batteryLevel = com.android.settings.Utils.getBatteryPercentage(intent);
|
updatePreference(mHistPref);
|
||||||
String batteryStatus = com.android.settings.Utils.getBatteryStatus(getResources(),
|
|
||||||
intent);
|
|
||||||
if (!batteryLevel.equals(mBatteryLevel) || !batteryStatus.equals(mBatteryStatus)) {
|
|
||||||
mBatteryLevel = batteryLevel;
|
|
||||||
mBatteryStatus = batteryStatus;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void refreshStats() {
|
|
||||||
mAppListGroup.removeAll();
|
mAppListGroup.removeAll();
|
||||||
mAppListGroup.setOrderingAsAdded(false);
|
mAppListGroup.setOrderingAsAdded(false);
|
||||||
mHistPref = new BatteryHistoryPreference(getActivity(), mStatsHelper.getStats(),
|
|
||||||
mStatsHelper.getBatteryBroadcast());
|
|
||||||
mHistPref.setOrder(-1);
|
|
||||||
mAppListGroup.addPreference(mHistPref);
|
|
||||||
boolean addedSome = false;
|
boolean addedSome = false;
|
||||||
|
|
||||||
final PowerProfile powerProfile = mStatsHelper.getPowerProfile();
|
final PowerProfile powerProfile = mStatsHelper.getPowerProfile();
|
||||||
final BatteryStats stats = mStatsHelper.getStats();
|
final BatteryStats stats = mStatsHelper.getStats();
|
||||||
final double averagePower = powerProfile.getAveragePower(PowerProfile.POWER_SCREEN_FULL);
|
final double averagePower = powerProfile.getAveragePower(PowerProfile.POWER_SCREEN_FULL);
|
||||||
|
|
||||||
if (averagePower >= MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP) {
|
if (averagePower >= MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP) {
|
||||||
final List<UserHandle> profiles = mUm.getUserProfiles();
|
|
||||||
|
|
||||||
mStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, profiles);
|
|
||||||
|
|
||||||
final List<BatterySipper> usageList = mStatsHelper.getUsageList();
|
final List<BatterySipper> usageList = mStatsHelper.getUsageList();
|
||||||
|
|
||||||
final int dischargeAmount = stats != null ? stats.getDischargeAmount(mStatsType) : 0;
|
final int dischargeAmount = stats != null ? stats.getDischargeAmount(mStatsType) : 0;
|
||||||
@@ -320,7 +234,8 @@ public class PowerUsageSummary extends InstrumentedPreferenceFragment {
|
|||||||
final PowerGaugePreference pref = new PowerGaugePreference(getActivity(),
|
final PowerGaugePreference pref = new PowerGaugePreference(getActivity(),
|
||||||
badgedIcon, contentDescription, entry);
|
badgedIcon, contentDescription, entry);
|
||||||
|
|
||||||
final double percentOfMax = (sipper.totalPowerMah * 100) / mStatsHelper.getMaxPower();
|
final double percentOfMax = (sipper.totalPowerMah * 100)
|
||||||
|
/ mStatsHelper.getMaxPower();
|
||||||
sipper.percent = percentOfTotal;
|
sipper.percent = percentOfTotal;
|
||||||
pref.setTitle(entry.getLabel());
|
pref.setTitle(entry.getLabel());
|
||||||
pref.setOrder(i + 1);
|
pref.setOrder(i + 1);
|
||||||
@@ -342,8 +257,6 @@ public class PowerUsageSummary extends InstrumentedPreferenceFragment {
|
|||||||
BatteryEntry.startRequestQueue();
|
BatteryEntry.startRequestQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
static final int MSG_REFRESH_STATS = 100;
|
|
||||||
|
|
||||||
Handler mHandler = new Handler() {
|
Handler mHandler = new Handler() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -367,9 +280,6 @@ public class PowerUsageSummary extends InstrumentedPreferenceFragment {
|
|||||||
activity.reportFullyDrawn();
|
activity.reportFullyDrawn();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MSG_REFRESH_STATS:
|
|
||||||
mStatsHelper.clearStats();
|
|
||||||
refreshStats();
|
|
||||||
}
|
}
|
||||||
super.handleMessage(msg);
|
super.handleMessage(msg);
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 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.os.IDeviceIdleController;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.os.ServiceManager;
|
||||||
|
import android.util.ArraySet;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles getting/changing the whitelist for the exceptions to battery saving features.
|
||||||
|
*/
|
||||||
|
public class PowerWhitelistBackend {
|
||||||
|
|
||||||
|
private static final String TAG = "PowerWhitelistBackend";
|
||||||
|
|
||||||
|
private static final String DEVICE_IDLE_SERVICE = "deviceidle";
|
||||||
|
|
||||||
|
private static final PowerWhitelistBackend INSTANCE = new PowerWhitelistBackend();
|
||||||
|
|
||||||
|
private final IDeviceIdleController mDeviceIdleService;
|
||||||
|
private final ArraySet<String> mWhitelistedApps = new ArraySet<>();
|
||||||
|
private final ArraySet<String> mSysWhitelistedApps = new ArraySet<>();
|
||||||
|
|
||||||
|
public PowerWhitelistBackend() {
|
||||||
|
mDeviceIdleService = IDeviceIdleController.Stub.asInterface(
|
||||||
|
ServiceManager.getService(DEVICE_IDLE_SERVICE));
|
||||||
|
refreshList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWhitelistSize() {
|
||||||
|
return mWhitelistedApps.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSysWhitelisted(String pkg) {
|
||||||
|
return mSysWhitelistedApps.contains(pkg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWhitelisted(String pkg) {
|
||||||
|
return mWhitelistedApps.contains(pkg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addApp(String pkg) {
|
||||||
|
try {
|
||||||
|
mDeviceIdleService.addPowerSaveWhitelistApp(pkg);
|
||||||
|
mWhitelistedApps.add(pkg);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.w(TAG, "Unable to reach IDeviceIdleController", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeApp(String pkg) {
|
||||||
|
try {
|
||||||
|
mDeviceIdleService.removePowerSaveWhitelistApp(pkg);
|
||||||
|
mWhitelistedApps.remove(pkg);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.w(TAG, "Unable to reach IDeviceIdleController", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshList() {
|
||||||
|
mSysWhitelistedApps.clear();
|
||||||
|
mWhitelistedApps.clear();
|
||||||
|
try {
|
||||||
|
String[] whitelistedApps = mDeviceIdleService.getFullPowerWhitelist();
|
||||||
|
for (String app : whitelistedApps) {
|
||||||
|
mWhitelistedApps.add(app);
|
||||||
|
}
|
||||||
|
String[] sysWhitelistedApps = mDeviceIdleService.getSystemPowerWhitelist();
|
||||||
|
for (String app : sysWhitelistedApps) {
|
||||||
|
mSysWhitelistedApps.add(app);
|
||||||
|
}
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.w(TAG, "Unable to reach IDeviceIdleController", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PowerWhitelistBackend getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user