Snap for 7266202 from ec7c17c3cd to sc-release
Change-Id: Idef03e1f10b449697a7b39ec20d1cb02ddc1826f
This commit is contained in:
@@ -1,50 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="77dp"
|
||||
android:height="134dp"
|
||||
android:viewportWidth="77"
|
||||
android:viewportHeight="134">
|
||||
<path
|
||||
android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"
|
||||
android:strokeWidth="1.8"
|
||||
android:fillColor="#F2F3F4"
|
||||
android:strokeColor="#DADCE0"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"/>
|
||||
<path
|
||||
android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"/>
|
||||
<path
|
||||
android:pathData="M13,5L65,5A8,8 0,0 1,73 13L73,120A8,8 0,0 1,65 128L13,128A8,8 0,0 1,5 120L5,13A8,8 0,0 1,13 5z"
|
||||
android:strokeLineJoin="bevel"
|
||||
android:strokeWidth="10"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#F29900"/>
|
||||
<path
|
||||
android:pathData="M51.077,14V18.314H56.612L50,24.958L53.037,28L59.692,21.334V26.921H64V14H51.077Z"
|
||||
android:fillColor="#F29900"/>
|
||||
<path
|
||||
android:pathData="M25.963,104L19.308,110.655V105.077H15V118H27.923V113.692H22.366L29,107.037L25.963,104Z"
|
||||
android:fillColor="#F29900"/>
|
||||
</group>
|
||||
</group>
|
||||
</vector>
|
||||
@@ -1,52 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="77dp"
|
||||
android:height="134dp"
|
||||
android:viewportWidth="77"
|
||||
android:viewportHeight="134">
|
||||
<path
|
||||
android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"
|
||||
android:strokeWidth="1.8"
|
||||
android:fillColor="#F2F3F4"
|
||||
android:strokeColor="#DADCE0"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"/>
|
||||
<path
|
||||
android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"/>
|
||||
<path
|
||||
android:pathData="M39,94h24v24h-24z"
|
||||
android:fillColor="#000000"
|
||||
android:fillAlpha="0.7"/>
|
||||
<path
|
||||
android:pathData="M51.414,98.138H45.138C44.033,98.138 43.138,99.033 43.138,100.138V112.689C43.138,113.794 44.033,114.689 45.138,114.689H57.69C58.794,114.689 59.69,113.794 59.69,112.689L59.69,106.414H57.69L57.69,112.689L45.138,112.689V100.138H51.414V98.138ZM49.414,108.414H48.448V109.379H49.414V108.414ZM48.448,106.414H46.448V108.414V109.379V111.379H48.448H49.414H51.414V109.379V108.414V106.414H49.414H48.448ZM55.891,103.103L58.035,103.103V104.758L53.069,104.758V99.793L54.724,99.793V101.936L58.275,98.378L59.45,99.553L55.891,103.103Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M13,5L65,5A8,8 0,0 1,73 13L73,120A8,8 0,0 1,65 128L13,128A8,8 0,0 1,5 120L5,13A8,8 0,0 1,13 5z"
|
||||
android:strokeLineJoin="bevel"
|
||||
android:strokeWidth="10"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#F29900"/>
|
||||
</group>
|
||||
</group>
|
||||
</vector>
|
||||
@@ -1,50 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="77dp"
|
||||
android:height="134dp"
|
||||
android:viewportWidth="77"
|
||||
android:viewportHeight="134">
|
||||
<path
|
||||
android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"
|
||||
android:strokeWidth="1.8"
|
||||
android:fillColor="#F2F3F4"
|
||||
android:strokeColor="#DADCE0"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M7.4,1.1L69.6,1.1A6.3,6.3 0,0 1,75.9 7.4L75.9,126.6A6.3,6.3 0,0 1,69.6 132.9L7.4,132.9A6.3,6.3 0,0 1,1.1 126.6L1.1,7.4A6.3,6.3 0,0 1,7.4 1.1z"/>
|
||||
<path
|
||||
android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M10.442,4.948L67.167,4.948A5.4,5.4 0,0 1,72.567 10.348L72.567,123.548A5.4,5.4 0,0 1,67.167 128.948L10.442,128.948A5.4,5.4 0,0 1,5.042 123.548L5.042,10.348A5.4,5.4 0,0 1,10.442 4.948z"/>
|
||||
<path
|
||||
android:pathData="M15,47L64,47A2,2 0,0 1,66 49L66,84A2,2 0,0 1,64 86L15,86A2,2 0,0 1,13 84L13,49A2,2 0,0 1,15 47z"
|
||||
android:strokeLineJoin="bevel"
|
||||
android:strokeWidth="5"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#F29900"/>
|
||||
<path
|
||||
android:pathData="M47.077,53V57.314H52.612L46,63.958L49.037,67L55.692,60.334V65.921H60V53H47.077Z"
|
||||
android:fillColor="#F29900"/>
|
||||
<path
|
||||
android:pathData="M29.963,66L23.308,72.655V67.077H19V80H31.923V75.692H26.366L33,69.037L29.963,66Z"
|
||||
android:fillColor="#F29900"/>
|
||||
</group>
|
||||
</group>
|
||||
</vector>
|
||||
39
res/drawable/ic_illustration_fullscreen.xml
Normal file
39
res/drawable/ic_illustration_fullscreen.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="77dp"
|
||||
android:height="134dp"
|
||||
android:viewportWidth="77"
|
||||
android:viewportHeight="134">
|
||||
<path
|
||||
android:pathData="M69.6,1.1H7.4C3.921,1.1 1.1,3.921 1.1,7.4V126.6C1.1,130.079 3.921,132.9 7.4,132.9H69.6C73.079,132.9 75.9,130.079 75.9,126.6V7.4C75.9,3.921 73.079,1.1 69.6,1.1Z"
|
||||
android:strokeWidth="1.8"
|
||||
android:fillColor="#F2F3F4"
|
||||
android:strokeColor="#DADCE0"/>
|
||||
<path
|
||||
android:pathData="M66.642,5H10.358C7.399,5 5,7.418 5,10.4V123.6C5,126.582 7.399,129 10.358,129H66.642C69.601,129 72,126.582 72,123.6V10.4C72,7.418 69.601,5 66.642,5Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M66,10H11C10.448,10 10,10.448 10,11V123C10,123.552 10.448,124 11,124H66C66.552,124 67,123.552 67,123V11C67,10.448 66.552,10 66,10ZM11,5C7.686,5 5,7.686 5,11V123C5,126.314 7.686,129 11,129H66C69.314,129 72,126.314 72,123V11C72,7.686 69.314,5 66,5H11Z"
|
||||
android:fillColor="#F29900"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M49.077,15V19.314H54.612L48,25.958L51.037,29L57.692,22.334V27.921H62V15H49.077Z"
|
||||
android:fillColor="#F29900"/>
|
||||
<path
|
||||
android:pathData="M25.963,105L19.308,111.655V106.077H15V119H27.923V114.692H22.366L29,108.037L25.963,105Z"
|
||||
android:fillColor="#F29900"/>
|
||||
</vector>
|
||||
46
res/drawable/ic_illustration_switch.xml
Normal file
46
res/drawable/ic_illustration_switch.xml
Normal file
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="77dp"
|
||||
android:height="134dp"
|
||||
android:viewportWidth="77"
|
||||
android:viewportHeight="134">
|
||||
<path
|
||||
android:pathData="M69.6,1.1H7.4C3.921,1.1 1.1,3.921 1.1,7.4V126.6C1.1,130.079 3.921,132.9 7.4,132.9H69.6C73.079,132.9 75.9,130.079 75.9,126.6V7.4C75.9,3.921 73.079,1.1 69.6,1.1Z"
|
||||
android:strokeWidth="1.8"
|
||||
android:fillColor="#F2F3F4"
|
||||
android:strokeColor="#DADCE0"/>
|
||||
<path
|
||||
android:pathData="M66.642,5H10.358C7.399,5 5,7.418 5,10.4V123.6C5,126.582 7.399,129 10.358,129H66.642C69.601,129 72,126.582 72,123.6V10.4C72,7.418 69.601,5 66.642,5Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M63,94H39V118H63V94Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillAlpha="0.7"/>
|
||||
<path
|
||||
android:pathData="M43,106V114H59V98H51V99.6H57.4V112.4H44.6V106H43Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M49.4,98H43V104.4H49.4V98Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M55.8,105.2V106.8H52.928L56.56,110.432L55.432,111.56L51.8,107.928V110.8H50.2V105.2H55.8Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M66,10H11C10.448,10 10,10.448 10,11V123C10,123.552 10.448,124 11,124H66C66.552,124 67,123.552 67,123V11C67,10.448 66.552,10 66,10ZM11,5C7.686,5 5,7.686 5,11V123C5,126.314 7.686,129 11,129H66C69.314,129 72,126.314 72,123V11C72,7.686 69.314,5 66,5H11Z"
|
||||
android:fillColor="#F29900"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
41
res/drawable/ic_illustration_window.xml
Normal file
41
res/drawable/ic_illustration_window.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="77dp"
|
||||
android:height="134dp"
|
||||
android:viewportWidth="77"
|
||||
android:viewportHeight="134">
|
||||
<path
|
||||
android:pathData="M69.6,1.1H7.4C3.921,1.1 1.1,3.921 1.1,7.4V126.6C1.1,130.079 3.921,132.9 7.4,132.9H69.6C73.079,132.9 75.9,130.079 75.9,126.6V7.4C75.9,3.921 73.079,1.1 69.6,1.1Z"
|
||||
android:strokeWidth="1.8"
|
||||
android:fillColor="#F2F3F4"
|
||||
android:strokeColor="#DADCE0"/>
|
||||
<path
|
||||
android:pathData="M66.642,5H10.358C7.399,5 5,7.418 5,10.4V123.6C5,126.582 7.399,129 10.358,129H66.642C69.601,129 72,126.582 72,123.6V10.4C72,7.418 69.601,5 66.642,5Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M63,48H14C12.895,48 12,48.895 12,50V85C12,86.105 12.895,87 14,87H63C64.105,87 65,86.105 65,85V50C65,48.895 64.105,48 63,48Z"
|
||||
android:strokeLineJoin="bevel"
|
||||
android:strokeWidth="5"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#F29900"/>
|
||||
<path
|
||||
android:pathData="M46.077,54V58.314H51.612L45,64.958L48.037,68L54.692,61.334V66.921H59V54H46.077Z"
|
||||
android:fillColor="#F29900"/>
|
||||
<path
|
||||
android:pathData="M28.963,67L22.308,73.655V68.077H18V81H30.923V76.692H25.366L32,70.037L28.963,67Z"
|
||||
android:fillColor="#F29900"/>
|
||||
</vector>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 The Android Open Source Project
|
||||
<!-- Copyright (C) 2021 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.
|
||||
@@ -18,36 +18,25 @@
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingStart="@dimen/preference_no_icon_padding_start"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/charge"
|
||||
android:id="@+id/chart_summary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:fontFamily="@*android:string/config_headlineFontFamily"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textSize="36sp"
|
||||
android:textColor="?android:attr/colorAccent" />
|
||||
android:layout_marginBottom="45dp"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
settings:textColor="?android:attr/textColorSecondary"
|
||||
android:text="@string/battery_usage_chart_graph_hint" />
|
||||
|
||||
<com.android.settings.widget.UsageView
|
||||
android:id="@+id/battery_usage"
|
||||
<com.android.settings.fuelgauge.BatteryChartView
|
||||
android:id="@+id/battery_chart"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="141dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
settings:sideLabels="@array/battery_labels"
|
||||
android:colorAccent="?android:attr/colorAccent"
|
||||
android:gravity="end"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
settings:textColor="?android:attr/textColorSecondary" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_summary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -15,25 +15,26 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<RelativeLayout
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="true"
|
||||
android:clipChildren="true"
|
||||
android:orientation="vertical">
|
||||
android:clipChildren="true">
|
||||
|
||||
<include
|
||||
android:id="@+id/wifi_dialog_frame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/add_network_button_bar"
|
||||
android:layout_alignParentTop="true"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
layout="@layout/wifi_dialog"/>
|
||||
|
||||
<include
|
||||
android:id="@+id/add_network_button_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
app:layout_constraintTop_toBottomOf="@id/wifi_dialog_frame"
|
||||
layout="@*android:layout/alert_dialog_button_bar_material"/>
|
||||
</RelativeLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -446,4 +446,11 @@
|
||||
|
||||
<!-- Choose SIM Activity dimens -->
|
||||
<dimen name="subtitle_bottom_padding">24dp</dimen>
|
||||
|
||||
<!-- Battery usage chart view component -->
|
||||
<dimen name="chartview_divider_width">1dp</dimen>
|
||||
<dimen name="chartview_divider_height">4dp</dimen>
|
||||
<dimen name="chartview_trapezoid_radius">2dp</dimen>
|
||||
<dimen name="chartview_trapezoid_margin_start">1dp</dimen>
|
||||
<dimen name="chartview_trapezoid_margin_bottom">2dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -2508,9 +2508,11 @@
|
||||
<!-- Summary for the toggle to turn off hotspot automatically [CHAR LIMIT=NONE]-->
|
||||
<string name="wifi_hotspot_auto_off_summary">When no devices are connected</string>
|
||||
<!-- Title for the toggle to enable/disable the maximize compatibility [CHAR LIMIT=NONE]-->
|
||||
<string name="wifi_hotspot_maximize_compatibility">Maximize compatibility</string>
|
||||
<!-- Summary for the toggle to show the maximize compatibility warning message [CHAR LIMIT=NONE]-->
|
||||
<string name="wifi_hotspot_maximize_compatibility_summary">This may reduce speed for devices connected to this hotspot and use more power</string>
|
||||
<string name="wifi_hotspot_maximize_compatibility">Extend compatibility</string>
|
||||
<!-- Summary for the toggle to show the maximize compatibility warning message in single AP device [CHAR LIMIT=NONE]-->
|
||||
<string name="wifi_hotspot_maximize_compatibility_single_ap_summary">Helps other devices find this hotspot. Reduces hotspot connection speed.</string>
|
||||
<!-- Summary for the toggle to show the maximize compatibility warning message in dual AP device [CHAR LIMIT=NONE]-->
|
||||
<string name="wifi_hotspot_maximize_compatibility_dual_ap_summary">Helps other devices find this hotspot. Increases battery usage.</string>
|
||||
|
||||
<!-- Summary text when turning hotspot on -->
|
||||
<string name="wifi_tether_starting">Turning hotspot on\u2026</string>
|
||||
@@ -2942,6 +2944,10 @@
|
||||
<string name="adaptive_sleep_contextual_slice_title">Turn on screen attention</string>
|
||||
<!-- Description about the contextual adaptive sleep card [CHAR LIMIT=NONE]-->
|
||||
<string name="adaptive_sleep_contextual_slice_summary">Keep screen on when looking at it</string>
|
||||
<!-- auto_rotate settings screen, title about the camera privacy lock enabled [CHAR LIMIT=NONE]-->
|
||||
<string name="auto_rotate_camera_lock_title">Camera is locked</string>
|
||||
<!-- Description feature's privacy sensitive details to make sure users understand what feature users, what it saves/sends etc [CHAR LIMIT=NONE]-->
|
||||
<string name="auto_rotate_camera_lock_summary">Camera must be unlocked for Face Detection</string>
|
||||
<!-- auto_rotate settings screen, title about the required permission is missing [CHAR LIMIT=NONE]-->
|
||||
<string name="auto_rotate_summary_no_permission">Camera access is required for Face Detection. Tap to manage permissions for Device Personalization Services</string>
|
||||
<!-- auto_rotate settings screen, text for the camera permission button [CHAR LIMIT=NONE]-->
|
||||
@@ -6348,6 +6354,21 @@
|
||||
<!-- [CHAR_LIMIT=NONE] Battery percentage: Description for preference -->
|
||||
<string name="battery_percentage_description">Show battery percentage in status bar</string>
|
||||
|
||||
<!-- [CHAR_LIMIT=NONE] Battery usage main screen chart graph hint -->
|
||||
<string name="battery_usage_chart_graph_hint">Battery level for past 24 hr</string>
|
||||
<!-- [CHAR_LIMIT=NONE] Battery app usage section header for past 24 hour -->
|
||||
<string name="battery_app_usage_for_past_24">App usage for past 24 hr</string>
|
||||
<!-- [CHAR_LIMIT=NONE] Battery system usage section header for past 24 hour -->
|
||||
<string name="battery_system_usage_for_past_24">System usage for past 24 hr</string>
|
||||
<!-- [CHAR_LIMIT=NONE] Battery system usage section header -->
|
||||
<string name="battery_system_usage_for">System usage for</string>
|
||||
<!-- [CHAR_LIMIT=NONE] Battery app usage section header -->
|
||||
<string name="battery_app_usage_for">App usage for</string>
|
||||
<!-- [CHAR_LIMIT=NONE] Battery usage section header for a specific time slot -->
|
||||
<string name="battery_usage_time_am">am</string>
|
||||
<!-- [CHAR_LIMIT=NONE] Battery usage section header for a specific time slot -->
|
||||
<string name="battery_usage_time_pm">pm</string>
|
||||
|
||||
<!-- Process Stats strings -->
|
||||
<skip />
|
||||
|
||||
|
||||
@@ -26,6 +26,12 @@
|
||||
android:summary="@string/auto_rotate_summary_no_permission"
|
||||
settings:controller="com.android.settings.display.SmartAutoRotatePermissionController" />
|
||||
|
||||
<com.android.settingslib.widget.BannerMessagePreference
|
||||
android:key="camera_lock_state"
|
||||
android:title="@string/auto_rotate_camera_lock_title"
|
||||
android:summary="@string/auto_rotate_camera_lock_summary"
|
||||
settings:controller="com.android.settings.display.SmartAutoRotateCameraStateController" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="face_based_rotate"
|
||||
android:title="@string/auto_rotate_switch_face_based"
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
settings:allowDividerBelow="true" >
|
||||
<Preference
|
||||
android:key="behavior"
|
||||
android:selectable="false"
|
||||
android:summary="@string/important_conversation_behavior_summary"/>
|
||||
<!-- Important conversations added here -->
|
||||
<PreferenceCategory
|
||||
|
||||
@@ -44,6 +44,5 @@
|
||||
|
||||
<SwitchPreference
|
||||
android:key="wifi_tether_maximize_compatibility"
|
||||
android:title="@string/wifi_hotspot_maximize_compatibility"
|
||||
android:summary="@string/wifi_hotspot_maximize_compatibility_summary"/>
|
||||
android:title="@string/wifi_hotspot_maximize_compatibility"/>
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -39,6 +39,7 @@ import android.util.Log;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.Settings.CreateShortcutActivity;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -62,7 +63,7 @@ public class SettingsInitialize extends BroadcastReceiver {
|
||||
final PackageManager pm = context.getPackageManager();
|
||||
managedProfileSetup(context, pm, broadcast, userInfo);
|
||||
webviewSettingSetup(context, pm, userInfo);
|
||||
refreshExistingShortcuts(context);
|
||||
ThreadUtils.postOnBackgroundThread(() -> refreshExistingShortcuts(context));
|
||||
}
|
||||
|
||||
private void managedProfileSetup(Context context, final PackageManager pm, Intent broadcast,
|
||||
@@ -142,5 +143,4 @@ public class SettingsInitialize extends BroadcastReceiver {
|
||||
}
|
||||
shortcutManager.updateShortcuts(updates);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -209,15 +209,15 @@ public class MagnificationSettingsFragment extends DashboardFragment {
|
||||
mModeInfos.clear();
|
||||
mModeInfos.add(new MagnificationModeInfo(getPrefContext().getText(
|
||||
R.string.accessibility_magnification_mode_dialog_option_full_screen), null,
|
||||
R.drawable.accessibility_magnification_full_screen, MagnificationMode.FULLSCREEN));
|
||||
R.drawable.ic_illustration_fullscreen, MagnificationMode.FULLSCREEN));
|
||||
mModeInfos.add(new MagnificationModeInfo(getPrefContext().getText(
|
||||
R.string.accessibility_magnification_mode_dialog_option_window), null,
|
||||
R.drawable.accessibility_magnification_window_screen, MagnificationMode.WINDOW));
|
||||
R.drawable.ic_illustration_window, MagnificationMode.WINDOW));
|
||||
mModeInfos.add(new MagnificationModeInfo(getPrefContext().getText(
|
||||
R.string.accessibility_magnification_mode_dialog_option_switch),
|
||||
getPrefContext().getText(
|
||||
R.string.accessibility_magnification_area_settings_mode_switch_summary),
|
||||
R.drawable.accessibility_magnification_switch, MagnificationMode.ALL));
|
||||
R.drawable.ic_illustration_switch, MagnificationMode.ALL));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
@@ -19,29 +19,29 @@ package com.android.settings.applications.appinfo;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.usb.IUsbManager;
|
||||
import android.os.ServiceManager;
|
||||
import android.content.pm.verify.domain.DomainVerificationManager;
|
||||
import android.content.pm.verify.domain.DomainVerificationUserState;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.applications.intentpicker.AppLaunchSettings;
|
||||
import com.android.settings.applications.intentpicker.IntentPickerUtils;
|
||||
import com.android.settingslib.R;
|
||||
import com.android.settingslib.applications.AppUtils;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
|
||||
public class AppOpenByDefaultPreferenceController extends AppInfoPreferenceControllerBase {
|
||||
|
||||
private IUsbManager mUsbManager;
|
||||
private PackageManager mPackageManager;
|
||||
private final DomainVerificationManager mDomainVerificationManager;
|
||||
private String mPackageName;
|
||||
|
||||
public AppOpenByDefaultPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
mUsbManager = IUsbManager.Stub.asInterface(ServiceManager.getService(Context.USB_SERVICE));
|
||||
mPackageManager = context.getPackageManager();
|
||||
mDomainVerificationManager = context.getSystemService(DomainVerificationManager.class);
|
||||
}
|
||||
|
||||
/** Set a package name for this controller. */
|
||||
@@ -69,8 +69,7 @@ public class AppOpenByDefaultPreferenceController extends AppInfoPreferenceContr
|
||||
&& !AppUtils.isBrowserApp(mContext, packageInfo.packageName,
|
||||
UserHandle.myUserId())) {
|
||||
preference.setVisible(true);
|
||||
preference.setSummary(AppUtils.getLaunchByDefaultSummary(mParent.getAppEntry(),
|
||||
mUsbManager, mPackageManager, mContext));
|
||||
preference.setSummary(getSubtext());
|
||||
} else {
|
||||
preference.setVisible(false);
|
||||
}
|
||||
@@ -80,4 +79,18 @@ public class AppOpenByDefaultPreferenceController extends AppInfoPreferenceContr
|
||||
protected Class<? extends SettingsPreferenceFragment> getDetailFragmentClass() {
|
||||
return AppLaunchSettings.class;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
CharSequence getSubtext() {
|
||||
return mContext.getText(isLinkHandlingAllowed()
|
||||
? R.string.app_link_open_always : R.string.app_link_open_never);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean isLinkHandlingAllowed() {
|
||||
final DomainVerificationUserState userState =
|
||||
IntentPickerUtils.getDomainVerificationUserState(mDomainVerificationManager,
|
||||
mPackageName);
|
||||
return userState == null ? false : userState.isLinkHandlingAllowed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,7 +364,12 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
|
||||
final TextView textView = linearLayout.findViewById(R.id.bt_battery_prediction);
|
||||
if (estimateReady == 1) {
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
textView.setText(StringUtil.formatElapsedTime(mContext, batteryEstimate, false));
|
||||
textView.setText(
|
||||
StringUtil.formatElapsedTime(
|
||||
mContext,
|
||||
batteryEstimate,
|
||||
/* withSeconds */ false,
|
||||
/* collapseTimeUnit */ false));
|
||||
} else {
|
||||
textView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@@ -318,7 +318,10 @@ public class DataUsageSummaryPreference extends Preference {
|
||||
textResourceId = R.string.no_carrier_update_text;
|
||||
}
|
||||
updateTime = StringUtil.formatElapsedTime(
|
||||
getContext(), updateAgeMillis, false /* withSeconds */);
|
||||
getContext(),
|
||||
updateAgeMillis,
|
||||
false /* withSeconds */,
|
||||
false /* collapseTimeUnit */);
|
||||
}
|
||||
carrierInfo.setText(TextUtils.expandTemplate(
|
||||
getContext().getText(textResourceId),
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
package com.android.settings.datetime.timezone.model;
|
||||
|
||||
import android.util.ArraySet;
|
||||
import android.util.TimeUtils;
|
||||
|
||||
import com.android.i18n.timezone.CountryTimeZones;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -31,21 +31,6 @@ import java.util.Set;
|
||||
*/
|
||||
public class FilteredCountryTimeZones {
|
||||
|
||||
/**
|
||||
* The timestamp used to determine which time zones to show to users by using the notUsedAfter
|
||||
* metadata Android holds for each time zone.
|
||||
*
|
||||
* notUsedAfter exists because some time zones effectively "merge" with other time zones after
|
||||
* a given point in time (i.e. they have identical transitions, offsets, etc.). After that
|
||||
* point we only need to show one of the functionally identical ones.
|
||||
*
|
||||
* Rather than using System.currentTimeMillis(), UX folks asked for consistent behavior and so
|
||||
* a timestamp known to be in the recent past is used. This should be updated occasionally but
|
||||
* it doesn't have to be very often.
|
||||
*/
|
||||
private static final Instant MIN_USE_DATE_OF_TIMEZONE =
|
||||
Instant.ofEpochMilli(1546300800000L); // 1/1/2019 00:00 UTC
|
||||
|
||||
private final CountryTimeZones mCountryTimeZones;
|
||||
private final List<String> mPreferredTimeZoneIds;
|
||||
private final Set<String> mAlternativeTimeZoneIds;
|
||||
@@ -56,7 +41,7 @@ public class FilteredCountryTimeZones {
|
||||
Set<String> alternativeTimeZoneIds = new ArraySet<>();
|
||||
for (CountryTimeZones.TimeZoneMapping timeZoneMapping :
|
||||
countryTimeZones.getTimeZoneMappings()) {
|
||||
if (timeZoneMapping.isShownInPickerAt(MIN_USE_DATE_OF_TIMEZONE)) {
|
||||
if (timeZoneMapping.isShownInPickerAt(TimeUtils.MIN_USE_DATE_OF_TIMEZONE)) {
|
||||
String timeZoneId = timeZoneMapping.getTimeZoneId();
|
||||
timeZoneIds.add(timeZoneId);
|
||||
alternativeTimeZoneIds.addAll(timeZoneMapping.getAlternativeIds());
|
||||
|
||||
@@ -60,14 +60,6 @@ public class BluetoothCodecDialogPreferenceController extends
|
||||
((BaseBluetoothDialogPreference) mPreference).setCallback(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHDAudioEnabled(boolean enabled) {
|
||||
if (!enabled) {
|
||||
// If option codec is disabled, SBC is the only only one available codec.
|
||||
onIndexUpdated(convertCfgToBtnIndex(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getSelectableIndex() {
|
||||
List<Integer> index = new ArrayList<>();
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.display;
|
||||
|
||||
import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;
|
||||
|
||||
import static com.android.settings.display.SmartAutoRotateController.isRotationResolverServiceAvailable;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.SensorPrivacyManager;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.widget.BannerMessagePreference;
|
||||
|
||||
/**
|
||||
* The controller of camera based rotate privacy sensor warning preference. The preference appears
|
||||
* when the privacy sensor service disables camera functionality completely.
|
||||
*/
|
||||
public class SmartAutoRotateCameraStateController extends BasePreferenceController {
|
||||
|
||||
private final SensorPrivacyManager mPrivacyManager;
|
||||
private Preference mPreference;
|
||||
|
||||
public SmartAutoRotateCameraStateController(Context context, String key) {
|
||||
super(context, key);
|
||||
mPrivacyManager = SensorPrivacyManager.getInstance(context);
|
||||
mPrivacyManager.addSensorPrivacyListener(CAMERA, enabled -> {
|
||||
mPreference.setVisible(enabled);
|
||||
updateState(mPreference);
|
||||
});
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean isCameraLocked() {
|
||||
return mPrivacyManager.isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
((BannerMessagePreference) mPreference)
|
||||
.setPositiveButtonText(R.string.allow)
|
||||
.setPositiveButtonOnClickListener(v -> {
|
||||
mPrivacyManager.setSensorPrivacy(CAMERA, false);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@AvailabilityStatus
|
||||
public int getAvailabilityStatus() {
|
||||
return isRotationResolverServiceAvailable(mContext)
|
||||
&& isCameraLocked() ? AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.settings.display;
|
||||
|
||||
import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;
|
||||
import static android.provider.Settings.Secure.CAMERA_AUTOROTATE;
|
||||
|
||||
import android.Manifest;
|
||||
@@ -23,12 +24,15 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.hardware.SensorPrivacyManager;
|
||||
import android.provider.Settings;
|
||||
import android.service.rotationresolver.RotationResolverService;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.view.RotationPolicy;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
@@ -41,10 +45,14 @@ public class SmartAutoRotateController extends TogglePreferenceController implem
|
||||
Preference.OnPreferenceChangeListener {
|
||||
|
||||
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
private final SensorPrivacyManager mPrivacyManager;
|
||||
private Preference mPreference;
|
||||
|
||||
public SmartAutoRotateController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
|
||||
mPrivacyManager = SensorPrivacyManager.getInstance(context);
|
||||
mPrivacyManager.addSensorPrivacyListener(CAMERA, enabled -> updateState(mPreference));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,16 +61,39 @@ public class SmartAutoRotateController extends TogglePreferenceController implem
|
||||
return UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
return !RotationPolicy.isRotationLocked(mContext) && hasSufficientPermission(mContext)
|
||||
? AVAILABLE : DISABLED_DEPENDENT_SETTING;
|
||||
&& !isCameraLocked() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
if (preference != null) {
|
||||
preference.setEnabled(getAvailabilityStatus() == AVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Need this because all controller tests use RoboElectric. No easy way to mock this service,
|
||||
* so we mock the call we need
|
||||
*/
|
||||
@VisibleForTesting
|
||||
boolean isCameraLocked() {
|
||||
return mPrivacyManager.isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return hasSufficientPermission(mContext) && Settings.Secure.getInt(
|
||||
return hasSufficientPermission(mContext) && !isCameraLocked() && Settings.Secure.getInt(
|
||||
mContext.getContentResolver(),
|
||||
CAMERA_AUTOROTATE, 0) == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setChecked(boolean isChecked) {
|
||||
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_CAMERA_ROTATE_TOGGLE,
|
||||
|
||||
@@ -19,6 +19,7 @@ import static com.android.settings.display.SmartAutoRotateController.hasSufficie
|
||||
import static com.android.settings.display.SmartAutoRotateController.isRotationResolverServiceAvailable;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.hardware.SensorPrivacyManager;
|
||||
import android.os.Bundle;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -47,6 +48,7 @@ public class SmartAutoRotatePreferenceFragment extends DashboardFragment {
|
||||
private static final String TAG = "SmartAutoRotatePreferenceFragment";
|
||||
|
||||
private RotationPolicy.RotationPolicyListener mRotationPolicyListener;
|
||||
private SensorPrivacyManager mPrivacyManager;
|
||||
private AutoRotateSwitchBarController mSwitchBarController;
|
||||
private static final String FACE_SWITCH_PREFERENCE_ID = "face_based_rotate";
|
||||
|
||||
@@ -66,6 +68,7 @@ public class SmartAutoRotatePreferenceFragment extends DashboardFragment {
|
||||
switchBar.show();
|
||||
mSwitchBarController = new AutoRotateSwitchBarController(activity, switchBar,
|
||||
getSettingsLifecycle());
|
||||
mPrivacyManager = SensorPrivacyManager.getInstance(activity);
|
||||
final Preference footerPreference = findPreference(FooterPreference.KEY_FOOTER);
|
||||
if (footerPreference != null) {
|
||||
footerPreference.setTitle(Html.fromHtml(getString(R.string.smart_rotate_text_headline),
|
||||
@@ -84,9 +87,11 @@ public class SmartAutoRotatePreferenceFragment extends DashboardFragment {
|
||||
public void onChange() {
|
||||
mSwitchBarController.onChange();
|
||||
final boolean isLocked = RotationPolicy.isRotationLocked(getContext());
|
||||
final boolean isCameraLocked = mPrivacyManager.isSensorPrivacyEnabled(
|
||||
SensorPrivacyManager.Sensors.CAMERA);
|
||||
final Preference preference = findPreference(FACE_SWITCH_PREFERENCE_ID);
|
||||
if (preference != null && hasSufficientPermission(getContext())) {
|
||||
preference.setEnabled(!isLocked);
|
||||
preference.setEnabled(!isLocked && !isCameraLocked);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -229,10 +229,18 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
||||
final long backgroundTimeMs = bundle.getLong(EXTRA_BACKGROUND_TIME);
|
||||
mForegroundPreference.setSummary(
|
||||
TextUtils.expandTemplate(getText(R.string.battery_used_for),
|
||||
StringUtil.formatElapsedTime(context, foregroundTimeMs, false)));
|
||||
StringUtil.formatElapsedTime(
|
||||
context,
|
||||
foregroundTimeMs,
|
||||
/* withSeconds */ false,
|
||||
/* collapseTimeUnit */ false)));
|
||||
mBackgroundPreference.setSummary(
|
||||
TextUtils.expandTemplate(getText(R.string.battery_active_for),
|
||||
StringUtil.formatElapsedTime(context, backgroundTimeMs, false)));
|
||||
StringUtil.formatElapsedTime(
|
||||
context,
|
||||
backgroundTimeMs,
|
||||
/* withSeconds */ false,
|
||||
/* collapseTimeUnit */ false)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -380,7 +380,7 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro
|
||||
final long usageTimeMs = entry.getTimeInForegroundMs();
|
||||
if (shouldShowSummary(entry) && usageTimeMs >= DateUtils.MINUTE_IN_MILLIS) {
|
||||
final CharSequence timeSequence =
|
||||
StringUtil.formatElapsedTime(mContext, usageTimeMs, false);
|
||||
StringUtil.formatElapsedTime(mContext, usageTimeMs, false, false);
|
||||
preference.setSummary(
|
||||
entry.isHidden()
|
||||
? timeSequence
|
||||
|
||||
269
src/com/android/settings/fuelgauge/BatteryChartView.java
Normal file
269
src/com/android/settings/fuelgauge/BatteryChartView.java
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
package com.android.settings.fuelgauge;
|
||||
|
||||
import static java.lang.Math.round;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.CornerPathEffect;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.Utils;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/** A widget component to draw chart graph. */
|
||||
public class BatteryChartView extends AppCompatImageView implements View.OnClickListener {
|
||||
private static final String TAG = "BatteryChartView";
|
||||
private static final int DEFAULT_TRAPEZOID_COUNT = 12;
|
||||
/** Selects all trapezoid shapes. */
|
||||
public static final int SELECTED_INDEX_ALL = -1;
|
||||
public static final int SELECTED_INDEX_INVALID = -2;
|
||||
|
||||
/** A callback listener for selected group index is updated. */
|
||||
public interface OnSelectListener {
|
||||
void onSelect(int trapezoidIndex);
|
||||
}
|
||||
|
||||
private int mDividerWidth;
|
||||
private int mDividerHeight;
|
||||
private int mTrapezoidCount;
|
||||
private int mSelectedIndex;
|
||||
private float mTrapezoidVOffset;
|
||||
private float mTrapezoidHOffset;
|
||||
// Colors for drawing the trapezoid shape and dividers.
|
||||
private int mTrapezoidColor;
|
||||
private int mTrapezoidSolidColor;
|
||||
private final int mDividerColor = Color.parseColor("#CDCCC5");
|
||||
|
||||
private int[] mLevels;
|
||||
private Paint mDividerPaint;
|
||||
private Paint mTrapezoidPaint;
|
||||
private TrapezoidSlot[] mTrapezoidSlot;
|
||||
// Records the location to calculate selected index.
|
||||
private MotionEvent mTouchUpEvent;
|
||||
private BatteryChartView.OnSelectListener mOnSelectListener;
|
||||
|
||||
public BatteryChartView(Context context) {
|
||||
super(context, null);
|
||||
}
|
||||
|
||||
public BatteryChartView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initializeColors(context);
|
||||
setOnClickListener(this);
|
||||
setSelectedIndex(SELECTED_INDEX_ALL);
|
||||
setTrapezoidCount(DEFAULT_TRAPEZOID_COUNT);
|
||||
}
|
||||
|
||||
/** Sets the total trapezoid count for drawing. */
|
||||
public void setTrapezoidCount(int trapezoidCount) {
|
||||
Log.i(TAG, "trapezoidCount:" + trapezoidCount);
|
||||
mTrapezoidCount = trapezoidCount;
|
||||
mTrapezoidSlot = new TrapezoidSlot[trapezoidCount];
|
||||
// Allocates the trapezoid slot array.
|
||||
for (int index = 0; index < trapezoidCount; index++) {
|
||||
mTrapezoidSlot[index] = new TrapezoidSlot();
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/** Sets all levels value to draw the trapezoid shape */
|
||||
public void setLevels(int[] levels) {
|
||||
// We should provide trapezoid count + 1 data to draw all trapezoids.
|
||||
mLevels = levels.length == mTrapezoidCount + 1 ? levels : null;
|
||||
setClickable(mLevels != null);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/** Sets the selected group index to draw highlight effect. */
|
||||
public void setSelectedIndex(int index) {
|
||||
if (mSelectedIndex != index) {
|
||||
mSelectedIndex = index;
|
||||
invalidate();
|
||||
// Callbacks to the listener if we have.
|
||||
if (mOnSelectListener != null) {
|
||||
mOnSelectListener.onSelect(mSelectedIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets the callback to monitor the selected group index. */
|
||||
public void setOnSelectListener(BatteryChartView.OnSelectListener listener) {
|
||||
mOnSelectListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
super.draw(canvas);
|
||||
drawHorizontalDividers(canvas);
|
||||
drawVerticalDividers(canvas);
|
||||
drawTrapezoids(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
// Caches the location to calculate selected trapezoid index.
|
||||
final int action = event.getAction();
|
||||
if (action == MotionEvent.ACTION_UP) {
|
||||
mTouchUpEvent = MotionEvent.obtain(event);
|
||||
} else if (action == MotionEvent.ACTION_CANCEL) {
|
||||
mTouchUpEvent = null; // reset
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mTouchUpEvent == null) {
|
||||
Log.w(TAG, "invalid motion event for onClick() callback");
|
||||
return;
|
||||
}
|
||||
final int trapezoidIndex = getTrapezoidIndex(mTouchUpEvent.getX());
|
||||
// Selects all if users click the same trapezoid item two times.
|
||||
if (trapezoidIndex == mSelectedIndex) {
|
||||
setSelectedIndex(SELECTED_INDEX_ALL);
|
||||
} else {
|
||||
setSelectedIndex(trapezoidIndex);
|
||||
}
|
||||
view.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK);
|
||||
}
|
||||
|
||||
private void initializeColors(Context context) {
|
||||
setBackgroundColor(Color.TRANSPARENT);
|
||||
mTrapezoidSolidColor = Utils.getColorAccentDefaultColor(context);
|
||||
mTrapezoidColor = Utils.getDisabled(context, mTrapezoidSolidColor);
|
||||
// Initializes the divider line paint.
|
||||
final Resources resources = getContext().getResources();
|
||||
mDividerWidth = resources.getDimensionPixelSize(R.dimen.chartview_divider_width);
|
||||
mDividerHeight = resources.getDimensionPixelSize(R.dimen.chartview_divider_height);
|
||||
mDividerPaint = new Paint();
|
||||
mDividerPaint.setAntiAlias(true);
|
||||
mDividerPaint.setColor(mDividerColor);
|
||||
mDividerPaint.setStyle(Paint.Style.STROKE);
|
||||
mDividerPaint.setStrokeWidth(mDividerWidth);
|
||||
Log.i(TAG, "mDividerWidth:" + mDividerWidth);
|
||||
Log.i(TAG, "mDividerHeight:" + mDividerHeight);
|
||||
// Initializes the trapezoid paint.
|
||||
mTrapezoidHOffset = resources.getDimension(R.dimen.chartview_trapezoid_margin_start);
|
||||
mTrapezoidVOffset = resources.getDimension(R.dimen.chartview_trapezoid_margin_bottom);
|
||||
mTrapezoidPaint = new Paint();
|
||||
mTrapezoidPaint.setAntiAlias(true);
|
||||
mTrapezoidPaint.setColor(mTrapezoidSolidColor);
|
||||
mTrapezoidPaint.setStyle(Paint.Style.FILL);
|
||||
mTrapezoidPaint.setPathEffect(
|
||||
new CornerPathEffect(
|
||||
resources.getDimensionPixelSize(R.dimen.chartview_trapezoid_radius)));
|
||||
}
|
||||
|
||||
private void drawHorizontalDividers(Canvas canvas) {
|
||||
// Draws the top divider line for 100% curve.
|
||||
float offsetY = mDividerWidth * 0.5f;
|
||||
canvas.drawLine(0, offsetY, getWidth(), offsetY, mDividerPaint);
|
||||
// Draws the center divider line for 50% curve.
|
||||
final float availableSpace =
|
||||
getHeight() - mDividerWidth * 2 - mTrapezoidVOffset - mDividerHeight;
|
||||
offsetY = mDividerWidth + availableSpace * 0.5f;
|
||||
canvas.drawLine(0, offsetY, getWidth(), offsetY, mDividerPaint);
|
||||
// Draws the center divider line for 0% curve.
|
||||
offsetY = getHeight() - mDividerHeight - mDividerWidth * 0.5f;
|
||||
canvas.drawLine(0, offsetY, getWidth(), offsetY, mDividerPaint);
|
||||
}
|
||||
|
||||
private void drawVerticalDividers(Canvas canvas) {
|
||||
final int dividerCount = mTrapezoidCount + 1;
|
||||
final float dividerSpace = dividerCount * mDividerWidth;
|
||||
final float unitWidth = (getWidth() - dividerSpace) / (float) mTrapezoidCount;
|
||||
final float startY = getHeight() - mDividerHeight;
|
||||
final float trapezoidSlotOffset = mTrapezoidHOffset + mDividerWidth * 0.5f;
|
||||
// Draws each vertical dividers.
|
||||
float startX = mDividerWidth * 0.5f;
|
||||
for (int index = 0; index < dividerCount; index++) {
|
||||
canvas.drawLine(startX, startY, startX, getHeight(), mDividerPaint);
|
||||
final float nextX = startX + mDividerWidth + unitWidth;
|
||||
// Updates the trapezoid slots for drawing.
|
||||
if (index < mTrapezoidSlot.length) {
|
||||
mTrapezoidSlot[index].mLeft = round(startX + trapezoidSlotOffset);
|
||||
mTrapezoidSlot[index].mRight = round(nextX - trapezoidSlotOffset);
|
||||
}
|
||||
startX = nextX;
|
||||
}
|
||||
}
|
||||
|
||||
private void drawTrapezoids(Canvas canvas) {
|
||||
// Ignores invalid trapezoid data.
|
||||
if (mLevels == null) {
|
||||
return;
|
||||
}
|
||||
final float trapezoidBottom =
|
||||
getHeight() - mDividerHeight - mDividerWidth - mTrapezoidVOffset;
|
||||
final float availableSpace = trapezoidBottom - mDividerWidth;
|
||||
final float unitHeight = availableSpace / 100f;
|
||||
// Draws all trapezoid shapes into the canvas.
|
||||
final Path trapezoidPath = new Path();
|
||||
for (int index = 0; index < mTrapezoidCount; index++) {
|
||||
// Configures the trapezoid paint color.
|
||||
mTrapezoidPaint.setColor(
|
||||
mSelectedIndex == index || mSelectedIndex == SELECTED_INDEX_ALL
|
||||
? mTrapezoidSolidColor
|
||||
: mTrapezoidColor);
|
||||
final float leftTop = round(trapezoidBottom - mLevels[index] * unitHeight);
|
||||
final float rightTop = round(trapezoidBottom - mLevels[index + 1] * unitHeight);
|
||||
trapezoidPath.reset();
|
||||
trapezoidPath.moveTo(mTrapezoidSlot[index].mLeft, trapezoidBottom);
|
||||
trapezoidPath.lineTo(mTrapezoidSlot[index].mLeft, leftTop);
|
||||
trapezoidPath.lineTo(mTrapezoidSlot[index].mRight, rightTop);
|
||||
trapezoidPath.lineTo(mTrapezoidSlot[index].mRight, trapezoidBottom);
|
||||
// A tricky way to make the trapezoid shape drawing the rounded corner.
|
||||
trapezoidPath.lineTo(mTrapezoidSlot[index].mLeft, trapezoidBottom);
|
||||
trapezoidPath.lineTo(mTrapezoidSlot[index].mLeft, leftTop);
|
||||
// Draws the trapezoid shape into canvas.
|
||||
canvas.drawPath(trapezoidPath, mTrapezoidPaint);
|
||||
}
|
||||
}
|
||||
|
||||
// Searches the corresponding trapezoid index from x location.
|
||||
private int getTrapezoidIndex(float x) {
|
||||
for (int index = 0; index < mTrapezoidSlot.length; index++) {
|
||||
final TrapezoidSlot slot = mTrapezoidSlot[index];
|
||||
if (x >= slot.mLeft && x <= slot.mRight) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return SELECTED_INDEX_INVALID;
|
||||
}
|
||||
|
||||
// A container class for each trapezoid left and right location.
|
||||
private static final class TrapezoidSlot {
|
||||
public float mLeft;
|
||||
public float mRight;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(Locale.US, "TrapezoidSlot[%f,%f]", mLeft, mRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
112
src/com/android/settings/fuelgauge/BatteryHistEntry.java
Normal file
112
src/com/android/settings/fuelgauge/BatteryHistEntry.java
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
package com.android.settings.fuelgauge;
|
||||
|
||||
import android.content.ContentValues;
|
||||
|
||||
/** A container class to carry data from {@link ContentValues}. */
|
||||
public final class BatteryHistEntry {
|
||||
private static final String TAG = "BatteryHistEntry";
|
||||
|
||||
public final long mUid;
|
||||
public final long mUserId;
|
||||
public final String mAppLabel;
|
||||
public final String mPackageName;
|
||||
// Whether the data is represented as system component or not?
|
||||
public final boolean mIsHidden;
|
||||
// Records the timestamp relative information.
|
||||
public final long mTimestamp;
|
||||
public final String mZoneId;
|
||||
// Records the battery usage relative information.
|
||||
public final double mTotalPower;
|
||||
public final double mConsumePower;
|
||||
public final double mPercentOfTotal;
|
||||
public final long mForegroundUsageTimeInMs;
|
||||
public final long mBackgroundUsageTimeInMs;
|
||||
public final int mDrainType;
|
||||
public final int mConsumerType;
|
||||
// Records the battery intent relative information.
|
||||
public final int mBatteryLevel;
|
||||
public final int mBatteryStatus;
|
||||
public final int mBatteryHealth;
|
||||
|
||||
private boolean mIsValidEntry = true;
|
||||
private ContentValues mContentValues;
|
||||
|
||||
public BatteryHistEntry(ContentValues contentValues) {
|
||||
mContentValues = contentValues;
|
||||
mUid = getLong("uid");
|
||||
mUserId = getLong("userId");
|
||||
mAppLabel = getString("appLabel");
|
||||
mPackageName = getString("packageName");
|
||||
mIsHidden = getBoolean("isHidden");
|
||||
mTimestamp = getLong("timestamp");
|
||||
mZoneId = getString("zoneId");
|
||||
mTotalPower = getDouble("totalPower");
|
||||
mConsumePower = getDouble("consumePower");
|
||||
mPercentOfTotal = getDouble("percentOfTotal");
|
||||
mForegroundUsageTimeInMs = getLong("foregroundUsageTimeInMs");
|
||||
mBackgroundUsageTimeInMs = getLong("backgroundUsageTimeInMs");
|
||||
mDrainType = getInteger("drainType");
|
||||
mConsumerType = getInteger("consumerType");
|
||||
mBatteryLevel = getInteger("batteryLevel");
|
||||
mBatteryStatus = getInteger("batteryStatus");
|
||||
mBatteryHealth = getInteger("batteryHealth");
|
||||
}
|
||||
|
||||
/** Whether this {@link BatteryHistEntry} is valid or not? */
|
||||
public boolean isValidEntry() {
|
||||
return mIsValidEntry;
|
||||
}
|
||||
|
||||
private int getInteger(String key) {
|
||||
if (mContentValues != null && mContentValues.containsKey(key)) {
|
||||
return mContentValues.getAsInteger(key);
|
||||
};
|
||||
mIsValidEntry = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
private long getLong(String key) {
|
||||
if (mContentValues != null && mContentValues.containsKey(key)) {
|
||||
return mContentValues.getAsLong(key);
|
||||
}
|
||||
mIsValidEntry = false;
|
||||
return -1L;
|
||||
}
|
||||
|
||||
private double getDouble(String key) {
|
||||
if (mContentValues != null && mContentValues.containsKey(key)) {
|
||||
return mContentValues.getAsDouble(key);
|
||||
}
|
||||
mIsValidEntry = false;
|
||||
return 0f;
|
||||
}
|
||||
|
||||
private String getString(String key) {
|
||||
if (mContentValues != null && mContentValues.containsKey(key)) {
|
||||
return mContentValues.getAsString(key);
|
||||
}
|
||||
mIsValidEntry = false;
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean getBoolean(String key) {
|
||||
if (mContentValues != null && mContentValues.containsKey(key)) {
|
||||
return mContentValues.getAsBoolean(key);
|
||||
}
|
||||
mIsValidEntry = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,8 @@ package com.android.settings.fuelgauge;
|
||||
import android.content.Context;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
@@ -28,26 +28,26 @@ import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.widget.UsageView;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
|
||||
/**
|
||||
* Custom preference for displaying power consumption as a bar and an icon on the left for the
|
||||
* subsystem/app type.
|
||||
* Custom preference for displaying the battery level as chart graph.
|
||||
*/
|
||||
public class BatteryHistoryPreference extends Preference {
|
||||
private static final String TAG = "BatteryHistoryPreference";
|
||||
|
||||
private CharSequence mSummary;
|
||||
private TextView mSummaryView;
|
||||
|
||||
@VisibleForTesting
|
||||
boolean hideSummary;
|
||||
@VisibleForTesting
|
||||
BatteryInfo mBatteryInfo;
|
||||
|
||||
public BatteryHistoryPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setLayoutResource(R.layout.battery_usage_graph);
|
||||
final boolean isChartGraphEnabled =
|
||||
FeatureFactory.getFactory(context).getPowerUsageFeatureProvider(context)
|
||||
.isChartGraphEnabled(context);
|
||||
Log.i(TAG, "isChartGraphEnabled: " + isChartGraphEnabled);
|
||||
if (isChartGraphEnabled) {
|
||||
setLayoutResource(R.layout.battery_chart_graph);
|
||||
}
|
||||
setSelectable(false);
|
||||
}
|
||||
|
||||
@@ -58,22 +58,6 @@ public class BatteryHistoryPreference extends Preference {
|
||||
}, batteryUsageStats, false);
|
||||
}
|
||||
|
||||
public void setBottomSummary(CharSequence text) {
|
||||
mSummary = text;
|
||||
if (mSummaryView != null) {
|
||||
mSummaryView.setVisibility(View.VISIBLE);
|
||||
mSummaryView.setText(mSummary);
|
||||
}
|
||||
hideSummary = false;
|
||||
}
|
||||
|
||||
public void hideBottomSummary() {
|
||||
if (mSummaryView != null) {
|
||||
mSummaryView.setVisibility(View.GONE);
|
||||
}
|
||||
hideSummary = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder view) {
|
||||
super.onBindViewHolder(view);
|
||||
@@ -81,18 +65,6 @@ public class BatteryHistoryPreference extends Preference {
|
||||
if (mBatteryInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
((TextView) view.findViewById(R.id.charge)).setText(mBatteryInfo.batteryPercentString);
|
||||
mSummaryView = (TextView) view.findViewById(R.id.bottom_summary);
|
||||
if (mSummary != null) {
|
||||
mSummaryView.setText(mSummary);
|
||||
}
|
||||
if (hideSummary) {
|
||||
mSummaryView.setVisibility(View.GONE);
|
||||
}
|
||||
UsageView usageView = (UsageView) view.findViewById(R.id.battery_usage);
|
||||
usageView.findViewById(R.id.label_group).setAlpha(.7f);
|
||||
mBatteryInfo.bindHistory(usageView);
|
||||
BatteryUtils.logRuntime(TAG, "onBindViewHolder", startTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,8 +263,11 @@ public class BatteryInfo {
|
||||
context.getString(chargingLimitedResId, info.batteryPercentString);
|
||||
} else if (chargeTimeMs > 0 && status != BatteryManager.BATTERY_STATUS_FULL) {
|
||||
info.remainingTimeUs = PowerUtil.convertMsToUs(chargeTimeMs);
|
||||
CharSequence timeString = StringUtil.formatElapsedTime(context,
|
||||
PowerUtil.convertUsToMs(info.remainingTimeUs), false /* withSeconds */);
|
||||
final CharSequence timeString = StringUtil.formatElapsedTime(
|
||||
context,
|
||||
PowerUtil.convertUsToMs(info.remainingTimeUs),
|
||||
false /* withSeconds */,
|
||||
true /* collapseTimeUnit */);
|
||||
int resId = R.string.power_charging_duration;
|
||||
info.remainingLabel = context.getString(
|
||||
R.string.power_remaining_charging_duration_only, timeString);
|
||||
@@ -287,7 +290,7 @@ public class BatteryInfo {
|
||||
context,
|
||||
PowerUtil.convertUsToMs(drainTimeUs),
|
||||
null /* percentageString */,
|
||||
estimate.isBasedOnUsage() && !shortString
|
||||
false /* basedOnUsage */
|
||||
);
|
||||
info.chargeLabel = PowerUtil.getBatteryRemainingStringFormatted(
|
||||
context,
|
||||
|
||||
105
src/com/android/settings/fuelgauge/ConvertUtils.java
Normal file
105
src/com/android/settings/fuelgauge/ConvertUtils.java
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.annotation.IntDef;
|
||||
import android.content.ContentValues;
|
||||
import android.os.BatteryConsumer;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.SystemBatteryConsumer;
|
||||
import android.os.UidBatteryConsumer;
|
||||
import android.os.UserBatteryConsumer;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/** A utility class to convert data into another types. */
|
||||
public final class ConvertUtils {
|
||||
private static final String TAG = "ConvertUtils";
|
||||
/** Invalid system battery consumer drain type. */
|
||||
public static final int INVALID_DRAIN_TYPE = -1;
|
||||
|
||||
@IntDef(prefix = {"CONSUMER_TYPE"}, value = {
|
||||
CONSUMER_TYPE_UNKNOWN,
|
||||
CONSUMER_TYPE_UID_BATTERY,
|
||||
CONSUMER_TYPE_USER_BATTERY,
|
||||
CONSUMER_TYPE_SYSTEM_BATTERY,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public static @interface ConsumerType {}
|
||||
|
||||
public static final int CONSUMER_TYPE_UNKNOWN = 0;
|
||||
public static final int CONSUMER_TYPE_UID_BATTERY = 1;
|
||||
public static final int CONSUMER_TYPE_USER_BATTERY = 2;
|
||||
public static final int CONSUMER_TYPE_SYSTEM_BATTERY = 3;
|
||||
|
||||
/** Gets consumer type from {@link BatteryConsumer}. */
|
||||
@ConsumerType
|
||||
public static int getConsumerType(BatteryConsumer consumer) {
|
||||
if (consumer instanceof UidBatteryConsumer) {
|
||||
return CONSUMER_TYPE_UID_BATTERY;
|
||||
} else if (consumer instanceof UserBatteryConsumer) {
|
||||
return CONSUMER_TYPE_USER_BATTERY;
|
||||
} else if (consumer instanceof SystemBatteryConsumer) {
|
||||
return CONSUMER_TYPE_SYSTEM_BATTERY;
|
||||
} else {
|
||||
return CONSUMER_TYPE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets battery drain type for {@link SystemBatteryConsumer}. */
|
||||
public static int getDrainType(BatteryConsumer consumer) {
|
||||
if (consumer instanceof SystemBatteryConsumer) {
|
||||
return ((SystemBatteryConsumer) consumer).getDrainType();
|
||||
}
|
||||
return INVALID_DRAIN_TYPE;
|
||||
}
|
||||
|
||||
public static ContentValues convert(
|
||||
BatteryEntry entry,
|
||||
BatteryUsageStats batteryUsageStats,
|
||||
int batteryLevel,
|
||||
int batteryStatus,
|
||||
int batteryHealth,
|
||||
long timestamp) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put("uid", Long.valueOf(entry.getUid()));
|
||||
values.put("userId",
|
||||
Long.valueOf(UserHandle.getUserId(entry.getUid())));
|
||||
values.put("appLabel", entry.getLabel());
|
||||
values.put("packageName", entry.getDefaultPackageName());
|
||||
values.put("isHidden", Boolean.valueOf(entry.isHidden()));
|
||||
values.put("timestamp", Long.valueOf(timestamp));
|
||||
values.put("zoneId", TimeZone.getDefault().getID());
|
||||
values.put("totalPower",
|
||||
Double.valueOf(batteryUsageStats.getConsumedPower()));
|
||||
values.put("consumePower", Double.valueOf(entry.getConsumedPower()));
|
||||
values.put("percentOfTotal", Double.valueOf(entry.percent));
|
||||
values.put("foregroundUsageTimeInMs",
|
||||
Long.valueOf(entry.getTimeInForegroundMs()));
|
||||
values.put("backgroundUsageTimeInMs",
|
||||
Long.valueOf(entry.getTimeInBackgroundMs()));
|
||||
values.put("drainType", getDrainType(entry.getBatteryConsumer()));
|
||||
values.put("consumerType", getConsumerType(entry.getBatteryConsumer()));
|
||||
values.put("batteryLevel", Integer.valueOf(batteryLevel));
|
||||
values.put("batteryStatus", Integer.valueOf(batteryStatus));
|
||||
values.put("batteryHealth", Integer.valueOf(batteryHealth));
|
||||
return values;
|
||||
}
|
||||
|
||||
private ConvertUtils() {}
|
||||
}
|
||||
@@ -17,14 +17,9 @@ import static com.android.settings.fuelgauge.BatteryBroadcastReceiver.BatteryUpd
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Bundle;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
@@ -44,16 +39,11 @@ public class PowerUsageAdvanced extends PowerUsageBase {
|
||||
private static final String TAG = "AdvancedBatteryUsage";
|
||||
private static final String KEY_BATTERY_GRAPH = "battery_graph";
|
||||
private static final String KEY_APP_LIST = "app_list";
|
||||
private static final String KEY_SHOW_ALL_APPS = "show_all_apps";
|
||||
@VisibleForTesting
|
||||
static final int MENU_TOGGLE_APPS = Menu.FIRST + 1;
|
||||
|
||||
@VisibleForTesting
|
||||
BatteryHistoryPreference mHistPref;
|
||||
private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
|
||||
private BatteryAppListPreferenceController mBatteryAppListPreferenceController;
|
||||
@VisibleForTesting
|
||||
boolean mShowAllApps = false;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
@@ -63,10 +53,6 @@ public class PowerUsageAdvanced extends PowerUsageBase {
|
||||
mHistPref = (BatteryHistoryPreference) findPreference(KEY_BATTERY_GRAPH);
|
||||
mPowerUsageFeatureProvider = FeatureFactory.getFactory(context)
|
||||
.getPowerUsageFeatureProvider(context);
|
||||
|
||||
// init the summary so other preferences won't have unnecessary move
|
||||
updateHistPrefSummary(context);
|
||||
restoreSavedInstance(icicle);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,42 +78,6 @@ public class PowerUsageAdvanced extends PowerUsageBase {
|
||||
return R.xml.power_usage_advanced;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
menu.add(Menu.NONE, MENU_TOGGLE_APPS, Menu.NONE,
|
||||
mShowAllApps ? R.string.hide_extra_apps : R.string.show_all_apps);
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case MENU_TOGGLE_APPS:
|
||||
mShowAllApps = !mShowAllApps;
|
||||
item.setTitle(mShowAllApps ? R.string.hide_extra_apps : R.string.show_all_apps);
|
||||
mMetricsFeatureProvider.action(getContext(),
|
||||
SettingsEnums.ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE,
|
||||
mShowAllApps);
|
||||
restartBatteryStatsLoader(BatteryUpdateType.MANUAL);
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void restoreSavedInstance(Bundle savedInstance) {
|
||||
if (savedInstance != null) {
|
||||
mShowAllApps = savedInstance.getBoolean(KEY_SHOW_ALL_APPS, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putBoolean(KEY_SHOW_ALL_APPS, mShowAllApps);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
@@ -151,22 +101,7 @@ public class PowerUsageAdvanced extends PowerUsageBase {
|
||||
return;
|
||||
}
|
||||
updatePreference(mHistPref);
|
||||
updateHistPrefSummary(context);
|
||||
|
||||
mBatteryAppListPreferenceController.refreshAppListGroup(mBatteryUsageStats, mShowAllApps);
|
||||
}
|
||||
|
||||
private void updateHistPrefSummary(Context context) {
|
||||
Intent batteryIntent =
|
||||
context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||
final boolean plugged = batteryIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) != 0;
|
||||
|
||||
if (mPowerUsageFeatureProvider.isEnhancedBatteryPredictionEnabled(context) && !plugged) {
|
||||
mHistPref.setBottomSummary(
|
||||
mPowerUsageFeatureProvider.getAdvancedUsageScreenInfoString());
|
||||
} else {
|
||||
mHistPref.hideBottomSummary();
|
||||
}
|
||||
mBatteryAppListPreferenceController.refreshAppListGroup(mBatteryUsageStats, true);
|
||||
}
|
||||
|
||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
|
||||
@@ -124,4 +124,9 @@ public interface PowerUsageFeatureProvider {
|
||||
* Checks whether smart battery feature is supported in this device
|
||||
*/
|
||||
boolean isSmartBatterySupported();
|
||||
|
||||
/**
|
||||
* Checks whether we should enable chart graph design or not
|
||||
*/
|
||||
boolean isChartGraphEnabled(Context context);
|
||||
}
|
||||
|
||||
@@ -150,4 +150,9 @@ public class PowerUsageFeatureProviderImpl implements PowerUsageFeatureProvider
|
||||
return mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_smart_battery_available);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChartGraphEnabled(Context context) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,10 +149,16 @@ public class BackupCallingPreferenceController extends TelephonyTogglePreference
|
||||
|
||||
private boolean hasBackupCallingFeature(int subscriptionId) {
|
||||
PersistableBundle carrierConfig = getCarrierConfigForSubId(subscriptionId);
|
||||
return (carrierConfig != null)
|
||||
&& carrierConfig.getBoolean(
|
||||
Boolean featureEnableStatus = null;
|
||||
if (carrierConfig != null) {
|
||||
featureEnableStatus = carrierConfig.getBoolean(
|
||||
CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL, false);
|
||||
}
|
||||
// TODO: remove log after fixing b/182326102
|
||||
Log.d(LOG_TAG, "config " + CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL
|
||||
+ "=" + featureEnableStatus + " for subId=" + mSubId);
|
||||
return (featureEnableStatus != null) && featureEnableStatus.booleanValue();
|
||||
}
|
||||
|
||||
private ImsMmTelManager getImsMmTelManager(int subId) {
|
||||
if (!SubscriptionManager.isUsableSubscriptionId(subId)) {
|
||||
|
||||
@@ -214,6 +214,8 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
// TODO: remove log after fixing b/182326102
|
||||
Log.d(LOG_TAG, "onResume() subId=" + mSubId);
|
||||
if (mActiveSubsciptionsListener == null) {
|
||||
mActiveSubsciptionsListener = new ActiveSubsciptionsListener(
|
||||
getContext().getMainLooper(), getContext(), mSubId) {
|
||||
|
||||
@@ -55,6 +55,7 @@ public class AllConversationsPreferenceController extends ConversationListPrefer
|
||||
Preference pref = new Preference(mContext);
|
||||
pref.setOrder(1);
|
||||
pref.setSummary(R.string.other_conversations_summary);
|
||||
pref.setSelectable(false);
|
||||
return pref;
|
||||
}
|
||||
|
||||
|
||||
@@ -480,7 +480,7 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle
|
||||
return mContext.getString(R.string.wifi_time_remaining, StringUtil.formatElapsedTime(
|
||||
mContext,
|
||||
Duration.between(now, expiryTime).getSeconds() * 1000,
|
||||
false /* withSeconds */));
|
||||
false /* withSeconds */, false /* collapseTimeUnit */));
|
||||
}
|
||||
|
||||
// For more than 2 days, show the expiry date
|
||||
|
||||
@@ -24,6 +24,8 @@ import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
/**
|
||||
* This controller helps to manage the state of maximize compatibility switch preference.
|
||||
*/
|
||||
@@ -53,6 +55,9 @@ public class WifiTetherMaximizeCompatibilityPreferenceController extends
|
||||
}
|
||||
mPreference.setEnabled(is5GhzBandSupported());
|
||||
((SwitchPreference) mPreference).setChecked(mIsChecked);
|
||||
mPreference.setSummary(mWifiManager.isBridgedApConcurrencySupported()
|
||||
? R.string.wifi_hotspot_maximize_compatibility_dual_ap_summary
|
||||
: R.string.wifi_hotspot_maximize_compatibility_single_ap_summary);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
@@ -33,6 +34,7 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.verify.domain.DomainVerificationManager;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
@@ -66,6 +68,8 @@ public class AppOpenByDefaultPreferenceControllerTest {
|
||||
private Preference mPreference;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private DomainVerificationManager mDomainVerificationManager;
|
||||
|
||||
private Context mContext;
|
||||
private AppOpenByDefaultPreferenceController mController;
|
||||
@@ -78,6 +82,8 @@ public class AppOpenByDefaultPreferenceControllerTest {
|
||||
mController.setParentFragment(mFragment);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||
when(mContext.getSystemService(DomainVerificationManager.class)).thenReturn(
|
||||
mDomainVerificationManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -194,10 +200,27 @@ public class AppOpenByDefaultPreferenceControllerTest {
|
||||
final AppEntry appEntry = mock(AppEntry.class);
|
||||
appEntry.info = new ApplicationInfo();
|
||||
when(mFragment.getAppEntry()).thenReturn(appEntry);
|
||||
doReturn(true).when(mController).isLinkHandlingAllowed();
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setVisible(true);
|
||||
verify(mPreference).setSummary(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSubtext_allowedLinkHandling_returnAllowedString() {
|
||||
final String allowdedString = "Allow app to open supported links";
|
||||
doReturn(true).when(mController).isLinkHandlingAllowed();
|
||||
|
||||
assertThat(mController.getSubtext()).isEqualTo(allowdedString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSubtext_notAllowedLinkHandling_returnNotAllowedString() {
|
||||
final String notAllowdedString = "Don’t allow app to open links";
|
||||
doReturn(false).when(mController).isLinkHandlingAllowed();
|
||||
|
||||
assertThat(mController.getSubtext()).isEqualTo(notAllowdedString);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,9 +473,9 @@ public class AdvancedBluetoothDetailsHeaderControllerTest {
|
||||
@Test
|
||||
public void showBatteryPredictionIfNecessary_estimateReadyIsAvailable_showCorrectValue() {
|
||||
final String leftBatteryPrediction =
|
||||
StringUtil.formatElapsedTime(mContext, 12000000, false).toString();
|
||||
StringUtil.formatElapsedTime(mContext, 12000000, false, false).toString();
|
||||
final String rightBatteryPrediction =
|
||||
StringUtil.formatElapsedTime(mContext, 1200000, false).toString();
|
||||
StringUtil.formatElapsedTime(mContext, 1200000, false, false).toString();
|
||||
|
||||
mController.showBatteryPredictionIfNecessary(1, 12000000,
|
||||
mLayoutPreference.findViewById(R.id.layout_left));
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.display;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
|
||||
import com.android.settings.testutils.ResolveInfoBuilder;
|
||||
import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = ShadowSensorPrivacyManager.class)
|
||||
public class SmartAutoRotateCameraStateControllerTest {
|
||||
|
||||
private static final String PACKAGE_NAME = "package_name";
|
||||
|
||||
private SmartAutoRotateCameraStateController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
final Context context = Mockito.spy(RuntimeEnvironment.application);
|
||||
final ContentResolver contentResolver = RuntimeEnvironment.application.getContentResolver();
|
||||
when(context.getContentResolver()).thenReturn(contentResolver);
|
||||
final PackageManager packageManager = Mockito.mock(PackageManager.class);
|
||||
when(context.getPackageManager()).thenReturn(packageManager);
|
||||
doReturn(PACKAGE_NAME).when(packageManager).getRotationResolverPackageName();
|
||||
mController = new SmartAutoRotateCameraStateController(context, "smart_auto_rotate");
|
||||
when(mController.isCameraLocked()).thenReturn(false);
|
||||
|
||||
final ResolveInfo resolveInfo = new ResolveInfoBuilder(PACKAGE_NAME).build();
|
||||
resolveInfo.serviceInfo = new ServiceInfo();
|
||||
when(packageManager.resolveService(any(), anyInt())).thenReturn(resolveInfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_returnUnsupportedOnDevice() {
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_cameraNotEnabled_returnAvailableUnSearchAble() {
|
||||
when(mController.isCameraLocked()).thenReturn(true);
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ import android.provider.Settings;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.testutils.ResolveInfoBuilder;
|
||||
import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -48,8 +49,10 @@ import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = ShadowSensorPrivacyManager.class)
|
||||
public class SmartAutoRotateControllerTest {
|
||||
|
||||
private static final String PACKAGE_NAME = "package_name";
|
||||
@@ -72,6 +75,7 @@ public class SmartAutoRotateControllerTest {
|
||||
doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission(
|
||||
Manifest.permission.CAMERA, PACKAGE_NAME);
|
||||
mController = new SmartAutoRotateController(context, "test_key");
|
||||
when(mController.isCameraLocked()).thenReturn(false);
|
||||
doReturn(mController.getPreferenceKey()).when(mPreference).getKey();
|
||||
|
||||
final ResolveInfo resolveInfo = new ResolveInfoBuilder(PACKAGE_NAME).build();
|
||||
@@ -105,6 +109,12 @@ public class SmartAutoRotateControllerTest {
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_cameraDisabled_returnDisableDependentSetting() {
|
||||
when(mController.isCameraLocked()).thenReturn(true);
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
|
||||
}
|
||||
|
||||
private void enableAutoRotation() {
|
||||
Settings.System.putIntForUser(mContentResolver,
|
||||
Settings.System.ACCELEROMETER_ROTATION, 1, UserHandle.USER_CURRENT);
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.fuelgauge;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.os.BatteryConsumer;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.SystemBatteryConsumer;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
import java.util.TimeZone;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public final class BatteryHistEntryTest {
|
||||
|
||||
@Mock
|
||||
private BatteryEntry mockBatteryEntry;
|
||||
@Mock
|
||||
private BatteryUsageStats mBatteryUsageStats;
|
||||
@Mock
|
||||
private SystemBatteryConsumer mockSystemBatteryConsumer;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor_returnsExpectedResult() {
|
||||
final int expectedType = 3;
|
||||
when(mockBatteryEntry.getUid()).thenReturn(1001);
|
||||
when(mockBatteryEntry.getLabel()).thenReturn("Settings");
|
||||
when(mockBatteryEntry.getDefaultPackageName())
|
||||
.thenReturn("com.google.android.settings.battery");
|
||||
when(mockBatteryEntry.isHidden()).thenReturn(true);
|
||||
when(mBatteryUsageStats.getConsumedPower()).thenReturn(5.1);
|
||||
when(mockBatteryEntry.getConsumedPower()).thenReturn(1.1);
|
||||
mockBatteryEntry.percent = 0.3;
|
||||
when(mockBatteryEntry.getTimeInForegroundMs()).thenReturn(1234L);
|
||||
when(mockBatteryEntry.getTimeInBackgroundMs()).thenReturn(5689L);
|
||||
when(mockBatteryEntry.getBatteryConsumer())
|
||||
.thenReturn(mockSystemBatteryConsumer);
|
||||
when(mockSystemBatteryConsumer.getDrainType()).thenReturn(expectedType);
|
||||
final ContentValues values =
|
||||
ConvertUtils.convert(
|
||||
mockBatteryEntry,
|
||||
mBatteryUsageStats,
|
||||
/*batteryLevel=*/ 12,
|
||||
/*batteryStatus=*/ BatteryManager.BATTERY_STATUS_FULL,
|
||||
/*batteryHealth=*/ BatteryManager.BATTERY_HEALTH_COLD,
|
||||
/*timestamp=*/ 10001L);
|
||||
|
||||
final BatteryHistEntry entry = new BatteryHistEntry(values);
|
||||
|
||||
assertThat(entry.isValidEntry()).isTrue();
|
||||
assertThat(entry.mUid).isEqualTo(1001);
|
||||
assertThat(entry.mUserId).isEqualTo(UserHandle.getUserId(1001));
|
||||
assertThat(entry.mAppLabel).isEqualTo("Settings");
|
||||
assertThat(entry.mPackageName)
|
||||
.isEqualTo("com.google.android.settings.battery");
|
||||
assertThat(entry.mIsHidden).isTrue();
|
||||
assertThat(entry.mTimestamp).isEqualTo(10001L);
|
||||
assertThat(entry.mZoneId).isEqualTo(TimeZone.getDefault().getID());
|
||||
assertThat(entry.mTotalPower).isEqualTo(5.1);
|
||||
assertThat(entry.mConsumePower).isEqualTo(1.1);
|
||||
assertThat(entry.mPercentOfTotal).isEqualTo(mockBatteryEntry.percent);
|
||||
assertThat(entry.mForegroundUsageTimeInMs).isEqualTo(1234L);
|
||||
assertThat(entry.mBackgroundUsageTimeInMs).isEqualTo(5689L);
|
||||
assertThat(entry.mDrainType).isEqualTo(expectedType);
|
||||
assertThat(entry.mConsumerType)
|
||||
.isEqualTo(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
|
||||
assertThat(entry.mBatteryLevel).isEqualTo(12);
|
||||
assertThat(entry.mBatteryStatus)
|
||||
.isEqualTo(BatteryManager.BATTERY_STATUS_FULL);
|
||||
assertThat(entry.mBatteryHealth)
|
||||
.isEqualTo(BatteryManager.BATTERY_HEALTH_COLD);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor_invalidField_returnsInvalidEntry() {
|
||||
final BatteryHistEntry entry = new BatteryHistEntry(new ContentValues());
|
||||
assertThat(entry.isValidEntry()).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.fuelgauge;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.widget.UsageView;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class BatteryHistoryPreferenceTest {
|
||||
|
||||
private static final String TEST_STRING = "test";
|
||||
@Mock
|
||||
private PreferenceViewHolder mViewHolder;
|
||||
@Mock
|
||||
private BatteryInfo mBatteryInfo;
|
||||
@Mock
|
||||
private TextView mTextView;
|
||||
@Mock
|
||||
private UsageView mUsageView;
|
||||
@Mock
|
||||
private View mLabelView;
|
||||
private BatteryHistoryPreference mBatteryHistoryPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
final View itemView =
|
||||
LayoutInflater.from(context).inflate(R.layout.battery_usage_graph, null);
|
||||
|
||||
mBatteryHistoryPreference = new BatteryHistoryPreference(context, null);
|
||||
mBatteryHistoryPreference.mBatteryInfo = mBatteryInfo;
|
||||
mViewHolder = spy(PreferenceViewHolder.createInstanceForTests(itemView));
|
||||
when(mViewHolder.findViewById(R.id.battery_usage)).thenReturn(mUsageView);
|
||||
when(mViewHolder.findViewById(R.id.charge)).thenReturn(mTextView);
|
||||
when(mUsageView.findViewById(anyInt())).thenReturn(mLabelView);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnBindViewHolder_updateBatteryUsage() {
|
||||
mBatteryHistoryPreference.onBindViewHolder(mViewHolder);
|
||||
|
||||
verify(mViewHolder).findViewById(R.id.battery_usage);
|
||||
verify(mTextView).setText(nullable(String.class));
|
||||
verify(mBatteryInfo).bindHistory(mUsageView);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetBottomSummary_updatesBottomSummaryTextIfSet() {
|
||||
mBatteryHistoryPreference.setBottomSummary(TEST_STRING);
|
||||
mBatteryHistoryPreference.onBindViewHolder(mViewHolder);
|
||||
|
||||
TextView view = (TextView) mViewHolder.findViewById(R.id.bottom_summary);
|
||||
assertThat(view.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(view.getText()).isEqualTo(TEST_STRING);
|
||||
assertThat(mBatteryHistoryPreference.hideSummary).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetBottomSummary_leavesBottomSummaryTextBlankIfNotSet() {
|
||||
mBatteryHistoryPreference.hideBottomSummary();
|
||||
mBatteryHistoryPreference.onBindViewHolder(mViewHolder);
|
||||
|
||||
TextView view = (TextView) mViewHolder.findViewById(R.id.bottom_summary);
|
||||
assertThat(view.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(view.getText()).isEqualTo("");
|
||||
assertThat(mBatteryHistoryPreference.hideSummary).isTrue();
|
||||
}
|
||||
}
|
||||
@@ -150,10 +150,9 @@ public class BatteryInfoTest {
|
||||
mBatteryUsageStats, estimate, SystemClock.elapsedRealtime() * 1000,
|
||||
true /* shortString */);
|
||||
|
||||
// We only add special mention for the long string
|
||||
assertThat(info.remainingLabel.toString()).contains(ENHANCED_STRING_SUFFIX);
|
||||
// Both long and short strings should not have extra text
|
||||
assertThat(info.remainingLabel.toString()).doesNotContain(ENHANCED_STRING_SUFFIX);
|
||||
assertThat(info.suggestionLabel).contains(BATTERY_RUN_OUT_PREFIX);
|
||||
// shortened string should not have extra text
|
||||
assertThat(info2.remainingLabel.toString()).doesNotContain(ENHANCED_STRING_SUFFIX);
|
||||
assertThat(info2.suggestionLabel).contains(BATTERY_RUN_OUT_PREFIX);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.fuelgauge;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.os.BatteryConsumer;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.SystemBatteryConsumer;
|
||||
import android.os.UidBatteryConsumer;
|
||||
import android.os.UserBatteryConsumer;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.TimeZone;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public final class ConvertUtilsTest {
|
||||
|
||||
@Mock
|
||||
private BatteryUsageStats mBatteryUsageStats;
|
||||
@Mock
|
||||
private BatteryEntry mockBatteryEntry;
|
||||
@Mock
|
||||
private BatteryConsumer mockBatteryConsumer;
|
||||
@Mock
|
||||
private UidBatteryConsumer mockUidBatteryConsumer;
|
||||
@Mock
|
||||
private UserBatteryConsumer mockUserBatteryConsumer;
|
||||
@Mock
|
||||
private SystemBatteryConsumer mockSystemBatteryConsumer;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvert_returnsExpectedContentValues() {
|
||||
final int expectedType = 3;
|
||||
when(mockBatteryEntry.getUid()).thenReturn(1001);
|
||||
when(mockBatteryEntry.getLabel()).thenReturn("Settings");
|
||||
when(mockBatteryEntry.getDefaultPackageName())
|
||||
.thenReturn("com.google.android.settings.battery");
|
||||
when(mockBatteryEntry.isHidden()).thenReturn(true);
|
||||
when(mBatteryUsageStats.getConsumedPower()).thenReturn(5.1);
|
||||
when(mockBatteryEntry.getConsumedPower()).thenReturn(1.1);
|
||||
mockBatteryEntry.percent = 0.3;
|
||||
when(mockBatteryEntry.getTimeInForegroundMs()).thenReturn(1234L);
|
||||
when(mockBatteryEntry.getTimeInBackgroundMs()).thenReturn(5689L);
|
||||
when(mockBatteryEntry.getBatteryConsumer())
|
||||
.thenReturn(mockSystemBatteryConsumer);
|
||||
when(mockSystemBatteryConsumer.getDrainType()).thenReturn(expectedType);
|
||||
|
||||
final ContentValues values =
|
||||
ConvertUtils.convert(
|
||||
mockBatteryEntry,
|
||||
mBatteryUsageStats,
|
||||
/*batteryLevel=*/ 12,
|
||||
/*batteryStatus=*/ BatteryManager.BATTERY_STATUS_FULL,
|
||||
/*batteryHealth=*/ BatteryManager.BATTERY_HEALTH_COLD,
|
||||
/*timestamp=*/ 10001L);
|
||||
|
||||
assertThat(values.getAsLong("uid")).isEqualTo(1001L);
|
||||
assertThat(values.getAsLong("userId"))
|
||||
.isEqualTo(UserHandle.getUserId(1001));
|
||||
assertThat(values.getAsString("appLabel")).isEqualTo("Settings");
|
||||
assertThat(values.getAsString("packageName"))
|
||||
.isEqualTo("com.google.android.settings.battery");
|
||||
assertThat(values.getAsBoolean("isHidden")).isTrue();
|
||||
assertThat(values.getAsLong("timestamp")).isEqualTo(10001L);
|
||||
assertThat(values.getAsString("zoneId"))
|
||||
.isEqualTo(TimeZone.getDefault().getID());
|
||||
assertThat(values.getAsDouble("totalPower")).isEqualTo(5.1);
|
||||
assertThat(values.getAsDouble("consumePower")).isEqualTo(1.1);
|
||||
assertThat(values.getAsDouble("percentOfTotal")).isEqualTo(0.3);
|
||||
assertThat(values.getAsLong("foregroundUsageTimeInMs")).isEqualTo(1234L);
|
||||
assertThat(values.getAsLong("backgroundUsageTimeInMs")).isEqualTo(5689L);
|
||||
assertThat(values.getAsInteger("drainType")).isEqualTo(expectedType);
|
||||
assertThat(values.getAsInteger("consumerType"))
|
||||
.isEqualTo(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
|
||||
assertThat(values.getAsInteger("batteryLevel")).isEqualTo(12);
|
||||
assertThat(values.getAsInteger("batteryStatus"))
|
||||
.isEqualTo(BatteryManager.BATTERY_STATUS_FULL);
|
||||
assertThat(values.getAsInteger("batteryHealth"))
|
||||
.isEqualTo(BatteryManager.BATTERY_HEALTH_COLD);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDrainType_returnsExpetcedResult() {
|
||||
final int expectedType = 3;
|
||||
when(mockSystemBatteryConsumer.getDrainType())
|
||||
.thenReturn(expectedType);
|
||||
|
||||
assertThat(ConvertUtils.getDrainType(mockSystemBatteryConsumer))
|
||||
.isEqualTo(expectedType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDrainType_notValidConsumer_returnsInvalidTypeValue() {
|
||||
assertThat(ConvertUtils.getDrainType(mockUserBatteryConsumer))
|
||||
.isEqualTo(ConvertUtils.INVALID_DRAIN_TYPE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetConsumerType_returnsExpetcedResult() {
|
||||
assertThat(ConvertUtils.getConsumerType(mockUidBatteryConsumer))
|
||||
.isEqualTo(ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||
assertThat(ConvertUtils.getConsumerType(mockUserBatteryConsumer))
|
||||
.isEqualTo(ConvertUtils.CONSUMER_TYPE_USER_BATTERY);
|
||||
assertThat(ConvertUtils.getConsumerType(mockSystemBatteryConsumer))
|
||||
.isEqualTo(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetConsumeType_invalidConsumer_returnsInvalidType() {
|
||||
assertThat(ConvertUtils.getConsumerType(mockBatteryConsumer))
|
||||
.isEqualTo(ConvertUtils.CONSUMER_TYPE_UNKNOWN);
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.fuelgauge;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class PowerUsageAdvancedTest {
|
||||
@Mock
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private Menu mMenu;
|
||||
@Mock
|
||||
private MenuInflater mMenuInflater;
|
||||
@Mock
|
||||
private MenuItem mToggleAppsMenu;
|
||||
private Context mContext;
|
||||
private PowerUsageAdvanced mFragment;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
when(mToggleAppsMenu.getItemId()).thenReturn(PowerUsageAdvanced.MENU_TOGGLE_APPS);
|
||||
|
||||
BatteryAppListPreferenceController.sConfig =
|
||||
new BatteryAppListPreferenceController.Config() {
|
||||
@Override
|
||||
public boolean shouldShowBatteryAttributionList(Context context) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
mFragment = spy(new PowerUsageAdvanced());
|
||||
mFragment.onAttach(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveInstanceState_showAllAppsRestored() {
|
||||
Bundle bundle = new Bundle();
|
||||
mFragment.mShowAllApps = true;
|
||||
doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
|
||||
|
||||
mFragment.onSaveInstanceState(bundle);
|
||||
mFragment.restoreSavedInstance(bundle);
|
||||
|
||||
assertThat(mFragment.mShowAllApps).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptionsMenu_menuAppToggle_metricEventInvoked() {
|
||||
mFragment.mShowAllApps = false;
|
||||
doNothing().when(mFragment).restartBatteryStatsLoader(anyInt());
|
||||
|
||||
mFragment.onOptionsItemSelected(mToggleAppsMenu);
|
||||
|
||||
verify(mFeatureFactory.metricsFeatureProvider).action(nullable(Context.class),
|
||||
eq(MetricsProto.MetricsEvent.ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE), eq(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptionsMenu_toggleAppsEnabled() {
|
||||
when(mFeatureFactory.powerUsageFeatureProvider.isPowerAccountingToggleEnabled())
|
||||
.thenReturn(true);
|
||||
mFragment.mShowAllApps = false;
|
||||
|
||||
mFragment.onCreateOptionsMenu(mMenu, mMenuInflater);
|
||||
|
||||
verify(mMenu).add(Menu.NONE, PowerUsageAdvanced.MENU_TOGGLE_APPS, Menu.NONE,
|
||||
R.string.show_all_apps);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.testutils.shadow;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.SensorPrivacyManager;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(value = SensorPrivacyManager.class)
|
||||
public class ShadowSensorPrivacyManager {
|
||||
|
||||
@Implementation
|
||||
public static SensorPrivacyManager getInstance(Context context) {
|
||||
return mock(SensorPrivacyManager.class);
|
||||
}
|
||||
}
|
||||
@@ -579,7 +579,11 @@ public class WifiDetailPreferenceController2Test {
|
||||
ZoneId.of("Europe/London"));
|
||||
doShouldShowRemainingTimeTest(fakeNow, timeRemainingMs);
|
||||
final String expectedSummary = mContext.getString(R.string.wifi_time_remaining,
|
||||
StringUtil.formatElapsedTime(mContext, timeRemainingMs, false /* withSeconds */));
|
||||
StringUtil.formatElapsedTime(
|
||||
mContext,
|
||||
timeRemainingMs,
|
||||
false /* withSeconds */,
|
||||
false /* collapseTimeUnit */));
|
||||
final InOrder inOrder = inOrder(mMockHeaderController);
|
||||
inOrder.verify(mMockHeaderController).setSecondSummary(expectedSummary);
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ import androidx.preference.SwitchPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.testutils.ResourcesUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -52,29 +54,30 @@ public class WifiTetherMaximizeCompatibilityPreferenceControllerTest {
|
||||
@Mock
|
||||
private WifiTetherBasePreferenceController.OnTetherConfigUpdateListener mListener;
|
||||
|
||||
private Context mContext;
|
||||
private WifiTetherMaximizeCompatibilityPreferenceController mController;
|
||||
private SwitchPreference mPreference;
|
||||
private SoftApConfiguration mConfig;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
final Context context = spy(ApplicationProvider.getApplicationContext());
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
mConfig = new SoftApConfiguration.Builder()
|
||||
.setSsid("test_Ssid")
|
||||
.setPassphrase(null, SoftApConfiguration.SECURITY_TYPE_OPEN)
|
||||
.setBridgedModeOpportunisticShutdownEnabled(true)
|
||||
.build();
|
||||
doReturn(mWifiManager).when(context).getSystemService(Context.WIFI_SERVICE);
|
||||
doReturn(mWifiManager).when(mContext).getSystemService(Context.WIFI_SERVICE);
|
||||
doReturn(true).when(mWifiManager).isBridgedApConcurrencySupported();
|
||||
doReturn(mConfig).when(mWifiManager).getSoftApConfiguration();
|
||||
|
||||
mController = new WifiTetherMaximizeCompatibilityPreferenceController(context, mListener);
|
||||
mController = new WifiTetherMaximizeCompatibilityPreferenceController(mContext, mListener);
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
final PreferenceManager preferenceManager = new PreferenceManager(context);
|
||||
final PreferenceScreen screen = preferenceManager.createPreferenceScreen(context);
|
||||
mPreference = new SwitchPreference(context);
|
||||
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
|
||||
final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext);
|
||||
mPreference = new SwitchPreference(mContext);
|
||||
mPreference.setKey(WifiTetherMaximizeCompatibilityPreferenceController.PREF_KEY);
|
||||
screen.addPreference(mPreference);
|
||||
mController.displayPreference(screen);
|
||||
@@ -104,6 +107,26 @@ public class WifiTetherMaximizeCompatibilityPreferenceControllerTest {
|
||||
assertThat(mPreference.isEnabled()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDisplay_notSupportedBridgedApConcurrency_setSingleApSummary() {
|
||||
doReturn(false).when(mWifiManager).isBridgedApConcurrencySupported();
|
||||
|
||||
mController.updateDisplay();
|
||||
|
||||
assertThat(mPreference.getSummary()).isEqualTo(ResourcesUtils.getResourcesString(mContext,
|
||||
"wifi_hotspot_maximize_compatibility_single_ap_summary"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDisplay_supportedBridgedApConcurrency_setDualApSummary() {
|
||||
doReturn(true).when(mWifiManager).isBridgedApConcurrencySupported();
|
||||
|
||||
mController.updateDisplay();
|
||||
|
||||
assertThat(mPreference.getSummary()).isEqualTo(ResourcesUtils.getResourcesString(mContext,
|
||||
"wifi_hotspot_maximize_compatibility_dual_ap_summary"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDisplay_supported5GHzBandAndCountryCodeIsNotNull_setPreferenceEnabled() {
|
||||
doReturn(true).when(mWifiManager).is5GHzBandSupported();
|
||||
|
||||
Reference in New Issue
Block a user