Snap for 7219331 from 2a1f61829e to sc-v2-release
Change-Id: Ia146a99cbc743d9ad729100cfbacfd2f4dc4db8e
This commit is contained in:
67
res/drawable/accessibility_button_navigation.xml
Normal file
67
res/drawable/accessibility_button_navigation.xml
Normal file
@@ -0,0 +1,67 @@
|
||||
<?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="125dp"
|
||||
android:height="153dp"
|
||||
android:viewportWidth="125"
|
||||
android:viewportHeight="153">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h125v153h-125z"/>
|
||||
<path
|
||||
android:pathData="M7.4,-62.9L117.6,-62.9A6.3,6.3 0,0 1,123.9 -56.6L123.9,145.6A6.3,6.3 0,0 1,117.6 151.9L7.4,151.9A6.3,6.3 0,0 1,1.1 145.6L1.1,-56.6A6.3,6.3 0,0 1,7.4 -62.9z"
|
||||
android:strokeWidth="1.8"
|
||||
android:fillColor="#DADCE0"
|
||||
android:strokeColor="#BDC1C6"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M7.4,-62.9L116.6,-62.9A6.3,6.3 0,0 1,122.9 -56.6L122.9,145.6A6.3,6.3 0,0 1,116.6 151.9L7.4,151.9A6.3,6.3 0,0 1,1.1 145.6L1.1,-56.6A6.3,6.3 0,0 1,7.4 -62.9z"/>
|
||||
<path
|
||||
android:pathData="M12.4,-61L112.6,-61A5.4,5.4 0,0 1,118 -55.6L118,140.6A5.4,5.4 0,0 1,112.6 146L12.4,146A5.4,5.4 0,0 1,7 140.6L7,-55.6A5.4,5.4 0,0 1,12.4 -61z"
|
||||
android:fillColor="#F8F9FA"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M12.4,-61L112.6,-61A5.4,5.4 0,0 1,118 -55.6L118,140.6A5.4,5.4 0,0 1,112.6 146L12.4,146A5.4,5.4 0,0 1,7 140.6L7,-55.6A5.4,5.4 0,0 1,12.4 -61z"/>
|
||||
</group>
|
||||
</group>
|
||||
<path
|
||||
android:pathData="M7,126H118V140.6C118,143.582 115.582,146 112.6,146H12.4C9.418,146 7,143.582 7,140.6V126Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillAlpha="0.87"/>
|
||||
<path
|
||||
android:strokeWidth="1"
|
||||
android:pathData="M63.5,138.688C64.713,138.688 65.697,137.708 65.697,136.5C65.697,135.292 64.713,134.312 63.5,134.312C62.286,134.312 61.303,135.292 61.303,136.5C61.303,137.708 62.286,138.688 63.5,138.688Z"
|
||||
android:fillColor="#00000000"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeColor="#9AA0A6"/>
|
||||
<path
|
||||
android:strokeWidth="1"
|
||||
android:pathData="M33.694,133.953C33.827,133.876 33.994,133.972 33.994,134.126V138.874C33.994,139.028 33.827,139.125 33.694,139.047L29.604,136.673C29.471,136.596 29.471,136.404 29.604,136.327L33.694,133.953Z"
|
||||
android:fillColor="#00000000"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeColor="#9AA0A6"/>
|
||||
<path
|
||||
android:pathData="M96.111,131.2C96.111,131.86 95.611,132.4 95,132.4C94.389,132.4 93.889,131.86 93.889,131.2C93.889,130.54 94.389,130 95,130C95.611,130 96.111,130.54 96.111,131.2ZM95,133C96.572,133 98.272,132.82 99.722,132.4L100,133.6C98.967,133.9 97.778,134.098 96.667,134.2V142H95.556V138.4H94.444V142H93.333V134.2C92.222,134.098 91.033,133.9 90,133.6L90.278,132.4C91.728,132.82 93.428,133 95,133Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M94.5,135.5m-15.5,0a15.5,15.5 0,1 1,31 0a15.5,15.5 0,1 1,-31 0"
|
||||
android:strokeWidth="4"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#4285F4"/>
|
||||
</group>
|
||||
</vector>
|
||||
42
res/drawable/accessibility_button_preview_base.xml
Normal file
42
res/drawable/accessibility_button_preview_base.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?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="125dp"
|
||||
android:height="153dp"
|
||||
android:viewportWidth="125"
|
||||
android:viewportHeight="153">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h125v153h-125z"/>
|
||||
<path
|
||||
android:pathData="M7.4,-62.9L117.6,-62.9A6.3,6.3 0,0 1,123.9 -56.6L123.9,145.6A6.3,6.3 0,0 1,117.6 151.9L7.4,151.9A6.3,6.3 0,0 1,1.1 145.6L1.1,-56.6A6.3,6.3 0,0 1,7.4 -62.9z"
|
||||
android:strokeWidth="1.8"
|
||||
android:fillColor="#DADCE0"
|
||||
android:strokeColor="#BDC1C6"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M7.4,-62.9L116.6,-62.9A6.3,6.3 0,0 1,122.9 -56.6L122.9,145.6A6.3,6.3 0,0 1,116.6 151.9L7.4,151.9A6.3,6.3 0,0 1,1.1 145.6L1.1,-56.6A6.3,6.3 0,0 1,7.4 -62.9z"/>
|
||||
<path
|
||||
android:pathData="M12.4,-61L112.6,-61A5.4,5.4 0,0 1,118 -55.6L118,140.6A5.4,5.4 0,0 1,112.6 146L12.4,146A5.4,5.4 0,0 1,7 140.6L7,-55.6A5.4,5.4 0,0 1,12.4 -61z"
|
||||
android:fillColor="#F8F9FA"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M12.4,-61L112.6,-61A5.4,5.4 0,0 1,118 -55.6L118,140.6A5.4,5.4 0,0 1,112.6 146L12.4,146A5.4,5.4 0,0 1,7 140.6L7,-55.6A5.4,5.4 0,0 1,12.4 -61z"/>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
</vector>
|
||||
@@ -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="125dp"
|
||||
android:height="153dp"
|
||||
android:viewportWidth="125"
|
||||
android:viewportHeight="153">
|
||||
<path
|
||||
android:pathData="M0,0h125v153h-125z"
|
||||
android:fillColor="#00000000"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M89,95h29v34h-29z"/>
|
||||
<path
|
||||
android:strokeWidth="1"
|
||||
android:pathData="M105,97.5L131,97.5A14.5,14.5 0,0 1,145.5 112L145.5,112A14.5,14.5 0,0 1,131 126.5L105,126.5A14.5,14.5 0,0 1,90.5 112L90.5,112A14.5,14.5 0,0 1,105 97.5z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#DADCE0"/>
|
||||
<path
|
||||
android:pathData="M105.4,112m-11.2,0a11.2,11.2 0,1 1,22.4 0a11.2,11.2 0,1 1,-22.4 0"
|
||||
android:fillColor="#80868B"/>
|
||||
<path
|
||||
android:pathData="M106.467,107.733C106.467,108.32 105.987,108.8 105.4,108.8C104.814,108.8 104.334,108.32 104.334,107.733C104.334,107.147 104.814,106.667 105.4,106.667C105.987,106.667 106.467,107.147 106.467,107.733ZM105.4,109.333C106.91,109.333 108.542,109.173 109.934,108.8L110.2,109.867C109.208,110.133 108.067,110.309 107,110.4V117.333H105.934V114.133H104.867V117.333H103.8V110.4C102.734,110.309 101.592,110.133 100.6,109.867L100.867,108.8C102.259,109.173 103.891,109.333 105.4,109.333Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="evenOdd"/>
|
||||
</group>
|
||||
</vector>
|
||||
@@ -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="125dp"
|
||||
android:height="153dp"
|
||||
android:viewportWidth="125"
|
||||
android:viewportHeight="153">
|
||||
<path
|
||||
android:pathData="M0,0h125v153h-125z"
|
||||
android:fillColor="#00000000"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M89,106h29v22h-29z"/>
|
||||
<path
|
||||
android:strokeWidth="1"
|
||||
android:pathData="M111,107.5L137,107.5A9.5,9.5 0,0 1,146.5 117L146.5,117A9.5,9.5 0,0 1,137 126.5L111,126.5A9.5,9.5 0,0 1,101.5 117L101.5,117A9.5,9.5 0,0 1,111 107.5z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#DADCE0"/>
|
||||
<path
|
||||
android:pathData="M111.168,116.968m-7.168,0a7.168,7.168 0,1 1,14.336 0a7.168,7.168 0,1 1,-14.336 0"
|
||||
android:fillColor="#80868B"/>
|
||||
<path
|
||||
android:pathData="M111.851,114.237C111.851,114.612 111.543,114.92 111.168,114.92C110.792,114.92 110.485,114.612 110.485,114.237C110.485,113.861 110.792,113.554 111.168,113.554C111.543,113.554 111.851,113.861 111.851,114.237ZM111.168,115.261C112.134,115.261 113.178,115.158 114.069,114.92L114.24,115.602C113.605,115.773 112.875,115.886 112.192,115.944V120.381H111.509V118.333H110.827V120.381H110.144V115.944C109.461,115.886 108.731,115.773 108.096,115.602L108.267,114.92C109.157,115.158 110.202,115.261 111.168,115.261Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="evenOdd"/>
|
||||
</group>
|
||||
</vector>
|
||||
@@ -0,0 +1,68 @@
|
||||
<?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="180dp"
|
||||
android:height="180dp"
|
||||
android:viewportWidth="180"
|
||||
android:viewportHeight="180">
|
||||
<path
|
||||
android:pathData="M90,90m-89,0a89,89 0,1 1,178 0a89,89 0,1 1,-178 0"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#ECEEEF"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M90,90m-87,0a87,87 0,1 1,174 0a87,87 0,1 1,-174 0"/>
|
||||
<path
|
||||
android:pathData="M35.4,-70.9L144.6,-70.9A6.3,6.3 0,0 1,150.9 -64.6L150.9,137.6A6.3,6.3 0,0 1,144.6 143.9L35.4,143.9A6.3,6.3 0,0 1,29.1 137.6L29.1,-64.6A6.3,6.3 0,0 1,35.4 -70.9z"
|
||||
android:strokeWidth="1.8"
|
||||
android:fillColor="#F2F3F4"
|
||||
android:strokeColor="#DADCE0"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M35.4,-70.9L144.6,-70.9A6.3,6.3 0,0 1,150.9 -64.6L150.9,137.6A6.3,6.3 0,0 1,144.6 143.9L35.4,143.9A6.3,6.3 0,0 1,29.1 137.6L29.1,-64.6A6.3,6.3 0,0 1,35.4 -70.9z"/>
|
||||
<path
|
||||
android:pathData="M40.4,-69L140.6,-69A5.4,5.4 0,0 1,146 -63.6L146,132.6A5.4,5.4 0,0 1,140.6 138L40.4,138A5.4,5.4 0,0 1,35 132.6L35,-63.6A5.4,5.4 0,0 1,40.4 -69z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M40.4,-69L140.6,-69A5.4,5.4 0,0 1,146 -63.6L146,132.6A5.4,5.4 0,0 1,140.6 138L40.4,138A5.4,5.4 0,0 1,35 132.6L35,-63.6A5.4,5.4 0,0 1,40.4 -69z"/>
|
||||
<path
|
||||
android:strokeWidth="1"
|
||||
android:pathData="M132,90.5L158,90.5A14.5,14.5 0,0 1,172.5 105L172.5,105A14.5,14.5 0,0 1,158 119.5L132,119.5A14.5,14.5 0,0 1,117.5 105L117.5,105A14.5,14.5 0,0 1,132 90.5z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#DADCE0"/>
|
||||
<path
|
||||
android:pathData="M132.4,105m-11.2,0a11.2,11.2 0,1 1,22.4 0a11.2,11.2 0,1 1,-22.4 0"
|
||||
android:fillColor="#80868B"/>
|
||||
<path
|
||||
android:pathData="M133.467,100.733C133.467,101.32 132.987,101.8 132.4,101.8C131.813,101.8 131.333,101.32 131.333,100.733C131.333,100.147 131.813,99.666 132.4,99.666C132.987,99.666 133.467,100.147 133.467,100.733ZM132.4,102.333C133.909,102.333 135.541,102.173 136.933,101.8L137.2,102.867C136.208,103.133 135.067,103.309 134,103.4V110.333H132.933V107.133H131.867V110.333H130.8V103.4C129.733,103.309 128.592,103.133 127.6,102.867L127.867,101.8C129.259,102.173 130.891,102.333 132.4,102.333Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M121.719,120.653C121.719,121.29 121.198,121.81 120.562,121.81C119.927,121.81 119.406,121.29 119.406,120.653C119.406,120.017 119.927,119.497 120.562,119.497C121.198,119.497 121.719,120.017 121.719,120.653ZM120.562,122.533C122.38,122.533 124.346,122.316 126.023,121.81L126.344,123.255C125.149,123.617 123.774,123.855 122.49,123.978V133.374H121.205V129.038H119.92V133.374H118.635V123.978C117.351,123.855 115.976,123.617 114.781,123.255L115.102,121.81C116.779,122.316 118.745,122.533 120.562,122.533Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="evenOdd"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M121.719,120.653C121.719,121.29 121.198,121.81 120.562,121.81C119.927,121.81 119.406,121.29 119.406,120.653C119.406,120.017 119.927,119.497 120.562,119.497C121.198,119.497 121.719,120.017 121.719,120.653ZM120.562,122.533C122.38,122.533 124.346,122.316 126.023,121.81L126.344,123.255C125.149,123.617 123.774,123.855 122.49,123.978V133.374H121.205V129.038H119.92V133.374H118.635V123.978C117.351,123.855 115.976,123.617 114.781,123.255L115.102,121.81C116.779,122.316 118.745,122.533 120.562,122.533Z"
|
||||
android:fillType="evenOdd"/>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
</vector>
|
||||
33
res/layout/accessibility_button_preview.xml
Normal file
33
res/layout/accessibility_button_preview.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:importantForAccessibility="noHideDescendants">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/preview_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/accessibility_button_preview_height"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="fitCenter"
|
||||
android:focusable="false"
|
||||
android:clickable="false"
|
||||
android:adjustViewBounds="true"/>
|
||||
</FrameLayout>
|
||||
@@ -1,68 +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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="56dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@android:style/TextAppearance.Material.Subhead"
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@*android:id/seekbar"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="8dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/text1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_weight="1"
|
||||
android:maxLines="1"
|
||||
android:textAlignment="viewStart"/>
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/text2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_weight="1"
|
||||
android:maxLines="1"
|
||||
android:textAlignment="viewEnd"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -966,6 +966,35 @@
|
||||
<item>-1</item>
|
||||
</integer-array>
|
||||
|
||||
<!-- Titles for the accessibility button location. [CHAR LIMIT=35] -->
|
||||
<string-array name="accessibility_button_location_selector_titles">
|
||||
<item>Floating over other apps</item>
|
||||
<item>Navigation bar</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Values for the accessibility button location. -->
|
||||
<!-- Should Keep in sync with Settings.Secure.ACCESSIBILITY_BUTTON_MODE_* -->
|
||||
<string-array name="accessibility_button_location_selector_values" translatable="false">
|
||||
<!-- Floating over other apps -->
|
||||
<item>1</item>
|
||||
<!-- Navigation bar -->
|
||||
<item>0</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Titles for the accessibility button size. [CHAR LIMIT=35] -->
|
||||
<string-array name="accessibility_button_size_selector_titles">
|
||||
<item>Small</item>
|
||||
<item>Large</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Values for the accessibility button size. -->
|
||||
<string-array name="accessibility_button_size_selector_values" translatable="false" >
|
||||
<!-- Small -->
|
||||
<item>0</item>
|
||||
<!-- Large -->
|
||||
<item>1</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Match this with the constants in VpnProfile. --> <skip />
|
||||
<!-- Short names for each VPN type, not really translatable. [CHAR LIMIT=20] -->
|
||||
<string-array name="vpn_types" translatable="false">
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
|
||||
<dimen name="color_mode_preview_height">320dp</dimen>
|
||||
|
||||
<dimen name="accessibility_button_preview_height">200dp</dimen>
|
||||
|
||||
<dimen name="ring_progress_bar_thickness">4dp</dimen>
|
||||
|
||||
<!-- Weight of the left pane in a multi-pane preference layout. -->
|
||||
|
||||
@@ -2416,6 +2416,10 @@
|
||||
<string name="wifi_hotspot_auto_off_title">Turn off hotspot automatically</string>
|
||||
<!-- 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>
|
||||
|
||||
<!-- Summary text when turning hotspot on -->
|
||||
<string name="wifi_tether_starting">Turning hotspot on\u2026</string>
|
||||
@@ -5106,6 +5110,8 @@
|
||||
<string name="accessibility_tutorial_dialog_title_gesture_settings">Use new accessibility gesture</string>
|
||||
<!-- Message for the accessibility tutorial dialog when user enables an accessibility service while using the 3-button nav bar. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_tutorial_dialog_message_button">To use this feature, tap the accessibility button <xliff:g id="accessibility_icon" example="[Icon]">%s</xliff:g> on the bottom of your screen.\n\nTo switch between features, touch & hold the accessibility button.</string>
|
||||
<!-- Message for the accessibility tutorial dialog when user enables an accessibility service while using the accessibility floating button. [CHAR LIMIT=100] -->
|
||||
<string name="accessibility_tutorial_dialog_message_floating_button">To use this feature, tap the accessibility button on your screen.</string>
|
||||
<!-- Instruction for the accessibility tutorial dialog in accessibility service with volume keys. [CHAR LIMIT=100] -->
|
||||
<string name="accessibility_tutorial_dialog_message_volume">To use this feature, press & hold both volume keys.</string>
|
||||
<!-- Instruction for the accessibility tutorial dialog in accessibility service with triple tap. [CHAR LIMIT=100] -->
|
||||
@@ -5136,6 +5142,8 @@
|
||||
<string name="accessibility_shortcut_edit_dialog_summary_software_gesture">Swipe up from the bottom of the screen with 2 fingers.\n\nTo switch between features, swipe up with 2 fingers and hold.</string>
|
||||
<!-- Summary for software shortcut in gesture mode in accessibility edit shortcut dialog while using gesture navigation and touch exploration are enabled [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_shortcut_edit_dialog_summary_software_gesture_talkback">Swipe up from the bottom of the screen with 3 fingers.\n\nTo switch between features, swipe up with 3 fingers and hold.</string>
|
||||
<!-- Summary for software shortcut in accessibility edit shortcut dialog when user had enabled the accessibility floating button mode (Floating over other apps). [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_shortcut_edit_dialog_summary_software_floating"><annotation id="link">Customize accessibility button</annotation></string>
|
||||
<!-- Title for hardware shortcut in accessibility edit shortcut dialog. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_shortcut_edit_dialog_title_hardware">Hold volume keys</string>
|
||||
<!-- Part of list to compose user's accessibility shortcut list. [CHAR LIMIT=NONE] -->
|
||||
@@ -5164,6 +5172,26 @@
|
||||
<string name="accessibility_shortcut_service_on_lock_screen_title">Shortcut from lock screen</string>
|
||||
<!-- Description of accessibility shortcut. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_shortcut_description">Allow feature shortcut to turn on from the lock screen. Hold both volume keys for a few seconds.</string>
|
||||
<!-- Title for the accessibility button page. [CHAR LIMIT=35] -->
|
||||
<string name="accessibility_button_title">Accessibility button</string>
|
||||
<!-- Summary text for the accessibility button preference. [CHAR LIMIT=50] -->
|
||||
<string name="accessibility_button_summary">Quickly access accessibility features</string>
|
||||
<!-- Description for the accessibility button page. Explain how this page works. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_button_description">Quickly access accessibility features from any screen. \n\nTo get started, go to accessibility settings and select a feature. Tap on the shortcut and select the accessibility button.</string>
|
||||
<!-- Title for the location of the accessibility button. [CHAR LIMIT=35] -->
|
||||
<string name="accessibility_button_location_title">Location</string>
|
||||
<!-- Title for the size of the accessibility button. [CHAR LIMIT=35] -->
|
||||
<string name="accessibility_button_size_title">Size</string>
|
||||
<!-- Title for the fade of the accessibility button. [CHAR LIMIT=35] -->
|
||||
<string name="accessibility_button_fade_title">Fade when not in use</string>
|
||||
<!-- Summary for the fade of the accessibility button. [CHAR LIMIT=80] -->
|
||||
<string name="accessibility_button_fade_summary">Fades after a few seconds so it\u2019s easier to see your screen</string>
|
||||
<!-- Title for the transparency of the accessibility button. Will become fade when not interact with the accessibility button. [CHAR LIMIT=40] -->
|
||||
<string name="accessibility_button_opacity_title">Transparency when not in use</string>
|
||||
<!-- Label on the left side of transparency adjustment slider [CHAR LIMIT=30] -->
|
||||
<string name="accessibility_button_low_label">Transparent</string>
|
||||
<!-- Label on the right side of transparency adjustment slider [CHAR LIMIT=30] -->
|
||||
<string name="accessibility_button_high_label">Non-transparent</string>
|
||||
<!-- Title for the accessibility preference to high contrast text. [CHAR LIMIT=35] -->
|
||||
<string name="accessibility_toggle_high_text_contrast_preference_title">High contrast text</string>
|
||||
<!-- Title for the accessibility preference to auto update screen magnification. [CHAR LIMIT=35] -->
|
||||
@@ -5338,15 +5366,17 @@
|
||||
<!-- Summary shown for tritanomaly (blue-yellow color blindness) [CHAR LIMIT=45] -->
|
||||
<string name="daltonizer_mode_tritanomaly_summary">Blue-yellow</string>
|
||||
|
||||
<!-- Title for the accessibility preference and switch of the Reduce Brightness feature. [CHAR LIMIT=NONE] -->
|
||||
<string name="reduce_bright_colors_preference_title">Reduce brightness</string>
|
||||
<!-- Title for the accessibility preference of the Reduce Brightness feature. [CHAR LIMIT=NONE] -->
|
||||
<string name="reduce_bright_colors_preference_title">Extra dim</string>
|
||||
<!-- Title for the activation switch of the Reduce Brightness feature. [CHAR LIMIT=NONE] -->
|
||||
<string name="reduce_bright_colors_switch_title">Make screen extra dim</string>
|
||||
<!-- Summary for the accessibility preference to configure Reduce Brightness feature. [CHAR LIMIT=NONE] -->
|
||||
<string name="reduce_bright_colors_preference_summary" product="default">Make screen darker than your phone\u2019s minimum brightness</string>
|
||||
<string name="reduce_bright_colors_preference_summary" product="default">Dim screen beyond your phone\u2019s minimum brightness</string>
|
||||
<!-- Summary for the accessibility preference to configure Reduce Brightness feature. [CHAR LIMIT=NONE] -->
|
||||
<string name="reduce_bright_colors_preference_summary" product="tablet">Make screen darker than your tablet\u2019s minimum brightness</string>
|
||||
<string name="reduce_bright_colors_preference_summary" product="tablet">Dim screen beyond your tablet\u2019s minimum brightness</string>
|
||||
<!-- Subtitle that describes Reduce Brightness. [CHAR LIMIT=NONE] -->
|
||||
<string name="reduce_bright_colors_preference_subtitle" product="default">
|
||||
<![CDATA[Make your screen darker so it\u2019s more comfortable to read.<br/><br/>
|
||||
<![CDATA[Make your screen dimmer so it\u2019s more comfortable to read.<br/><br/>
|
||||
This can be helpful when:
|
||||
<ol>
|
||||
<li>\u00a0Your phone\u2019s default minimum brightness is still too bright</li>
|
||||
@@ -5366,10 +5396,6 @@
|
||||
</string>
|
||||
<!-- Title for setting the brightness intensity of the display using Reduce Brightness. [CHAR LIMIT=NONE] -->
|
||||
<string name="reduce_bright_colors_intensity_preference_title">Intensity</string>
|
||||
<!-- Start label for setting the brightness intensity of the display using Reduce Brightness. [CHAR LIMIT=50] -->
|
||||
<string name="reduce_bright_colors_intensity_preference_start_label">Slightly darker</string>
|
||||
<!-- End label for setting the brightness intensity of the display using Reduce Brightness. [CHAR LIMIT=NONE] -->
|
||||
<string name="reduce_bright_colors_intensity_preference_end_label">Darkest</string>
|
||||
<!-- Title for setting whether the Reduce Brightness activation state persists across reboots. [CHAR LIMIT=NONE] -->
|
||||
<string name="reduce_bright_colors_persist_preference_title">Keep on after device restarts</string>
|
||||
|
||||
@@ -8193,7 +8219,7 @@
|
||||
<string name="zen_mode_settings_dnd_custom_settings_footer">Do Not Disturb is on for <xliff:g id="rule_names" example="Sleeping and Work">%s</xliff:g> with custom settings.</string>
|
||||
|
||||
<!-- [CHAR LIMIT=120] Zen mode settings footer: Link following zen_mode_settings_dnd_custom_settings_footer to see the currently applied custom dnd settings. -->
|
||||
<string name="zen_mode_settings_dnd_custom_settings_footer_link"><annotation id="link"> View custom settings</annotation></string>
|
||||
<string name="zen_mode_settings_dnd_custom_settings_footer_link"> <annotation id="link">View custom settings</annotation></string>
|
||||
|
||||
<!--[CHAR LIMIT=40] Zen Interruption level: Priority. -->
|
||||
<string name="zen_interruption_level_priority">Priority only</string>
|
||||
@@ -8251,6 +8277,9 @@
|
||||
<!-- Do not disturb settings, main screen, field, duration setting where user can specify how
|
||||
long dnd will last when toggling dnd on from qs) [CHAR LIMIT=100] -->
|
||||
<string name="zen_category_duration">Duration for Quick Settings</string>
|
||||
<!-- Do not disturb settings, main screen, category header describing settings that do not
|
||||
fit in another group [CHAR LIMIT=100] -->
|
||||
<string name="zen_settings_general">General</string>
|
||||
|
||||
<!-- Do not disturb settings, sound and vibrations screen footer [CHAR LIMIT=NONE]-->
|
||||
<string name="zen_sound_footer">When Do Not Disturb is on, sound and vibration will be muted, except for the items you allow above.</string>
|
||||
@@ -12827,7 +12856,9 @@
|
||||
<!-- Title for battery saver main switch preferences. [CHAR LIMIT=50] -->
|
||||
<string name="battery_saver_main_switch_title">Use battery saver</string>
|
||||
<!-- Title for Do Not Disturb main switch preferences. [CHAR LIMIT=50] -->
|
||||
<string name="do_not_disturb_main_switch_title">Use Do Not Disturb</string>
|
||||
<string name="do_not_disturb_main_switch_title_on">Turn off now</string>
|
||||
<!-- Title for Do Not Disturb main switch preferences. [CHAR LIMIT=50] -->
|
||||
<string name="do_not_disturb_main_switch_title_off">Turn on now</string>
|
||||
<!-- Title for Night Light main switch preferences. [CHAR LIMIT=50] -->
|
||||
<string name="night_light_main_switch_title">Use Night Light</string>
|
||||
<!-- Title for NFC main switch preferences. [CHAR LIMIT=50] -->
|
||||
|
||||
70
res/xml/accessibility_button_settings.xml
Normal file
70
res/xml/accessibility_button_settings.xml
Normal file
@@ -0,0 +1,70 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/accessibility_button_title">
|
||||
|
||||
<com.android.settingslib.widget.LayoutPreference
|
||||
android:key="caption_preview"
|
||||
android:title="@string/summary_placeholder"
|
||||
android:layout="@layout/accessibility_button_preview"
|
||||
android:selectable="false"
|
||||
settings:searchable="false"
|
||||
android:persistent="false"
|
||||
settings:controller="com.android.settings.accessibility.AccessibilityButtonPreviewPreferenceController"/>
|
||||
|
||||
<ListPreference
|
||||
android:entries="@array/accessibility_button_location_selector_titles"
|
||||
android:entryValues="@array/accessibility_button_location_selector_values"
|
||||
android:key="accessibility_button_location"
|
||||
android:title="@string/accessibility_button_location_title"
|
||||
android:summary="%s"
|
||||
android:persistent="false"
|
||||
settings:controller="com.android.settings.accessibility.AccessibilityButtonLocationPreferenceController"/>
|
||||
|
||||
<ListPreference
|
||||
android:entries="@array/accessibility_button_size_selector_titles"
|
||||
android:entryValues="@array/accessibility_button_size_selector_values"
|
||||
android:key="accessibility_button_size"
|
||||
android:title="@string/accessibility_button_size_title"
|
||||
android:summary="%s"
|
||||
android:persistent="false"
|
||||
settings:controller="com.android.settings.accessibility.FloatingMenuSizePreferenceController"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="accessibility_button_fade"
|
||||
android:title="@string/accessibility_button_fade_title"
|
||||
android:summary="@string/accessibility_button_fade_summary"
|
||||
android:persistent="false"
|
||||
settings:controller="com.android.settings.accessibility.FloatingMenuFadePreferenceController"/>
|
||||
|
||||
<com.android.settings.widget.SeekBarPreference
|
||||
android:key="accessibility_button_opacity"
|
||||
android:title="@string/accessibility_button_opacity_title"
|
||||
android:selectable="true"
|
||||
android:persistent="false"
|
||||
settings:controller="com.android.settings.accessibility.FloatingMenuOpacityPreferenceController"/>
|
||||
|
||||
<com.android.settingslib.widget.FooterPreference
|
||||
android:key="accessibility_button_footer"
|
||||
android:title="@string/accessibility_button_description"
|
||||
android:selectable="false"
|
||||
settings:searchable="false"
|
||||
android:persistent="false"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -21,6 +21,13 @@
|
||||
android:persistent="false"
|
||||
android:title="@string/accessibility_shortcuts_settings_title">
|
||||
|
||||
<Preference
|
||||
android:fragment="com.android.settings.accessibility.AccessibilityButtonFragment"
|
||||
android:key="accessibility_button_preference"
|
||||
android:persistent="false"
|
||||
android:title="@string/accessibility_button_title"
|
||||
android:summary="@string/accessibility_button_summary"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="accessibility_shortcut_preference"
|
||||
android:persistent="false"
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="network_and_internet_screen"
|
||||
android:title="@string/network_dashboard_title"
|
||||
settings:initialExpandedChildrenCount="5">
|
||||
android:title="@string/network_dashboard_title">
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="multi_network_header"
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="network_provider_and_internet_screen"
|
||||
android:title="@string/network_dashboard_title"
|
||||
settings:initialExpandedChildrenCount="5">
|
||||
android:title="@string/network_dashboard_title">
|
||||
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:fragment="com.android.settings.network.NetworkProviderSettings"
|
||||
|
||||
@@ -17,16 +17,13 @@
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:persistent="false"
|
||||
android:title="@string/reduce_bright_colors_preference_title">
|
||||
|
||||
<com.android.settings.widget.LabeledContinuousSeekBarPreference
|
||||
<com.android.settings.widget.SeekBarPreference
|
||||
android:key="rbc_intensity"
|
||||
android:persistent="false"
|
||||
android:title="@string/reduce_bright_colors_intensity_preference_title"
|
||||
settings:textStart="@string/reduce_bright_colors_intensity_preference_start_label"
|
||||
settings:textEnd="@string/reduce_bright_colors_intensity_preference_end_label"/>
|
||||
android:title="@string/reduce_bright_colors_intensity_preference_title"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="rbc_persist"
|
||||
|
||||
@@ -36,149 +36,124 @@
|
||||
android:title="@string/connected_devices_dashboard_title"
|
||||
settings:controller="com.android.settings.connecteddevice.TopLevelConnectedDevicesPreferenceController"/>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="apps"
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.applications.AppDashboardFragment"
|
||||
android:icon="@drawable/ic_homepage_apps_v2"
|
||||
android:key="top_level_apps"
|
||||
android:order="-120"
|
||||
settings:allowDividerAbove="false">
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.applications.AppDashboardFragment"
|
||||
android:icon="@drawable/ic_homepage_apps_v2"
|
||||
android:key="top_level_apps"
|
||||
android:order="-120"
|
||||
android:title="@string/apps_dashboard_title"/>
|
||||
android:title="@string/apps_dashboard_title"/>
|
||||
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.notification.ConfigureNotificationSettings"
|
||||
android:icon="@drawable/ic_homepage_notification_v2"
|
||||
android:key="top_level_notification"
|
||||
android:order="-110"
|
||||
android:title="@string/configure_notification_settings"/>
|
||||
</PreferenceCategory>
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.notification.ConfigureNotificationSettings"
|
||||
android:icon="@drawable/ic_homepage_notification_v2"
|
||||
android:key="top_level_notification"
|
||||
android:order="-110"
|
||||
android:title="@string/configure_notification_settings"/>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="phone_essential"
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.fuelgauge.PowerUsageSummary"
|
||||
android:icon="@drawable/ic_homepage_battery_v2"
|
||||
android:key="top_level_battery"
|
||||
android:order="-100"
|
||||
settings:allowDividerAbove="false">
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.fuelgauge.PowerUsageSummary"
|
||||
android:icon="@drawable/ic_homepage_battery_v2"
|
||||
android:key="top_level_battery"
|
||||
android:order="-100"
|
||||
android:title="@string/power_usage_summary_title"
|
||||
settings:controller="com.android.settings.fuelgauge.TopLevelBatteryPreferenceController"/>
|
||||
android:title="@string/power_usage_summary_title"
|
||||
settings:controller="com.android.settings.fuelgauge.TopLevelBatteryPreferenceController"/>
|
||||
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.deviceinfo.StorageSettings"
|
||||
android:icon="@drawable/ic_homepage_storage_v2"
|
||||
android:key="top_level_storage"
|
||||
android:order="-90"
|
||||
android:title="@string/storage_settings"
|
||||
settings:controller="com.android.settings.deviceinfo.TopLevelStoragePreferenceController"/>
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.deviceinfo.StorageSettings"
|
||||
android:icon="@drawable/ic_homepage_storage_v2"
|
||||
android:key="top_level_storage"
|
||||
android:order="-90"
|
||||
android:title="@string/storage_settings"
|
||||
settings:controller="com.android.settings.deviceinfo.TopLevelStoragePreferenceController"/>
|
||||
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.notification.SoundSettings"
|
||||
android:icon="@drawable/ic_homepage_sound_v2"
|
||||
android:key="top_level_sound"
|
||||
android:order="-80"
|
||||
android:title="@string/sound_settings"/>
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.notification.SoundSettings"
|
||||
android:icon="@drawable/ic_homepage_sound_v2"
|
||||
android:key="top_level_sound"
|
||||
android:order="-80"
|
||||
android:title="@string/sound_settings"/>
|
||||
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.DisplaySettings"
|
||||
android:icon="@drawable/ic_homepage_display_v2"
|
||||
android:key="top_level_display"
|
||||
android:order="-70"
|
||||
android:title="@string/display_settings"
|
||||
settings:controller="com.android.settings.display.TopLevelDisplayPreferenceController"/>
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.DisplaySettings"
|
||||
android:icon="@drawable/ic_homepage_display_v2"
|
||||
android:key="top_level_display"
|
||||
android:order="-70"
|
||||
android:title="@string/display_settings"
|
||||
settings:controller="com.android.settings.display.TopLevelDisplayPreferenceController"/>
|
||||
|
||||
<com.android.settings.homepage.RestrictedHomepagePreference
|
||||
android:icon="@drawable/ic_homepage_wallpaper_v2"
|
||||
android:key="top_level_wallpaper"
|
||||
android:order="-60"
|
||||
android:title="@string/wallpaper_settings_title"
|
||||
settings:controller="com.android.settings.display.TopLevelWallpaperPreferenceController"/>
|
||||
<com.android.settings.homepage.RestrictedHomepagePreference
|
||||
android:icon="@drawable/ic_homepage_wallpaper_v2"
|
||||
android:key="top_level_wallpaper"
|
||||
android:order="-60"
|
||||
android:title="@string/wallpaper_settings_title"
|
||||
settings:controller="com.android.settings.display.TopLevelWallpaperPreferenceController"/>
|
||||
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.accessibility.AccessibilitySettings"
|
||||
android:icon="@drawable/ic_homepage_accessibility_v2"
|
||||
android:key="top_level_accessibility"
|
||||
android:order="-50"
|
||||
android:title="@string/accessibility_settings"
|
||||
settings:controller="com.android.settings.accessibility.TopLevelAccessibilityPreferenceController"/>
|
||||
</PreferenceCategory>
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.accessibility.AccessibilitySettings"
|
||||
android:icon="@drawable/ic_homepage_accessibility_v2"
|
||||
android:key="top_level_accessibility"
|
||||
android:order="-50"
|
||||
android:title="@string/accessibility_settings"
|
||||
settings:controller="com.android.settings.accessibility.TopLevelAccessibilityPreferenceController"/>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="privacy_and_security"
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.privacy.PrivacyDashboardFragment"
|
||||
android:icon="@drawable/ic_homepage_privacy_v2"
|
||||
android:key="top_level_privacy"
|
||||
android:order="-40"
|
||||
settings:allowDividerAbove="false">
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.privacy.PrivacyDashboardFragment"
|
||||
android:icon="@drawable/ic_homepage_privacy_v2"
|
||||
android:key="top_level_privacy"
|
||||
android:order="-40"
|
||||
android:title="@string/privacy_dashboard_title"/>
|
||||
android:title="@string/privacy_dashboard_title"/>
|
||||
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.location.LocationSettings"
|
||||
android:icon="@drawable/ic_homepage_location_v2"
|
||||
android:key="top_level_location"
|
||||
android:order="-30"
|
||||
android:title="@string/location_settings_title"
|
||||
settings:controller="com.android.settings.location.TopLevelLocationPreferenceController"/>
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.location.LocationSettings"
|
||||
android:icon="@drawable/ic_homepage_location_v2"
|
||||
android:key="top_level_location"
|
||||
android:order="-30"
|
||||
android:title="@string/location_settings_title"
|
||||
settings:controller="com.android.settings.location.TopLevelLocationPreferenceController"/>
|
||||
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.security.SecuritySettings"
|
||||
android:icon="@drawable/ic_homepage_security_v2"
|
||||
android:key="top_level_security"
|
||||
android:order="-20"
|
||||
android:title="@string/security_settings_title"
|
||||
settings:controller="com.android.settings.security.TopLevelSecurityEntryPreferenceController"/>
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.security.SecuritySettings"
|
||||
android:icon="@drawable/ic_homepage_security_v2"
|
||||
android:key="top_level_security"
|
||||
android:order="-20"
|
||||
android:title="@string/security_settings_title"
|
||||
settings:controller="com.android.settings.security.TopLevelSecurityEntryPreferenceController"/>
|
||||
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:key="top_level_emergency"
|
||||
android:title="@string/emergency_settings_preference_title"
|
||||
android:icon="@drawable/ic_homepage_emergency_v2"
|
||||
android:order="-10"
|
||||
android:fragment="com.android.settings.emergency.EmergencyDashboardFragment"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="accounts"
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:key="top_level_emergency"
|
||||
android:title="@string/emergency_settings_preference_title"
|
||||
android:icon="@drawable/ic_homepage_emergency_v2"
|
||||
android:order="-10"
|
||||
settings:allowDividerAbove="false">
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.accounts.AccountDashboardFragment"
|
||||
android:icon="@drawable/ic_homepage_accounts_v2"
|
||||
android:key="top_level_accounts"
|
||||
android:order="-10"
|
||||
android:title="@string/account_dashboard_title"
|
||||
settings:controller="com.android.settings.accounts.TopLevelAccountEntryPreferenceController"/>
|
||||
</PreferenceCategory>
|
||||
android:fragment="com.android.settings.emergency.EmergencyDashboardFragment"/>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="system"
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.accounts.AccountDashboardFragment"
|
||||
android:icon="@drawable/ic_homepage_accounts_v2"
|
||||
android:key="top_level_accounts"
|
||||
android:order="-10"
|
||||
android:title="@string/account_dashboard_title"
|
||||
settings:controller="com.android.settings.accounts.TopLevelAccountEntryPreferenceController"/>
|
||||
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.system.SystemDashboardFragment"
|
||||
android:icon="@drawable/ic_homepage_system_dashboard_v2"
|
||||
android:key="top_level_system"
|
||||
android:order="10"
|
||||
settings:allowDividerAbove="false">
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.system.SystemDashboardFragment"
|
||||
android:icon="@drawable/ic_homepage_system_dashboard_v2"
|
||||
android:key="top_level_system"
|
||||
android:order="10"
|
||||
android:title="@string/header_category_system"/>
|
||||
android:title="@string/header_category_system"/>
|
||||
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment"
|
||||
android:icon="@drawable/ic_homepage_about_v2"
|
||||
android:key="top_level_about_device"
|
||||
android:order="20"
|
||||
android:title="@string/about_settings"
|
||||
settings:controller="com.android.settings.deviceinfo.aboutphone.TopLevelAboutDevicePreferenceController"/>
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:fragment="com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment"
|
||||
android:icon="@drawable/ic_homepage_about_v2"
|
||||
android:key="top_level_about_device"
|
||||
android:order="20"
|
||||
android:title="@string/about_settings"
|
||||
settings:controller="com.android.settings.deviceinfo.aboutphone.TopLevelAboutDevicePreferenceController"/>
|
||||
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:icon="@drawable/ic_homepage_support_v2"
|
||||
android:key="top_level_support"
|
||||
android:order="100"
|
||||
android:title="@string/page_tab_title_support"
|
||||
settings:controller="com.android.settings.support.SupportPreferenceController"/>
|
||||
</PreferenceCategory>
|
||||
<com.android.settings.homepage.HomepagePreference
|
||||
android:icon="@drawable/ic_homepage_support_v2"
|
||||
android:key="top_level_support"
|
||||
android:order="100"
|
||||
android:title="@string/page_tab_title_support"
|
||||
settings:controller="com.android.settings.support.SupportPreferenceController"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -37,12 +37,13 @@
|
||||
android:persistent="false"
|
||||
android:title="@string/wifi_hotspot_password_title"/>
|
||||
|
||||
<ListPreference
|
||||
android:key="wifi_tether_network_ap_band"
|
||||
android:title="@string/wifi_hotspot_ap_band_title"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="wifi_tether_auto_turn_off"
|
||||
android:title="@string/wifi_hotspot_auto_off_title"
|
||||
android:summary="@string/wifi_hotspot_auto_off_summary"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="wifi_tether_maximize_compatibility"
|
||||
android:title="@string/wifi_hotspot_maximize_compatibility"
|
||||
android:summary="@string/wifi_hotspot_maximize_compatibility_summary"/>
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
<!-- Turn on DND button -->
|
||||
<com.android.settingslib.widget.MainSwitchPreference
|
||||
android:key="zen_mode_toggle"
|
||||
android:title="@string/do_not_disturb_main_switch_title"
|
||||
settings:keywords="@string/keywords_zen_mode_settings"/>
|
||||
|
||||
<PreferenceCategory
|
||||
@@ -49,15 +48,18 @@
|
||||
</PreferenceCategory>
|
||||
|
||||
<!-- Automatic rules -->
|
||||
<Preference
|
||||
android:key="zen_mode_automation_settings"
|
||||
android:title="@string/zen_category_schedule"
|
||||
settings:allowDividerAbove="true"
|
||||
android:fragment="com.android.settings.notification.zen.ZenModeAutomationSettings"/>
|
||||
<PreferenceCategory
|
||||
android:key="zen_mode_settings_schedule"
|
||||
android:title="@string/zen_category_schedule">
|
||||
<Preference
|
||||
android:key="zen_mode_automation_settings"
|
||||
android:title="@string/zen_category_schedule"
|
||||
android:fragment="com.android.settings.notification.zen.ZenModeAutomationSettings"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="zen_mode_settings_advanced"
|
||||
settings:initialExpandedChildrenCount="0">
|
||||
android:title="@string/zen_settings_general"
|
||||
android:key="zen_mode_settings_advanced">
|
||||
|
||||
<!-- DND duration settings -->
|
||||
<com.android.settings.notification.zen.ZenDurationDialogPreference
|
||||
|
||||
@@ -44,6 +44,8 @@ import com.android.net.module.util.ProxyUtils;
|
||||
import com.android.settings.SettingsPreferenceFragment.SettingsDialogFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ProxySelector extends InstrumentedFragment implements DialogCreatable {
|
||||
private static final String TAG = "ProxySelector";
|
||||
|
||||
@@ -229,7 +231,9 @@ public class ProxySelector extends InstrumentedFragment implements DialogCreatab
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ProxyInfo p = new ProxyInfo(hostname, port, exclList);
|
||||
|
||||
ProxyInfo p = ProxyInfo.buildDirectProxy(
|
||||
hostname, port, Arrays.asList(exclList.split(",")));
|
||||
// FIXME: The best solution would be to make a better UI that would
|
||||
// disable editing of the text boxes if the user chooses to use the
|
||||
// default settings. i.e. checking a box to always use the default
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
|
||||
/** Settings fragment containing accessibility button properties. */
|
||||
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
|
||||
public class AccessibilityButtonFragment extends DashboardFragment {
|
||||
|
||||
private static final String TAG = "AccessibilityButtonFragment";
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.accessibility_button_settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.ACCESSIBILITY_BUTTON_SETTINGS;
|
||||
}
|
||||
|
||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider(R.xml.accessibility_button_settings);
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
|
||||
/** Preference controller that controls the preferred location in accessibility button page. */
|
||||
public class AccessibilityButtonLocationPreferenceController extends BasePreferenceController
|
||||
implements Preference.OnPreferenceChangeListener {
|
||||
|
||||
private final ArrayMap<String, String> mValueTitleMap = new ArrayMap<>();
|
||||
private int mDefaultLocation;
|
||||
|
||||
public AccessibilityButtonLocationPreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
initValueTitleMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AccessibilityUtil.isGestureNavigateEnabled(mContext)
|
||||
? DISABLED_DEPENDENT_SETTING : AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final ListPreference listPreference = (ListPreference) preference;
|
||||
final Integer value = Ints.tryParse((String) newValue);
|
||||
if (value != null) {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_MODE, value);
|
||||
updateState(listPreference);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
final ListPreference listPreference = (ListPreference) preference;
|
||||
|
||||
listPreference.setValue(getCurrentAccessibilityButtonMode());
|
||||
}
|
||||
|
||||
private String getCurrentAccessibilityButtonMode() {
|
||||
final int mode = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_MODE, mDefaultLocation);
|
||||
return String.valueOf(mode);
|
||||
}
|
||||
|
||||
private void initValueTitleMap() {
|
||||
if (mValueTitleMap.size() == 0) {
|
||||
final String[] values = mContext.getResources().getStringArray(
|
||||
R.array.accessibility_button_location_selector_values);
|
||||
final String[] titles = mContext.getResources().getStringArray(
|
||||
R.array.accessibility_button_location_selector_titles);
|
||||
final int mapSize = values.length;
|
||||
|
||||
mDefaultLocation = Integer.parseInt(values[0]);
|
||||
for (int i = 0; i < mapSize; i++) {
|
||||
mValueTitleMap.put(values[i], titles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
import com.android.settingslib.widget.LayoutPreference;
|
||||
|
||||
/** Preference controller that controls the preview effect in accessibility button page. */
|
||||
public class AccessibilityButtonPreviewPreferenceController extends BasePreferenceController
|
||||
implements LifecycleObserver, OnResume, OnPause {
|
||||
|
||||
private static final int SMALL_SIZE = 0;
|
||||
private static final float DEFAULT_OPACITY = 0.55f;
|
||||
private static final int DEFAULT_SIZE = 0;
|
||||
|
||||
private final ContentResolver mContentResolver;
|
||||
@VisibleForTesting
|
||||
final ContentObserver mContentObserver;
|
||||
private FloatingMenuLayerDrawable mFloatingMenuPreviewDrawable;
|
||||
|
||||
@VisibleForTesting
|
||||
ImageView mPreview;
|
||||
|
||||
public AccessibilityButtonPreviewPreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mContentResolver = context.getContentResolver();
|
||||
mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
updatePreviewPreference();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
final LayoutPreference preference = screen.findPreference(getPreferenceKey());
|
||||
mPreview = preference.findViewById(R.id.preview_image);
|
||||
|
||||
updatePreviewPreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
mContentResolver.registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_MODE),
|
||||
/* notifyForDescendants= */ false, mContentObserver);
|
||||
mContentResolver.registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE),
|
||||
/* notifyForDescendants= */ false, mContentObserver);
|
||||
mContentResolver.registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY),
|
||||
/* notifyForDescendants= */ false, mContentObserver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
mContentResolver.unregisterContentObserver(mContentObserver);
|
||||
}
|
||||
|
||||
private void updatePreviewPreference() {
|
||||
if (AccessibilityUtil.isFloatingMenuEnabled(mContext)) {
|
||||
final int size = Settings.Secure.getInt(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, DEFAULT_SIZE);
|
||||
final int opacity = (int) (Settings.Secure.getFloat(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, DEFAULT_OPACITY) * 100);
|
||||
final int floatingMenuIconId = (size == SMALL_SIZE)
|
||||
? R.drawable.accessibility_button_preview_small_floating_menu
|
||||
: R.drawable.accessibility_button_preview_large_floating_menu;
|
||||
|
||||
mPreview.setImageDrawable(getFloatingMenuPreviewDrawable(floatingMenuIconId, opacity));
|
||||
// Only change opacity(alpha) would not invoke redraw view, need to invalidate manually.
|
||||
mPreview.invalidate();
|
||||
} else {
|
||||
mPreview.setImageDrawable(
|
||||
mContext.getDrawable(R.drawable.accessibility_button_navigation));
|
||||
}
|
||||
}
|
||||
|
||||
private Drawable getFloatingMenuPreviewDrawable(int resId, int opacity) {
|
||||
if (mFloatingMenuPreviewDrawable == null) {
|
||||
mFloatingMenuPreviewDrawable = FloatingMenuLayerDrawable.createLayerDrawable(
|
||||
mContext, resId, opacity);
|
||||
} else {
|
||||
mFloatingMenuPreviewDrawable.updateLayerDrawable(mContext, resId, opacity);
|
||||
}
|
||||
|
||||
return mFloatingMenuPreviewDrawable;
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.TypedArray;
|
||||
@@ -24,6 +25,7 @@ import android.graphics.drawable.Drawable;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.TextUtils;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.ImageSpan;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -40,6 +42,8 @@ import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.utils.AnnotationSpan;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -253,6 +257,8 @@ public class AccessibilityEditDialogUtils {
|
||||
summary.setVisibility(View.GONE);
|
||||
} else {
|
||||
summary.setText(summaryText);
|
||||
summary.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
summary.setFocusable(false);
|
||||
}
|
||||
final ImageView image = view.findViewById(R.id.image);
|
||||
image.setImageResource(imageResId);
|
||||
@@ -260,10 +266,13 @@ public class AccessibilityEditDialogUtils {
|
||||
|
||||
private static void initSoftwareShortcut(Context context, View view) {
|
||||
final View dialogView = view.findViewById(R.id.software_shortcut);
|
||||
final CharSequence title = context.getText(
|
||||
R.string.accessibility_shortcut_edit_dialog_title_software);
|
||||
final TextView summary = dialogView.findViewById(R.id.summary);
|
||||
final int lineHeight = summary.getLineHeight();
|
||||
setupShortcutWidget(dialogView, retrieveTitle(context),
|
||||
retrieveSummary(context, lineHeight), retrieveImageResId(context));
|
||||
|
||||
setupShortcutWidget(dialogView, title, retrieveSummary(context, lineHeight),
|
||||
retrieveImageResId(context));
|
||||
}
|
||||
|
||||
private static void initHardwareShortcut(Context context, View view) {
|
||||
@@ -297,35 +306,28 @@ public class AccessibilityEditDialogUtils {
|
||||
});
|
||||
}
|
||||
|
||||
private static CharSequence retrieveTitle(Context context) {
|
||||
int resId = R.string.accessibility_shortcut_edit_dialog_title_software;
|
||||
if (AccessibilityUtil.isGestureNavigateEnabled(context)) {
|
||||
resId = AccessibilityUtil.isTouchExploreEnabled(context)
|
||||
? R.string.accessibility_shortcut_edit_dialog_title_software_gesture_talkback
|
||||
: R.string.accessibility_shortcut_edit_dialog_title_software_gesture;
|
||||
}
|
||||
return context.getText(resId);
|
||||
}
|
||||
|
||||
private static CharSequence retrieveSummary(Context context, int lineHeight) {
|
||||
if (AccessibilityUtil.isGestureNavigateEnabled(context)) {
|
||||
final int resId = AccessibilityUtil.isTouchExploreEnabled(context)
|
||||
? R.string.accessibility_shortcut_edit_dialog_summary_software_gesture_talkback
|
||||
: R.string.accessibility_shortcut_edit_dialog_summary_software_gesture;
|
||||
return context.getText(resId);
|
||||
}
|
||||
return getSummaryStringWithIcon(context, lineHeight);
|
||||
return AccessibilityUtil.isFloatingMenuEnabled(context)
|
||||
? getSummaryStringWithLink(context) : getSummaryStringWithIcon(context, lineHeight);
|
||||
}
|
||||
|
||||
private static int retrieveImageResId(Context context) {
|
||||
// TODO(b/142531156): Use vector drawable instead of temporal png file to avoid distorted.
|
||||
int resId = R.drawable.accessibility_shortcut_type_software;
|
||||
if (AccessibilityUtil.isGestureNavigateEnabled(context)) {
|
||||
resId = AccessibilityUtil.isTouchExploreEnabled(context)
|
||||
? R.drawable.accessibility_shortcut_type_software_gesture_talkback
|
||||
: R.drawable.accessibility_shortcut_type_software_gesture;
|
||||
}
|
||||
return resId;
|
||||
return AccessibilityUtil.isFloatingMenuEnabled(context)
|
||||
? R.drawable.accessibility_shortcut_type_software_floating
|
||||
: R.drawable.accessibility_shortcut_type_software;
|
||||
}
|
||||
|
||||
private static CharSequence getSummaryStringWithLink(Context context) {
|
||||
final View.OnClickListener linkListener = v -> new SubSettingLauncher(context)
|
||||
.setDestination(AccessibilityButtonFragment.class.getName())
|
||||
.setSourceMetricsCategory(
|
||||
SettingsEnums.SWITCH_SHORTCUT_DIALOG_ACCESSIBILITY_BUTTON_SETTINGS)
|
||||
.launch();
|
||||
final AnnotationSpan.LinkInfo linkInfo = new AnnotationSpan.LinkInfo(
|
||||
AnnotationSpan.LinkInfo.DEFAULT_ANNOTATION, linkListener);
|
||||
|
||||
return AnnotationSpan.linkify(context.getText(
|
||||
R.string.accessibility_shortcut_edit_dialog_summary_software_floating), linkInfo);
|
||||
}
|
||||
|
||||
private static SpannableString getSummaryStringWithIcon(Context context, int lineHeight) {
|
||||
|
||||
@@ -333,7 +333,8 @@ public final class AccessibilityGestureNavigationTutorial {
|
||||
}
|
||||
|
||||
private static TutorialPage createSoftwareTutorialPage(@NonNull Context context) {
|
||||
final CharSequence title = getSoftwareTitle(context);
|
||||
final CharSequence title = context.getText(
|
||||
R.string.accessibility_tutorial_dialog_title_button);
|
||||
final ImageView image = createSoftwareImage(context);
|
||||
final CharSequence instruction = getSoftwareInstruction(context);
|
||||
final ImageView indicatorIcon =
|
||||
@@ -390,44 +391,19 @@ public final class AccessibilityGestureNavigationTutorial {
|
||||
return tutorialPages;
|
||||
}
|
||||
|
||||
private static CharSequence getSoftwareTitle(Context context) {
|
||||
final boolean isGestureNavigationEnabled =
|
||||
AccessibilityUtil.isGestureNavigateEnabled(context);
|
||||
final int resId = isGestureNavigationEnabled
|
||||
? R.string.accessibility_tutorial_dialog_title_gesture
|
||||
: R.string.accessibility_tutorial_dialog_title_button;
|
||||
|
||||
return context.getText(resId);
|
||||
}
|
||||
|
||||
private static ImageView createSoftwareImage(Context context) {
|
||||
int resId = R.drawable.accessibility_shortcut_type_software;
|
||||
if (AccessibilityUtil.isGestureNavigateEnabled(context)) {
|
||||
resId = AccessibilityUtil.isTouchExploreEnabled(context)
|
||||
? R.drawable.accessibility_shortcut_type_software_gesture_talkback
|
||||
: R.drawable.accessibility_shortcut_type_software_gesture;
|
||||
}
|
||||
final int resId = AccessibilityUtil.isFloatingMenuEnabled(context)
|
||||
? R.drawable.accessibility_shortcut_type_software_floating
|
||||
: R.drawable.accessibility_shortcut_type_software;
|
||||
|
||||
return createImageView(context, resId);
|
||||
}
|
||||
|
||||
private static CharSequence getSoftwareInstruction(Context context) {
|
||||
final boolean isGestureNavigateEnabled =
|
||||
AccessibilityUtil.isGestureNavigateEnabled(context);
|
||||
final boolean isTouchExploreEnabled = AccessibilityUtil.isTouchExploreEnabled(context);
|
||||
int resId = R.string.accessibility_tutorial_dialog_message_button;
|
||||
if (isGestureNavigateEnabled) {
|
||||
resId = isTouchExploreEnabled
|
||||
? R.string.accessibility_tutorial_dialog_message_gesture_talkback
|
||||
: R.string.accessibility_tutorial_dialog_message_gesture;
|
||||
}
|
||||
|
||||
CharSequence text = context.getText(resId);
|
||||
if (resId == R.string.accessibility_tutorial_dialog_message_button) {
|
||||
text = getSoftwareInstructionWithIcon(context, text);
|
||||
}
|
||||
|
||||
return text;
|
||||
return AccessibilityUtil.isFloatingMenuEnabled(context)
|
||||
? context.getText(R.string.accessibility_tutorial_dialog_message_floating_button)
|
||||
: getSoftwareInstructionWithIcon(context,
|
||||
context.getText(R.string.accessibility_tutorial_dialog_message_button));
|
||||
}
|
||||
|
||||
private static CharSequence getSoftwareInstructionWithIcon(Context context, CharSequence text) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
@@ -143,6 +144,13 @@ final class AccessibilityUtil {
|
||||
== NAV_BAR_MODE_GESTURAL;
|
||||
}
|
||||
|
||||
/** Determines if a accessibility floating menu is being used. */
|
||||
public static boolean isFloatingMenuEnabled(Context context) {
|
||||
return Settings.Secure.getInt(context.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_MODE, /* def= */ -1)
|
||||
== ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
|
||||
}
|
||||
|
||||
/** Determines if a touch explore is being used. */
|
||||
public static boolean isTouchExploreEnabled(Context context) {
|
||||
final AccessibilityManager am = context.getSystemService(AccessibilityManager.class);
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
|
||||
/** Preference controller that controls the fade switch button in accessibility button page. */
|
||||
public class FloatingMenuFadePreferenceController extends BasePreferenceController implements
|
||||
Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
|
||||
|
||||
private static final int OFF = 0;
|
||||
private static final int ON = 1;
|
||||
|
||||
private final ContentResolver mContentResolver;
|
||||
@VisibleForTesting
|
||||
final ContentObserver mContentObserver;
|
||||
|
||||
@VisibleForTesting
|
||||
SwitchPreference mPreference;
|
||||
|
||||
public FloatingMenuFadePreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mContentResolver = context.getContentResolver();
|
||||
mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
updateAvailabilityStatus();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AccessibilityUtil.isFloatingMenuEnabled(mContext)
|
||||
? AVAILABLE : DISABLED_DEPENDENT_SETTING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final boolean isEnabled = (boolean) newValue;
|
||||
putFloatingMenuFadeValue(isEnabled);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
final SwitchPreference switchPreference = (SwitchPreference) preference;
|
||||
|
||||
switchPreference.setChecked(getFloatingMenuFadeValue() == ON);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
mContentResolver.registerContentObserver(
|
||||
Settings.Secure.getUriFor(
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_MODE),
|
||||
/* notifyForDescendants= */ false, mContentObserver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
mContentResolver.unregisterContentObserver(mContentObserver);
|
||||
}
|
||||
|
||||
private void updateAvailabilityStatus() {
|
||||
mPreference.setEnabled(AccessibilityUtil.isFloatingMenuEnabled(mContext));
|
||||
}
|
||||
|
||||
private int getFloatingMenuFadeValue() {
|
||||
return Settings.Secure.getInt(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED, ON);
|
||||
}
|
||||
|
||||
private void putFloatingMenuFadeValue(boolean isEnabled) {
|
||||
Settings.Secure.putInt(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED,
|
||||
isEnabled ? ON : OFF);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/** LayerDrawable that contains device icon as background and floating menu icon as foreground. */
|
||||
public class FloatingMenuLayerDrawable extends LayerDrawable {
|
||||
|
||||
private FloatingMenuLayerDrawableState mState;
|
||||
|
||||
/**
|
||||
* Creates a new layer drawable with the list of specified layers.
|
||||
*
|
||||
* @param layers a list of drawables to use as layers in this new drawable,
|
||||
* must be non-null
|
||||
*/
|
||||
private FloatingMenuLayerDrawable(@NonNull Drawable[] layers) {
|
||||
super(layers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the {@link LayerDrawable} that contains device icon as background and floating menu
|
||||
* icon with given {@code opacity} value as foreground.
|
||||
*
|
||||
* @param context the valid context used to get the icon
|
||||
* @param resId the resource ID of the floating menu icon
|
||||
* @param opacity the opacity to apply to the given icon
|
||||
* @return the drawable that combines the device icon and the floating menu icon
|
||||
*/
|
||||
public static FloatingMenuLayerDrawable createLayerDrawable(Context context, int resId,
|
||||
int opacity) {
|
||||
final Drawable bg = context.getDrawable(R.drawable.accessibility_button_preview_base);
|
||||
final FloatingMenuLayerDrawable basicDrawable = new FloatingMenuLayerDrawable(
|
||||
new Drawable[]{bg, null});
|
||||
|
||||
basicDrawable.updateLayerDrawable(context, resId, opacity);
|
||||
return basicDrawable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the drawable with given {@code resId} drawable and {@code opacity}(alpha)
|
||||
* value at index 1 layer.
|
||||
*
|
||||
* @param context the valid context used to get the icon
|
||||
* @param resId the resource ID of the floating menu icon
|
||||
* @param opacity the opacity to apply to the given icon
|
||||
*/
|
||||
public void updateLayerDrawable(Context context, int resId, int opacity) {
|
||||
final Drawable icon = context.getDrawable(resId);
|
||||
icon.setAlpha(opacity);
|
||||
this.setDrawable(/* index= */ 1, icon);
|
||||
this.setConstantState(context, resId, opacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstantState getConstantState() {
|
||||
return mState;
|
||||
}
|
||||
|
||||
/** Stores the constant state and data to the given drawable. */
|
||||
private void setConstantState(Context context, int resId, int opacity) {
|
||||
mState = new FloatingMenuLayerDrawableState(context, resId, opacity);
|
||||
}
|
||||
|
||||
/** {@link ConstantState} to store the data of {@link FloatingMenuLayerDrawable}. */
|
||||
@VisibleForTesting
|
||||
static class FloatingMenuLayerDrawableState extends ConstantState {
|
||||
|
||||
private final Context mContext;
|
||||
private final int mResId;
|
||||
private final int mOpacity;
|
||||
|
||||
FloatingMenuLayerDrawableState(Context context, int resId, int opacity) {
|
||||
mContext = context;
|
||||
mResId = resId;
|
||||
mOpacity = opacity;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Drawable newDrawable() {
|
||||
return createLayerDrawable(mContext, mResId, mOpacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChangingConfigurations() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final FloatingMenuLayerDrawableState that = (FloatingMenuLayerDrawableState) o;
|
||||
return mResId == that.mResId
|
||||
&& mOpacity == that.mOpacity
|
||||
&& Objects.equals(mContext, that.mContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mContext, mResId, mOpacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.core.SliderPreferenceController;
|
||||
import com.android.settings.widget.SeekBarPreference;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
|
||||
/** Preference controller that controls the opacity seekbar in accessibility button page. */
|
||||
public class FloatingMenuOpacityPreferenceController extends SliderPreferenceController
|
||||
implements LifecycleObserver, OnResume, OnPause {
|
||||
|
||||
@VisibleForTesting
|
||||
static final float DEFAULT_OPACITY = 0.55f;
|
||||
private static final int FADE_ENABLED = 1;
|
||||
private static final float MIN_PROGRESS = 10f;
|
||||
private static final float MAX_PROGRESS = 100f;
|
||||
@VisibleForTesting
|
||||
static final float PRECISION = 100f;
|
||||
|
||||
private final ContentResolver mContentResolver;
|
||||
@VisibleForTesting
|
||||
final ContentObserver mContentObserver;
|
||||
|
||||
@VisibleForTesting
|
||||
SeekBarPreference mPreference;
|
||||
|
||||
public FloatingMenuOpacityPreferenceController(Context context,
|
||||
String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mContentResolver = context.getContentResolver();
|
||||
mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
updateAvailabilityStatus();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AccessibilityUtil.isFloatingMenuEnabled(mContext)
|
||||
? AVAILABLE : DISABLED_DEPENDENT_SETTING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
mPreference.setContinuousUpdates(true);
|
||||
mPreference.setMax(getMax());
|
||||
mPreference.setMin(getMin());
|
||||
mPreference.setHapticFeedbackMode(SeekBarPreference.HAPTIC_FEEDBACK_MODE_ON_ENDS);
|
||||
|
||||
updateState(mPreference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
mContentResolver.registerContentObserver(
|
||||
Settings.Secure.getUriFor(
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_MODE), /* notifyForDescendants= */
|
||||
false, mContentObserver);
|
||||
mContentResolver.registerContentObserver(
|
||||
Settings.Secure.getUriFor(
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED),
|
||||
/* notifyForDescendants= */ false, mContentObserver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
mContentResolver.unregisterContentObserver(mContentObserver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSliderPosition() {
|
||||
return convertOpacityFloatToInt(getOpacity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSliderPosition(int position) {
|
||||
final float value = convertOpacityIntToFloat(position);
|
||||
|
||||
return Settings.Secure.putFloat(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMax() {
|
||||
return (int) MAX_PROGRESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMin() {
|
||||
return (int) MIN_PROGRESS;
|
||||
}
|
||||
|
||||
private void updateAvailabilityStatus() {
|
||||
final boolean fadeEnabled = Settings.Secure.getInt(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED, FADE_ENABLED)
|
||||
== FADE_ENABLED;
|
||||
|
||||
mPreference.setEnabled(AccessibilityUtil.isFloatingMenuEnabled(mContext) && fadeEnabled);
|
||||
}
|
||||
|
||||
private int convertOpacityFloatToInt(float value) {
|
||||
return Math.round(value * PRECISION);
|
||||
}
|
||||
|
||||
private float convertOpacityIntToFloat(int value) {
|
||||
return (float) value / PRECISION;
|
||||
}
|
||||
|
||||
private float getOpacity() {
|
||||
float value = Settings.Secure.getFloat(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, DEFAULT_OPACITY);
|
||||
final float minValue = MIN_PROGRESS / PRECISION;
|
||||
final float maxValue = MAX_PROGRESS / PRECISION;
|
||||
|
||||
return (value < minValue || value > maxValue) ? DEFAULT_OPACITY : value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/** Preference controller that controls the preferred size in accessibility button page. */
|
||||
public class FloatingMenuSizePreferenceController extends BasePreferenceController
|
||||
implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
|
||||
|
||||
private final ContentResolver mContentResolver;
|
||||
@VisibleForTesting
|
||||
final ContentObserver mContentObserver;
|
||||
|
||||
@VisibleForTesting
|
||||
ListPreference mPreference;
|
||||
|
||||
private final ArrayMap<String, String> mValueTitleMap = new ArrayMap<>();
|
||||
private int mDefaultSize;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
Size.SMALL,
|
||||
Size.LARGE,
|
||||
})
|
||||
@VisibleForTesting
|
||||
@interface Size {
|
||||
int SMALL = 0;
|
||||
int LARGE = 1;
|
||||
}
|
||||
|
||||
public FloatingMenuSizePreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mContentResolver = context.getContentResolver();
|
||||
mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
updateAvailabilityStatus();
|
||||
}
|
||||
};
|
||||
|
||||
initValueTitleMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AccessibilityUtil.isFloatingMenuEnabled(mContext)
|
||||
? AVAILABLE : DISABLED_DEPENDENT_SETTING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final ListPreference listPreference = (ListPreference) preference;
|
||||
final Integer value = Ints.tryParse((String) newValue);
|
||||
if (value != null) {
|
||||
putAccessibilityFloatingMenuSize(value);
|
||||
updateState(listPreference);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
final ListPreference listPreference = (ListPreference) preference;
|
||||
|
||||
listPreference.setValue(String.valueOf(getAccessibilityFloatingMenuSize(mDefaultSize)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
mContentResolver.registerContentObserver(
|
||||
Settings.Secure.getUriFor(
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_MODE), /* notifyForDescendants= */
|
||||
false, mContentObserver);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
mContentResolver.unregisterContentObserver(mContentObserver);
|
||||
}
|
||||
|
||||
private void updateAvailabilityStatus() {
|
||||
mPreference.setEnabled(AccessibilityUtil.isFloatingMenuEnabled(mContext));
|
||||
}
|
||||
|
||||
private void initValueTitleMap() {
|
||||
if (mValueTitleMap.size() == 0) {
|
||||
final String[] values = mContext.getResources().getStringArray(
|
||||
R.array.accessibility_button_size_selector_values);
|
||||
final String[] titles = mContext.getResources().getStringArray(
|
||||
R.array.accessibility_button_size_selector_titles);
|
||||
final int mapSize = values.length;
|
||||
|
||||
mDefaultSize = Integer.parseInt(values[0]);
|
||||
for (int i = 0; i < mapSize; i++) {
|
||||
mValueTitleMap.put(values[i], titles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Size
|
||||
private int getAccessibilityFloatingMenuSize(@Size int defaultValue) {
|
||||
return Settings.Secure.getInt(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, defaultValue);
|
||||
}
|
||||
|
||||
private void putAccessibilityFloatingMenuSize(@Size int value) {
|
||||
Settings.Secure.putInt(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, value);
|
||||
}
|
||||
}
|
||||
@@ -608,19 +608,15 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
|
||||
|
||||
final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(context,
|
||||
mComponentName.flattenToString(), UserShortcutType.SOFTWARE);
|
||||
int resId = R.string.accessibility_shortcut_edit_summary_software;
|
||||
if (AccessibilityUtil.isGestureNavigateEnabled(context)) {
|
||||
resId = AccessibilityUtil.isTouchExploreEnabled(context)
|
||||
? R.string.accessibility_shortcut_edit_dialog_title_software_gesture_talkback
|
||||
: R.string.accessibility_shortcut_edit_dialog_title_software_gesture;
|
||||
}
|
||||
final CharSequence softwareTitle = context.getText(resId);
|
||||
|
||||
List<CharSequence> list = new ArrayList<>();
|
||||
if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) {
|
||||
final List<CharSequence> list = new ArrayList<>();
|
||||
final CharSequence softwareTitle = context.getText(
|
||||
R.string.accessibility_shortcut_edit_summary_software);
|
||||
|
||||
if (hasShortcutType(shortcutTypes, UserShortcutType.SOFTWARE)) {
|
||||
list.add(softwareTitle);
|
||||
}
|
||||
if ((shortcutTypes & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE) {
|
||||
if (hasShortcutType(shortcutTypes, UserShortcutType.HARDWARE)) {
|
||||
final CharSequence hardwareTitle = context.getText(
|
||||
R.string.accessibility_shortcut_hardware_keyword);
|
||||
list.add(hardwareTitle);
|
||||
|
||||
@@ -80,6 +80,8 @@ public class ToggleReduceBrightColorsPreferenceFragment extends ToggleFeaturePre
|
||||
};
|
||||
|
||||
final View view = super.onCreateView(inflater, container, savedInstanceState);
|
||||
// Parent sets the title when creating the view, so set it after calling super
|
||||
mToggleServiceSwitchPreference.setTitle(R.string.reduce_bright_colors_switch_title);
|
||||
updateGeneralCategoryOrder();
|
||||
return view;
|
||||
}
|
||||
|
||||
@@ -226,27 +226,23 @@ public class ToggleScreenMagnificationPreferenceFragment extends
|
||||
return context.getText(R.string.switch_off_text);
|
||||
}
|
||||
|
||||
final int shortcutType = PreferredShortcuts.retrieveUserShortcutType(context,
|
||||
final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(context,
|
||||
MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE);
|
||||
int resId = R.string.accessibility_shortcut_edit_summary_software;
|
||||
if (AccessibilityUtil.isGestureNavigateEnabled(context)) {
|
||||
resId = AccessibilityUtil.isTouchExploreEnabled(context)
|
||||
? R.string.accessibility_shortcut_edit_dialog_title_software_gesture_talkback
|
||||
: R.string.accessibility_shortcut_edit_dialog_title_software_gesture;
|
||||
}
|
||||
final CharSequence softwareTitle = context.getText(resId);
|
||||
|
||||
List<CharSequence> list = new ArrayList<>();
|
||||
if ((shortcutType & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) {
|
||||
final List<CharSequence> list = new ArrayList<>();
|
||||
final CharSequence softwareTitle = context.getText(
|
||||
R.string.accessibility_shortcut_edit_summary_software);
|
||||
|
||||
if (hasShortcutType(shortcutTypes, UserShortcutType.SOFTWARE)) {
|
||||
list.add(softwareTitle);
|
||||
}
|
||||
if ((shortcutType & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE) {
|
||||
if (hasShortcutType(shortcutTypes, UserShortcutType.HARDWARE)) {
|
||||
final CharSequence hardwareTitle = context.getText(
|
||||
R.string.accessibility_shortcut_hardware_keyword);
|
||||
list.add(hardwareTitle);
|
||||
}
|
||||
|
||||
if ((shortcutType & UserShortcutType.TRIPLETAP) == UserShortcutType.TRIPLETAP) {
|
||||
if (hasShortcutType(shortcutTypes, UserShortcutType.TRIPLETAP)) {
|
||||
final CharSequence tripleTapTitle = context.getText(
|
||||
R.string.accessibility_shortcut_triple_tap_keyword);
|
||||
list.add(tripleTapTitle);
|
||||
|
||||
@@ -30,14 +30,11 @@ import androidx.loader.content.Loader;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.os.BatterySipper;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.fuelgauge.AdvancedPowerUsageDetail;
|
||||
import com.android.settings.fuelgauge.BatteryEntry;
|
||||
import com.android.settings.fuelgauge.BatteryStatsHelperLoader;
|
||||
import com.android.settings.fuelgauge.BatteryUsageStatsLoader;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
@@ -52,22 +49,11 @@ public class AppBatteryPreferenceController extends BasePreferenceController
|
||||
|
||||
private static final String KEY_BATTERY = "battery";
|
||||
|
||||
// TODO(b/180630447): switch to BatteryUsageStatsLoader and remove all references to
|
||||
// BatteryStatsHelper and BatterySipper
|
||||
@VisibleForTesting
|
||||
final BatteryStatsHelperLoaderCallbacks mBatteryStatsHelperLoaderCallbacks =
|
||||
new BatteryStatsHelperLoaderCallbacks();
|
||||
@VisibleForTesting
|
||||
final BatteryUsageStatsLoaderCallbacks mBatteryUsageStatsLoaderCallbacks =
|
||||
new BatteryUsageStatsLoaderCallbacks();
|
||||
|
||||
@VisibleForTesting
|
||||
BatterySipper mSipper;
|
||||
@VisibleForTesting
|
||||
BatteryStatsHelper mBatteryHelper;
|
||||
@VisibleForTesting
|
||||
BatteryUtils mBatteryUtils;
|
||||
|
||||
@VisibleForTesting
|
||||
BatteryUsageStats mBatteryUsageStats;
|
||||
@VisibleForTesting
|
||||
@@ -124,9 +110,6 @@ public class AppBatteryPreferenceController extends BasePreferenceController
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
mParent.getLoaderManager().restartLoader(
|
||||
AppInfoDashboardFragment.LOADER_BATTERY, Bundle.EMPTY,
|
||||
mBatteryStatsHelperLoaderCallbacks);
|
||||
mParent.getLoaderManager().restartLoader(
|
||||
AppInfoDashboardFragment.LOADER_BATTERY_USAGE_STATS, Bundle.EMPTY,
|
||||
mBatteryUsageStatsLoaderCallbacks);
|
||||
@@ -134,20 +117,17 @@ public class AppBatteryPreferenceController extends BasePreferenceController
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
mParent.getLoaderManager().destroyLoader(AppInfoDashboardFragment.LOADER_BATTERY);
|
||||
mParent.getLoaderManager().destroyLoader(
|
||||
AppInfoDashboardFragment.LOADER_BATTERY_USAGE_STATS);
|
||||
}
|
||||
|
||||
private void onLoadFinished() {
|
||||
// Wait for both loaders to finish before proceeding.
|
||||
if (mBatteryHelper == null || mBatteryUsageStats == null) {
|
||||
if (mBatteryUsageStats == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PackageInfo packageInfo = mParent.getPackageInfo();
|
||||
if (packageInfo != null) {
|
||||
mSipper = findTargetSipper(mBatteryHelper, packageInfo.applicationInfo.uid);
|
||||
mUidBatteryConsumer = findTargetUidBatteryConsumer(mBatteryUsageStats,
|
||||
packageInfo.applicationInfo.uid);
|
||||
if (mParent.getActivity() != null) {
|
||||
@@ -172,19 +152,7 @@ public class AppBatteryPreferenceController extends BasePreferenceController
|
||||
|
||||
@VisibleForTesting
|
||||
boolean isBatteryStatsAvailable() {
|
||||
return mBatteryHelper != null && mSipper != null && mUidBatteryConsumer != null;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
BatterySipper findTargetSipper(BatteryStatsHelper batteryHelper, int uid) {
|
||||
final List<BatterySipper> usageList = batteryHelper.getUsageList();
|
||||
for (int i = 0, size = usageList.size(); i < size; i++) {
|
||||
final BatterySipper sipper = usageList.get(i);
|
||||
if (sipper.getUid() == uid) {
|
||||
return sipper;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return mUidBatteryConsumer != null;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -199,25 +167,6 @@ public class AppBatteryPreferenceController extends BasePreferenceController
|
||||
return null;
|
||||
}
|
||||
|
||||
private class BatteryStatsHelperLoaderCallbacks
|
||||
implements LoaderManager.LoaderCallbacks<BatteryStatsHelper> {
|
||||
@Override
|
||||
public Loader<BatteryStatsHelper> onCreateLoader(int id, Bundle args) {
|
||||
return new BatteryStatsHelperLoader(mContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<BatteryStatsHelper> loader,
|
||||
BatteryStatsHelper batteryHelper) {
|
||||
mBatteryHelper = batteryHelper;
|
||||
AppBatteryPreferenceController.this.onLoadFinished();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<BatteryStatsHelper> loader) {
|
||||
}
|
||||
}
|
||||
|
||||
private class BatteryUsageStatsLoaderCallbacks
|
||||
implements LoaderManager.LoaderCallbacks<BatteryUsageStats> {
|
||||
@Override
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.applications.appinfo;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.text.BidiFormatter;
|
||||
|
||||
import com.android.settings.R;
|
||||
@@ -29,7 +30,13 @@ public class AppVersionPreferenceController extends AppInfoPreferenceControllerB
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
// TODO(b/168333280): Review the null case in detail since this is just a quick
|
||||
// workaround to fix NPE.
|
||||
final PackageInfo packageInfo = mParent.getPackageInfo();
|
||||
if (packageInfo == null) {
|
||||
return null;
|
||||
}
|
||||
return mContext.getString(R.string.version_text,
|
||||
BidiFormatter.getInstance().unicodeWrap(mParent.getPackageInfo().versionName));
|
||||
BidiFormatter.getInstance().unicodeWrap(packageInfo.versionName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
package com.android.settings.datetime;
|
||||
|
||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_NOT_ALLOWED;
|
||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_NOT_APPLICABLE;
|
||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_NOT_SUPPORTED;
|
||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_POSSESSED;
|
||||
import static android.app.time.Capabilities.CAPABILITY_NOT_ALLOWED;
|
||||
import static android.app.time.Capabilities.CAPABILITY_NOT_APPLICABLE;
|
||||
import static android.app.time.Capabilities.CAPABILITY_NOT_SUPPORTED;
|
||||
import static android.app.time.Capabilities.CAPABILITY_POSSESSED;
|
||||
|
||||
import android.app.time.TimeManager;
|
||||
import android.app.time.TimeZoneCapabilities;
|
||||
|
||||
@@ -105,7 +105,7 @@ public class TopLevelWallpaperPreferenceController extends BasePreferenceControl
|
||||
final Intent intent = new Intent().setComponent(
|
||||
getComponentName()).putExtra(mWallpaperLaunchExtra, LAUNCHED_SETTINGS);
|
||||
if (areStylesAvailable()) {
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
}
|
||||
preference.getContext().startActivity(intent);
|
||||
return true;
|
||||
|
||||
@@ -1,57 +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 android.content.Context;
|
||||
import android.os.UserManager;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settingslib.utils.AsyncLoaderCompat;
|
||||
|
||||
/**
|
||||
* Loader to get new {@link BatteryStatsHelper} in the background
|
||||
*/
|
||||
public class BatteryStatsHelperLoader extends AsyncLoaderCompat<BatteryStatsHelper> {
|
||||
@VisibleForTesting
|
||||
UserManager mUserManager;
|
||||
@VisibleForTesting
|
||||
BatteryUtils mBatteryUtils;
|
||||
|
||||
public BatteryStatsHelperLoader(Context context) {
|
||||
super(context);
|
||||
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
mBatteryUtils = BatteryUtils.getInstance(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BatteryStatsHelper loadInBackground() {
|
||||
Context context = getContext();
|
||||
final BatteryStatsHelper statsHelper = new BatteryStatsHelper(context,
|
||||
true /* collectBatteryBroadcast */);
|
||||
mBatteryUtils.initBatteryStatsHelper(statsHelper, null /* bundle */, mUserManager);
|
||||
|
||||
return statsHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDiscardResult(BatteryStatsHelper result) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -42,7 +42,6 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.android.internal.os.BatterySipper;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
|
||||
@@ -173,22 +172,12 @@ public class BatteryUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether we should hide the battery sipper.
|
||||
* Returns true if the specified battery consumer should be excluded from the summary
|
||||
* battery consumption list.
|
||||
*/
|
||||
public boolean shouldHideSipper(BatterySipper sipper) {
|
||||
final BatterySipper.DrainType drainType = sipper.drainType;
|
||||
|
||||
return drainType == BatterySipper.DrainType.IDLE
|
||||
|| drainType == BatterySipper.DrainType.CELL
|
||||
|| drainType == BatterySipper.DrainType.SCREEN
|
||||
|| drainType == BatterySipper.DrainType.UNACCOUNTED
|
||||
|| drainType == BatterySipper.DrainType.OVERCOUNTED
|
||||
|| drainType == BatterySipper.DrainType.BLUETOOTH
|
||||
|| drainType == BatterySipper.DrainType.WIFI
|
||||
|| (sipper.totalPowerMah * SECONDS_IN_HOUR) < MIN_POWER_THRESHOLD_MILLI_AMP
|
||||
|| mPowerUsageFeatureProvider.isTypeService(sipper)
|
||||
|| mPowerUsageFeatureProvider.isTypeSystem(sipper)
|
||||
|| isHiddenSystemModule(sipper);
|
||||
public boolean shouldHideUidBatteryConsumer(UidBatteryConsumer consumer) {
|
||||
return shouldHideUidBatteryConsumer(consumer,
|
||||
mPackageManager.getPackagesForUid(consumer.getUid()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,17 +216,6 @@ public class BatteryUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if one of packages in {@code sipper} is hidden system modules
|
||||
*/
|
||||
public boolean isHiddenSystemModule(BatterySipper sipper) {
|
||||
if (sipper.uidObj == null) {
|
||||
return false;
|
||||
}
|
||||
sipper.mPackages = mPackageManager.getPackagesForUid(sipper.getUid());
|
||||
return isHiddenSystemModule(sipper.mPackages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if one the specified packages belongs to a hidden system module.
|
||||
*/
|
||||
@@ -270,23 +248,6 @@ public class BatteryUtils {
|
||||
return (powerUsageMah / totalPowerMah) * dischargeAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the whole running time in the state {@code statsType}
|
||||
*
|
||||
* @param batteryStatsHelper utility class that contains the data
|
||||
* @param statsType state that we want to calculate the time for
|
||||
* @return the running time in millis
|
||||
*/
|
||||
public long calculateRunningTimeBasedOnStatsType(BatteryStatsHelper batteryStatsHelper,
|
||||
int statsType) {
|
||||
final long elapsedRealtimeUs = PowerUtil.convertMsToUs(
|
||||
SystemClock.elapsedRealtime());
|
||||
// Return the battery time (millisecond) on status mStatsType
|
||||
return PowerUtil.convertUsToMs(
|
||||
batteryStatsHelper.getStats().computeBatteryRealtime(elapsedRealtimeUs, statsType));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the package name for a {@link android.os.BatteryStats.Uid}
|
||||
*
|
||||
@@ -336,14 +297,13 @@ public class BatteryUtils {
|
||||
/**
|
||||
* Calculate the time since last full charge, including the device off time
|
||||
*
|
||||
* @param batteryStatsHelper utility class that contains the data
|
||||
* @param batteryUsageStats class that contains the data
|
||||
* @param currentTimeMs current wall time
|
||||
* @return time in millis
|
||||
*/
|
||||
public long calculateLastFullChargeTime(BatteryStatsHelper batteryStatsHelper,
|
||||
public long calculateLastFullChargeTime(BatteryUsageStats batteryUsageStats,
|
||||
long currentTimeMs) {
|
||||
return currentTimeMs - batteryStatsHelper.getStats().getStartClockTime();
|
||||
|
||||
return currentTimeMs - batteryUsageStats.getStatsStartRealtime();
|
||||
}
|
||||
|
||||
public static void logRuntime(String tag, String message, long startTime) {
|
||||
|
||||
@@ -29,7 +29,6 @@ import androidx.annotation.VisibleForTesting;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.loader.content.Loader;
|
||||
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
|
||||
/**
|
||||
@@ -44,10 +43,8 @@ public abstract class PowerUsageBase extends DashboardFragment {
|
||||
private static final String KEY_REFRESH_TYPE = "refresh_type";
|
||||
private static final String KEY_INCLUDE_HISTORY = "include_history";
|
||||
|
||||
private static final int LOADER_BATTERY_STATS_HELPER = 0;
|
||||
private static final int LOADER_BATTERY_USAGE_STATS = 1;
|
||||
|
||||
protected BatteryStatsHelper mStatsHelper;
|
||||
@VisibleForTesting
|
||||
BatteryUsageStats mBatteryUsageStats;
|
||||
|
||||
@@ -55,12 +52,6 @@ public abstract class PowerUsageBase extends DashboardFragment {
|
||||
private BatteryBroadcastReceiver mBatteryBroadcastReceiver;
|
||||
protected boolean mIsBatteryPresent = true;
|
||||
|
||||
// TODO(b/180630447): switch to BatteryUsageStatsLoader and remove all references to
|
||||
// BatteryStatsHelper and BatterySipper
|
||||
@VisibleForTesting
|
||||
final BatteryStatsHelperLoaderCallbacks mBatteryStatsHelperLoaderCallbacks =
|
||||
new BatteryStatsHelperLoaderCallbacks();
|
||||
|
||||
@VisibleForTesting
|
||||
final BatteryUsageStatsLoaderCallbacks mBatteryUsageStatsLoaderCallbacks =
|
||||
new BatteryUsageStatsLoaderCallbacks();
|
||||
@@ -69,13 +60,11 @@ public abstract class PowerUsageBase extends DashboardFragment {
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
mUm = (UserManager) activity.getSystemService(Context.USER_SERVICE);
|
||||
mStatsHelper = new BatteryStatsHelper(activity, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
mStatsHelper.create(icicle);
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
mBatteryBroadcastReceiver = new BatteryBroadcastReceiver(getContext());
|
||||
@@ -103,18 +92,11 @@ public abstract class PowerUsageBase extends DashboardFragment {
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putInt(KEY_REFRESH_TYPE, refreshType);
|
||||
bundle.putBoolean(KEY_INCLUDE_HISTORY, isBatteryHistoryNeeded());
|
||||
getLoaderManager().restartLoader(LOADER_BATTERY_STATS_HELPER, bundle,
|
||||
mBatteryStatsHelperLoaderCallbacks);
|
||||
getLoaderManager().restartLoader(LOADER_BATTERY_USAGE_STATS, bundle,
|
||||
mBatteryUsageStatsLoaderCallbacks);
|
||||
}
|
||||
|
||||
private void onLoadFinished(@BatteryUpdateType int refreshType) {
|
||||
// Wait for both loaders to finish before proceeding.
|
||||
if (mStatsHelper == null || mBatteryUsageStats == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
refreshUi(refreshType);
|
||||
}
|
||||
|
||||
@@ -127,28 +109,6 @@ public abstract class PowerUsageBase extends DashboardFragment {
|
||||
BatteryUtils.logRuntime(TAG, "updatePreference", startTime);
|
||||
}
|
||||
|
||||
private class BatteryStatsHelperLoaderCallbacks
|
||||
implements LoaderManager.LoaderCallbacks<BatteryStatsHelper> {
|
||||
private int mRefreshType;
|
||||
|
||||
@Override
|
||||
public Loader<BatteryStatsHelper> onCreateLoader(int id, Bundle args) {
|
||||
mRefreshType = args.getInt(KEY_REFRESH_TYPE);
|
||||
return new BatteryStatsHelperLoader(getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<BatteryStatsHelper> loader,
|
||||
BatteryStatsHelper batteryHelper) {
|
||||
mStatsHelper = batteryHelper;
|
||||
PowerUsageBase.this.onLoadFinished(mRefreshType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<BatteryStatsHelper> loader) {
|
||||
}
|
||||
}
|
||||
|
||||
private class BatteryUsageStatsLoaderCallbacks
|
||||
implements LoaderManager.LoaderCallbacks<BatteryUsageStats> {
|
||||
private int mRefreshType;
|
||||
|
||||
@@ -108,7 +108,7 @@ public class PowerUsageSummary extends PowerUsageBase implements
|
||||
|
||||
@Override
|
||||
public Loader<List<BatteryTip>> onCreateLoader(int id, Bundle args) {
|
||||
return new BatteryTipLoader(getContext(), mStatsHelper);
|
||||
return new BatteryTipLoader(getContext(), mBatteryUsageStats);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -93,6 +93,13 @@ public class RequestIgnoreBatteryOptimizations extends AlertActivity implements
|
||||
setupAlert();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
getWindow().addSystemFlags(android.view.WindowManager.LayoutParams
|
||||
.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which) {
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
package com.android.settings.fuelgauge.batterytip;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.BatteryUsageStats;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.fuelgauge.BatteryInfo;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.fuelgauge.batterytip.detectors.BatteryDefenderDetector;
|
||||
@@ -48,13 +48,13 @@ public class BatteryTipLoader extends AsyncLoaderCompat<List<BatteryTip>> {
|
||||
|
||||
private static final boolean USE_FAKE_DATA = false;
|
||||
|
||||
private BatteryStatsHelper mBatteryStatsHelper;
|
||||
private BatteryUsageStats mBatteryUsageStats;
|
||||
@VisibleForTesting
|
||||
BatteryUtils mBatteryUtils;
|
||||
|
||||
public BatteryTipLoader(Context context, BatteryStatsHelper batteryStatsHelper) {
|
||||
public BatteryTipLoader(Context context, BatteryUsageStats batteryUsageStats) {
|
||||
super(context);
|
||||
mBatteryStatsHelper = batteryStatsHelper;
|
||||
mBatteryUsageStats = batteryUsageStats;
|
||||
mBatteryUtils = BatteryUtils.getInstance(context);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class BatteryTipLoader extends AsyncLoaderCompat<List<BatteryTip>> {
|
||||
final Context context = getContext();
|
||||
|
||||
tips.add(new LowBatteryDetector(context, policy, batteryInfo).detect());
|
||||
tips.add(new HighUsageDetector(context, policy, mBatteryStatsHelper, batteryInfo).detect());
|
||||
tips.add(new HighUsageDetector(context, policy, mBatteryUsageStats, batteryInfo).detect());
|
||||
tips.add(new SmartBatteryDetector(policy, context.getContentResolver()).detect());
|
||||
tips.add(new EarlyWarningDetector(policy, context).detect());
|
||||
tips.add(new BatteryDefenderDetector(batteryInfo).detect());
|
||||
|
||||
@@ -19,12 +19,11 @@ package com.android.settings.fuelgauge.batterytip.detectors;
|
||||
import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.UidBatteryConsumer;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.os.BatterySipper;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.fuelgauge.BatteryInfo;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
@@ -34,7 +33,6 @@ import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -44,7 +42,7 @@ import java.util.concurrent.TimeUnit;
|
||||
*/
|
||||
public class HighUsageDetector implements BatteryTipDetector {
|
||||
private BatteryTipPolicy mPolicy;
|
||||
private BatteryStatsHelper mBatteryStatsHelper;
|
||||
private BatteryUsageStats mBatteryUsageStats;
|
||||
private final BatteryInfo mBatteryInfo;
|
||||
private List<AppInfo> mHighUsageAppList;
|
||||
@VisibleForTesting
|
||||
@@ -55,9 +53,9 @@ public class HighUsageDetector implements BatteryTipDetector {
|
||||
boolean mDischarging;
|
||||
|
||||
public HighUsageDetector(Context context, BatteryTipPolicy policy,
|
||||
BatteryStatsHelper batteryStatsHelper, BatteryInfo batteryInfo) {
|
||||
BatteryUsageStats batteryUsageStats, BatteryInfo batteryInfo) {
|
||||
mPolicy = policy;
|
||||
mBatteryStatsHelper = batteryStatsHelper;
|
||||
mBatteryUsageStats = batteryUsageStats;
|
||||
mBatteryInfo = batteryInfo;
|
||||
mHighUsageAppList = new ArrayList<>();
|
||||
mBatteryUtils = BatteryUtils.getInstance(context);
|
||||
@@ -69,37 +67,35 @@ public class HighUsageDetector implements BatteryTipDetector {
|
||||
@Override
|
||||
public BatteryTip detect() {
|
||||
final long lastFullChargeTimeMs = mBatteryUtils.calculateLastFullChargeTime(
|
||||
mBatteryStatsHelper, System.currentTimeMillis());
|
||||
mBatteryUsageStats, System.currentTimeMillis());
|
||||
if (mPolicy.highUsageEnabled && mDischarging) {
|
||||
parseBatteryData();
|
||||
if (mDataParser.isDeviceHeavilyUsed() || mPolicy.testHighUsageTip) {
|
||||
final BatteryStats batteryStats = mBatteryStatsHelper.getStats();
|
||||
final List<BatterySipper> batterySippers
|
||||
= new ArrayList<>(mBatteryStatsHelper.getUsageList());
|
||||
final double totalPower = mBatteryStatsHelper.getTotalPower();
|
||||
final int dischargeAmount = batteryStats != null
|
||||
? batteryStats.getDischargeAmount(BatteryStats.STATS_SINCE_CHARGED)
|
||||
: 0;
|
||||
|
||||
Collections.sort(batterySippers,
|
||||
(sipper1, sipper2) -> Double.compare(sipper2.totalSmearedPowerMah,
|
||||
sipper1.totalSmearedPowerMah));
|
||||
for (BatterySipper batterySipper : batterySippers) {
|
||||
final double totalPower = mBatteryUsageStats.getConsumedPower();
|
||||
final int dischargeAmount = mBatteryUsageStats.getDischargePercentage();
|
||||
final List<UidBatteryConsumer> uidBatteryConsumers =
|
||||
mBatteryUsageStats.getUidBatteryConsumers();
|
||||
// Sort by descending power
|
||||
uidBatteryConsumers.sort(
|
||||
(consumer1, consumer2) -> Double.compare(consumer2.getConsumedPower(),
|
||||
consumer1.getConsumedPower()));
|
||||
for (UidBatteryConsumer consumer : uidBatteryConsumers) {
|
||||
final double percent = mBatteryUtils.calculateBatteryPercent(
|
||||
batterySipper.totalSmearedPowerMah, totalPower, dischargeAmount);
|
||||
if ((percent + 0.5f < 1f) || mBatteryUtils.shouldHideSipper(batterySipper)) {
|
||||
consumer.getConsumedPower(), totalPower, dischargeAmount);
|
||||
if ((percent + 0.5f < 1f)
|
||||
|| mBatteryUtils.shouldHideUidBatteryConsumer(consumer)) {
|
||||
// Don't show it if we should hide or usage percentage is lower than 1%
|
||||
continue;
|
||||
}
|
||||
|
||||
mHighUsageAppList.add(new AppInfo.Builder()
|
||||
.setUid(batterySipper.getUid())
|
||||
.setUid(consumer.getUid())
|
||||
.setPackageName(
|
||||
mBatteryUtils.getPackageName(batterySipper.getUid()))
|
||||
mBatteryUtils.getPackageName(consumer.getUid()))
|
||||
.build());
|
||||
if (mHighUsageAppList.size() >= mPolicy.highUsageAppCount) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// When in test mode, add an app if necessary
|
||||
|
||||
@@ -30,15 +30,12 @@ import android.content.om.OverlayInfo;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsTutorialDialogWrapperActivity;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
@@ -188,12 +185,7 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment i
|
||||
protected boolean setDefaultKey(String key) {
|
||||
setCurrentSystemNavigationMode(mOverlayManager, key);
|
||||
setIllustrationVideo(mVideoPreference, key);
|
||||
if (TextUtils.equals(KEY_SYSTEM_NAV_GESTURAL, key) && (
|
||||
isAnyServiceSupportAccessibilityButton() || isNavBarMagnificationEnabled())) {
|
||||
Intent intent = new Intent(getActivity(), SettingsTutorialDialogWrapperActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -267,18 +259,6 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment i
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAnyServiceSupportAccessibilityButton() {
|
||||
final AccessibilityManager ams = getContext().getSystemService(AccessibilityManager.class);
|
||||
final List<String> targets = ams.getAccessibilityShortcutTargets(
|
||||
AccessibilityManager.ACCESSIBILITY_BUTTON);
|
||||
return !targets.isEmpty();
|
||||
}
|
||||
|
||||
private boolean isNavBarMagnificationEnabled() {
|
||||
return Settings.Secure.getInt(getContext().getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 0) == 1;
|
||||
}
|
||||
|
||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider(R.xml.system_navigation_gesture_settings) {
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.util.ArrayMap;
|
||||
import android.view.View;
|
||||
|
||||
@@ -40,11 +41,10 @@ import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.ListBuilder.RowBuilder;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SubSettings;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.fuelgauge.BatteryStatsHelperLoader;
|
||||
import com.android.settings.fuelgauge.BatteryUsageStatsLoader;
|
||||
import com.android.settings.fuelgauge.PowerUsageSummary;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipLoader;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
|
||||
@@ -206,9 +206,10 @@ public class BatteryFixSlice implements CustomSliceable {
|
||||
@WorkerThread
|
||||
@VisibleForTesting
|
||||
static List<BatteryTip> refreshBatteryTips(Context context) {
|
||||
final BatteryStatsHelperLoader statsLoader = new BatteryStatsHelperLoader(context);
|
||||
final BatteryStatsHelper statsHelper = statsLoader.loadInBackground();
|
||||
final BatteryTipLoader loader = new BatteryTipLoader(context, statsHelper);
|
||||
final BatteryUsageStatsLoader statsLoader = new BatteryUsageStatsLoader(context,
|
||||
/* includeBatteryHistory */ false);
|
||||
final BatteryUsageStats batteryUsageStats = statsLoader.loadInBackground();
|
||||
final BatteryTipLoader loader = new BatteryTipLoader(context, batteryUsageStats);
|
||||
final List<BatteryTip> batteryTips = loader.loadInBackground();
|
||||
for (BatteryTip batteryTip : batteryTips) {
|
||||
if (batteryTip.getState() != BatteryTip.StateType.INVISIBLE) {
|
||||
|
||||
@@ -147,31 +147,6 @@ public class ProviderModelSlice extends WifiSlice {
|
||||
listBuilder.addRow(getWifiSliceItemRow(item));
|
||||
}
|
||||
}
|
||||
|
||||
// Fifth section: If device has connection problem, this row show the message for user.
|
||||
// 1) show non_carrier_network_unavailable:
|
||||
// - while no wifi item
|
||||
// 2) show all_network_unavailable:
|
||||
// - while no wifi item + no carrier
|
||||
// - while no wifi item + no data capability
|
||||
if (worker == null || wifiList == null || wifiList.size() == 0) {
|
||||
log("no wifi item");
|
||||
int resId = R.string.non_carrier_network_unavailable;
|
||||
if (!hasCarrier || !mHelper.isDataSimActive()) {
|
||||
log("No carrier item or no carrier data.");
|
||||
resId = R.string.all_network_unavailable;
|
||||
}
|
||||
|
||||
if (!hasCarrier && !hasEthernet) {
|
||||
// If there is no item in ProviderModelItem, slice needs a header.
|
||||
listBuilder.setHeader(mHelper.createHeader(
|
||||
NetworkProviderSettings.ACTION_NETWORK_PROVIDER_SETTINGS));
|
||||
}
|
||||
listBuilder.addGridRow(
|
||||
mHelper.createMessageGridRow(resId,
|
||||
NetworkProviderSettings.ACTION_NETWORK_PROVIDER_SETTINGS));
|
||||
}
|
||||
|
||||
return listBuilder.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ import android.util.Log;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.slice.builders.GridRowBuilder;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
|
||||
@@ -79,12 +78,6 @@ public class ProviderModelSliceHelper {
|
||||
Log.d(TAG, s);
|
||||
}
|
||||
|
||||
protected ListBuilder.HeaderBuilder createHeader(String intentAction) {
|
||||
return new ListBuilder.HeaderBuilder()
|
||||
.setTitle(mContext.getText(R.string.summary_placeholder))
|
||||
.setPrimaryAction(getPrimarySliceAction(intentAction));
|
||||
}
|
||||
|
||||
protected ListBuilder createListBuilder(Uri uri) {
|
||||
final ListBuilder builder = new ListBuilder(mContext, uri, ListBuilder.INFINITY)
|
||||
.setAccentColor(-1)
|
||||
@@ -92,14 +85,6 @@ public class ProviderModelSliceHelper {
|
||||
return builder;
|
||||
}
|
||||
|
||||
protected GridRowBuilder createMessageGridRow(int messageResId, String intentAction) {
|
||||
final CharSequence title = mContext.getText(messageResId);
|
||||
return new GridRowBuilder()
|
||||
// Add cells to the grid row.
|
||||
.addCell(new GridRowBuilder.CellBuilder().addTitleText(title))
|
||||
.setPrimaryAction(getPrimarySliceAction(intentAction));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected WifiSliceItem getConnectedWifiItem(List<WifiSliceItem> wifiList) {
|
||||
if (wifiList == null) {
|
||||
@@ -111,7 +96,10 @@ public class ProviderModelSliceHelper {
|
||||
return item.isPresent() ? item.get() : null;
|
||||
}
|
||||
|
||||
protected boolean hasCarrier() {
|
||||
/**
|
||||
* @return whether there is the carrier item in the slice.
|
||||
*/
|
||||
public boolean hasCarrier() {
|
||||
if (isAirplaneModeEnabled()
|
||||
|| mSubscriptionManager == null || mTelephonyManager == null
|
||||
|| mSubscriptionManager.getDefaultDataSubscriptionId()
|
||||
@@ -175,7 +163,12 @@ public class ProviderModelSliceHelper {
|
||||
return mTelephonyManager.isDataEnabled();
|
||||
}
|
||||
|
||||
protected boolean isDataSimActive() {
|
||||
/**
|
||||
* To check the carrier data status.
|
||||
*
|
||||
* @return whether the carrier data is active.
|
||||
*/
|
||||
public boolean isDataSimActive() {
|
||||
return isNoCarrierData() ? false : MobileNetworkUtils.activeNetworkIsCellular(mContext);
|
||||
}
|
||||
|
||||
@@ -193,11 +186,6 @@ public class ProviderModelSliceHelper {
|
||||
return mobileDataOnAndNoData || mobileDataOffAndOutOfService;
|
||||
}
|
||||
|
||||
private boolean isAirplaneSafeNetworksModeEnabled() {
|
||||
// TODO: isAirplaneSafeNetworksModeEnabled is not READY
|
||||
return false;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Drawable getMobileDrawable(Drawable drawable) throws Throwable {
|
||||
// set color and drawable
|
||||
|
||||
@@ -25,6 +25,7 @@ import androidx.fragment.app.FragmentManager;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.notification.SettingsEnableZenModeDialog;
|
||||
@@ -90,9 +91,11 @@ public class ZenModeButtonPreferenceController extends AbstractZenModePreference
|
||||
case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
|
||||
case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
|
||||
mPreference.updateStatus(true);
|
||||
mPreference.setTitle(R.string.do_not_disturb_main_switch_title_on);
|
||||
break;
|
||||
case Settings.Global.ZEN_MODE_OFF:
|
||||
default:
|
||||
mPreference.setTitle(R.string.do_not_disturb_main_switch_title_off);
|
||||
mPreference.updateStatus(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,23 @@ import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
|
||||
import static com.android.settings.network.NetworkProviderSettings.ACTION_NETWORK_PROVIDER_SETTINGS;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.ScanResult;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerExecutor;
|
||||
import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyCallback;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
@@ -35,6 +48,9 @@ import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.network.AirplaneModePreferenceController;
|
||||
import com.android.settings.network.InternetUpdater;
|
||||
import com.android.settings.network.ProviderModelSliceHelper;
|
||||
import com.android.settings.network.SubscriptionsChangeListener;
|
||||
import com.android.settings.network.telephony.DataConnectivityListener;
|
||||
import com.android.settings.slices.CustomSliceRegistry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -44,23 +60,69 @@ import java.util.List;
|
||||
* Represents the Internet Connectivity Panel.
|
||||
*/
|
||||
public class InternetConnectivityPanel implements PanelContent, LifecycleObserver,
|
||||
InternetUpdater.InternetChangeListener {
|
||||
InternetUpdater.InternetChangeListener, DataConnectivityListener.Client,
|
||||
SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
|
||||
private static final String TAG = "InternetConnectivityPanel";
|
||||
private static final int SUBTITLE_TEXT_NONE = -1;
|
||||
private static final int SUBTITLE_TEXT_WIFI_IS_TURNED_ON = R.string.wifi_is_turned_on_subtitle;
|
||||
private static final int SUBTITLE_TEXT_NON_CARRIER_NETWORK_UNAVAILABLE =
|
||||
R.string.non_carrier_network_unavailable;
|
||||
private static final int SUBTITLE_TEXT_ALL_CARRIER_NETWORK_UNAVAILABLE =
|
||||
R.string.all_network_unavailable;
|
||||
|
||||
private final Context mContext;
|
||||
private final WifiManager mWifiManager;
|
||||
private final IntentFilter mWifiStateFilter;
|
||||
private final NetworkProviderTelephonyCallback mTelephonyCallback;
|
||||
private final BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent == null) {
|
||||
return;
|
||||
}
|
||||
if (TextUtils.equals(intent.getAction(), WifiManager.NETWORK_STATE_CHANGED_ACTION)
|
||||
|| TextUtils.equals(intent.getAction(),
|
||||
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
|
||||
updatePanelTitle();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@VisibleForTesting
|
||||
boolean mIsProviderModelEnabled;
|
||||
private PanelContentCallback mCallback;
|
||||
@VisibleForTesting
|
||||
InternetUpdater mInternetUpdater;
|
||||
@VisibleForTesting
|
||||
ProviderModelSliceHelper mProviderModelSliceHelper;
|
||||
|
||||
public static InternetConnectivityPanel create(Context context) {
|
||||
return new InternetConnectivityPanel(context);
|
||||
}
|
||||
private int mSubtitle = SUBTITLE_TEXT_NONE;
|
||||
private PanelContentCallback mCallback;
|
||||
private TelephonyManager mTelephonyManager;
|
||||
private SubscriptionsChangeListener mSubscriptionsListener;
|
||||
private DataConnectivityListener mConnectivityListener;
|
||||
private int mDefaultDataSubid = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
|
||||
private InternetConnectivityPanel(Context context) {
|
||||
mContext = context.getApplicationContext();
|
||||
mIsProviderModelEnabled = Utils.isProviderModelEnabled(mContext);
|
||||
mInternetUpdater = new InternetUpdater(context, null /* Lifecycle */, this);
|
||||
|
||||
mSubscriptionsListener = new SubscriptionsChangeListener(context, this);
|
||||
mConnectivityListener = new DataConnectivityListener(context, this);
|
||||
mTelephonyCallback = new NetworkProviderTelephonyCallback();
|
||||
mDefaultDataSubid = getDefaultDataSubscriptionId();
|
||||
mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
|
||||
|
||||
mWifiManager = mContext.getSystemService(WifiManager.class);
|
||||
mWifiStateFilter = new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION);
|
||||
mWifiStateFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
|
||||
|
||||
mProviderModelSliceHelper = new ProviderModelSliceHelper(mContext, null);
|
||||
}
|
||||
|
||||
/** create the panel */
|
||||
public static InternetConnectivityPanel create(Context context) {
|
||||
return new InternetConnectivityPanel(context);
|
||||
}
|
||||
|
||||
/** @OnLifecycleEvent(ON_RESUME) */
|
||||
@@ -70,6 +132,12 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
return;
|
||||
}
|
||||
mInternetUpdater.onResume();
|
||||
mSubscriptionsListener.start();
|
||||
mConnectivityListener.start();
|
||||
mTelephonyManager.registerTelephonyCallback(
|
||||
new HandlerExecutor(new Handler(Looper.getMainLooper())), mTelephonyCallback);
|
||||
mContext.registerReceiver(mWifiStateReceiver, mWifiStateFilter);
|
||||
updatePanelTitle();
|
||||
}
|
||||
|
||||
/** @OnLifecycleEvent(ON_PAUSE) */
|
||||
@@ -79,6 +147,10 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
return;
|
||||
}
|
||||
mInternetUpdater.onPause();
|
||||
mSubscriptionsListener.stop();
|
||||
mConnectivityListener.stop();
|
||||
mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback);
|
||||
mContext.unregisterReceiver(mWifiStateReceiver);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,9 +170,8 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
*/
|
||||
@Override
|
||||
public CharSequence getSubTitle() {
|
||||
if (mIsProviderModelEnabled && mInternetUpdater.isAirplaneModeOn()
|
||||
&& mInternetUpdater.isWifiEnabled()) {
|
||||
return mContext.getText(R.string.wifi_is_turned_on_subtitle);
|
||||
if (mIsProviderModelEnabled && mSubtitle != SUBTITLE_TEXT_NONE) {
|
||||
return mContext.getText(mSubtitle);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -170,15 +241,36 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
updatePanelTitle();
|
||||
}
|
||||
|
||||
private void updatePanelTitle() {
|
||||
@Override
|
||||
public void onSubscriptionsChanged() {
|
||||
final int defaultDataSubId = getDefaultDataSubscriptionId();
|
||||
log("onSubscriptionsChanged: defaultDataSubId:" + defaultDataSubId);
|
||||
if (mDefaultDataSubid == defaultDataSubId) {
|
||||
return;
|
||||
}
|
||||
if (SubscriptionManager.isUsableSubscriptionId(defaultDataSubId)) {
|
||||
mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback);
|
||||
mTelephonyManager.registerTelephonyCallback(
|
||||
new HandlerExecutor(new Handler(Looper.getMainLooper())), mTelephonyCallback);
|
||||
}
|
||||
updatePanelTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataConnectivityChange() {
|
||||
log("onDataConnectivityChange");
|
||||
updatePanelTitle();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void updatePanelTitle() {
|
||||
if (mCallback == null) {
|
||||
return;
|
||||
}
|
||||
updateSubtitleText();
|
||||
|
||||
if (mInternetUpdater.isAirplaneModeOn() && mInternetUpdater.isWifiEnabled()) {
|
||||
// When the airplane mode is on and Wi-Fi is enabled.
|
||||
// Title: Airplane mode
|
||||
// Sub-Title: Wi-Fi is turned on
|
||||
log("Subtitle:" + mSubtitle);
|
||||
if (mSubtitle != SUBTITLE_TEXT_NONE) {
|
||||
mCallback.onHeaderChanged();
|
||||
} else {
|
||||
// Other situations.
|
||||
@@ -187,4 +279,63 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve
|
||||
}
|
||||
mCallback.onCustomizedButtonStateChanged();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
int getDefaultDataSubscriptionId() {
|
||||
return SubscriptionManager.getDefaultDataSubscriptionId();
|
||||
}
|
||||
|
||||
private void updateSubtitleText() {
|
||||
mSubtitle = SUBTITLE_TEXT_NONE;
|
||||
if (!mInternetUpdater.isWifiEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mInternetUpdater.isAirplaneModeOn()) {
|
||||
// When the airplane mode is on and Wi-Fi is enabled.
|
||||
// Title: Airplane mode
|
||||
// Sub-Title: Wi-Fi is turned on
|
||||
log("Airplane mode is on + Wi-Fi on.");
|
||||
mSubtitle = SUBTITLE_TEXT_WIFI_IS_TURNED_ON;
|
||||
return;
|
||||
}
|
||||
|
||||
final List<ScanResult> wifiList = mWifiManager.getScanResults();
|
||||
if (wifiList != null && wifiList.size() == 0) {
|
||||
// Sub-Title:
|
||||
// show non_carrier_network_unavailable
|
||||
// - while Wi-Fi on + no Wi-Fi item
|
||||
// show all_network_unavailable:
|
||||
// - while Wi-Fi on + no Wi-Fi item + no carrier
|
||||
// - while Wi-Fi on + no Wi-Fi item + no data capability
|
||||
log("No Wi-Fi item.");
|
||||
mSubtitle = SUBTITLE_TEXT_NON_CARRIER_NETWORK_UNAVAILABLE;
|
||||
if (!mProviderModelSliceHelper.hasCarrier()
|
||||
|| !mProviderModelSliceHelper.isDataSimActive()) {
|
||||
log("No carrier item or no carrier data.");
|
||||
mSubtitle = SUBTITLE_TEXT_ALL_CARRIER_NETWORK_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class NetworkProviderTelephonyCallback extends TelephonyCallback implements
|
||||
TelephonyCallback.DataConnectionStateListener,
|
||||
TelephonyCallback.ServiceStateListener {
|
||||
@Override
|
||||
public void onServiceStateChanged(ServiceState state) {
|
||||
log("onServiceStateChanged voiceState=" + state.getState()
|
||||
+ " dataState=" + state.getDataRegistrationState());
|
||||
updatePanelTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataConnectionStateChanged(int state, int networkType) {
|
||||
log("onDataConnectionStateChanged: networkType=" + networkType + " state=" + state);
|
||||
updatePanelTitle();
|
||||
}
|
||||
}
|
||||
|
||||
private static void log(String s) {
|
||||
Log.d(TAG, s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -592,7 +592,7 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
|
||||
// 0 is a last resort default, but the interface validates that the proxy port is
|
||||
// present and non-zero.
|
||||
int port = proxyPort.isEmpty() ? 0 : Integer.parseInt(proxyPort);
|
||||
profile.proxy = new ProxyInfo(proxyHost, port, null);
|
||||
profile.proxy = ProxyInfo.buildDirectProxy(proxyHost, port);
|
||||
} else {
|
||||
profile.proxy = null;
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
/** A continuous labeled slider preference */
|
||||
public class LabeledContinuousSeekBarPreference extends LabeledSeekBarPreference {
|
||||
public LabeledContinuousSeekBarPreference(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public LabeledContinuousSeekBarPreference(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public LabeledContinuousSeekBarPreference(Context context, AttributeSet attrs,
|
||||
int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public LabeledContinuousSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr,
|
||||
int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
setLayoutResource(R.layout.preference_labeled_continuous_slider);
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,7 @@ import com.android.settingslib.wifi.AccessPoint;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
@@ -319,9 +320,9 @@ public class WifiConfigController implements TextWatcher,
|
||||
// Display IP address.
|
||||
StaticIpConfiguration staticConfig = config.getIpConfiguration()
|
||||
.getStaticIpConfiguration();
|
||||
if (staticConfig != null && staticConfig.ipAddress != null) {
|
||||
if (staticConfig != null && staticConfig.getIpAddress() != null) {
|
||||
addRow(group, R.string.wifi_ip_address,
|
||||
staticConfig.ipAddress.getAddress().getHostAddress());
|
||||
staticConfig.getIpAddress().getAddress().getHostAddress());
|
||||
}
|
||||
} else {
|
||||
mIpSettingsSpinner.setSelection(DHCP);
|
||||
@@ -860,7 +861,8 @@ public class WifiConfigController implements TextWatcher,
|
||||
result = R.string.proxy_error_invalid_port;
|
||||
}
|
||||
if (result == 0) {
|
||||
mHttpProxy = new ProxyInfo(host, port, exclusionList);
|
||||
mHttpProxy = ProxyInfo.buildDirectProxy(
|
||||
host, port, Arrays.asList(exclusionList.split(",")));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -874,7 +876,7 @@ public class WifiConfigController implements TextWatcher,
|
||||
if (uri == null) {
|
||||
return false;
|
||||
}
|
||||
mHttpProxy = new ProxyInfo(uri);
|
||||
mHttpProxy = ProxyInfo.buildPacProxy(uri);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -897,67 +899,81 @@ public class WifiConfigController implements TextWatcher,
|
||||
if (inetAddr == null || inetAddr.equals(Inet4Address.ANY)) {
|
||||
return R.string.wifi_ip_settings_invalid_ip_address;
|
||||
}
|
||||
|
||||
int networkPrefixLength = -1;
|
||||
// Copy all fields into the builder first and set desired value later with builder.
|
||||
final StaticIpConfiguration.Builder staticIPBuilder = new StaticIpConfiguration.Builder()
|
||||
.setDnsServers(staticIpConfiguration.getDnsServers())
|
||||
.setDomains(staticIpConfiguration.getDomains())
|
||||
.setGateway(staticIpConfiguration.getGateway())
|
||||
.setIpAddress(staticIpConfiguration.getIpAddress());
|
||||
try {
|
||||
networkPrefixLength = Integer.parseInt(mNetworkPrefixLengthView.getText().toString());
|
||||
if (networkPrefixLength < 0 || networkPrefixLength > 32) {
|
||||
return R.string.wifi_ip_settings_invalid_network_prefix_length;
|
||||
}
|
||||
staticIpConfiguration.ipAddress = new LinkAddress(inetAddr, networkPrefixLength);
|
||||
} catch (NumberFormatException e) {
|
||||
// Set the hint as default after user types in ip address
|
||||
mNetworkPrefixLengthView.setText(mConfigUi.getContext().getString(
|
||||
R.string.wifi_network_prefix_length_hint));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return R.string.wifi_ip_settings_invalid_ip_address;
|
||||
}
|
||||
|
||||
String gateway = mGatewayView.getText().toString();
|
||||
if (TextUtils.isEmpty(gateway)) {
|
||||
int networkPrefixLength = -1;
|
||||
try {
|
||||
//Extract a default gateway from IP address
|
||||
InetAddress netPart = NetUtils.getNetworkPart(inetAddr, networkPrefixLength);
|
||||
byte[] addr = netPart.getAddress();
|
||||
addr[addr.length - 1] = 1;
|
||||
mGatewayView.setText(InetAddress.getByAddress(addr).getHostAddress());
|
||||
} catch (RuntimeException ee) {
|
||||
} catch (java.net.UnknownHostException u) {
|
||||
networkPrefixLength = Integer.parseInt(
|
||||
mNetworkPrefixLengthView.getText().toString());
|
||||
if (networkPrefixLength < 0 || networkPrefixLength > 32) {
|
||||
return R.string.wifi_ip_settings_invalid_network_prefix_length;
|
||||
}
|
||||
staticIPBuilder.setIpAddress(new LinkAddress(inetAddr, networkPrefixLength));
|
||||
} catch (NumberFormatException e) {
|
||||
// Set the hint as default after user types in ip address
|
||||
mNetworkPrefixLengthView.setText(mConfigUi.getContext().getString(
|
||||
R.string.wifi_network_prefix_length_hint));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return R.string.wifi_ip_settings_invalid_ip_address;
|
||||
}
|
||||
} else {
|
||||
InetAddress gatewayAddr = getIPv4Address(gateway);
|
||||
if (gatewayAddr == null) {
|
||||
return R.string.wifi_ip_settings_invalid_gateway;
|
||||
}
|
||||
if (gatewayAddr.isMulticastAddress()) {
|
||||
return R.string.wifi_ip_settings_invalid_gateway;
|
||||
}
|
||||
staticIpConfiguration.gateway = gatewayAddr;
|
||||
}
|
||||
|
||||
String dns = mDns1View.getText().toString();
|
||||
InetAddress dnsAddr = null;
|
||||
|
||||
if (TextUtils.isEmpty(dns)) {
|
||||
//If everything else is valid, provide hint as a default option
|
||||
mDns1View.setText(mConfigUi.getContext().getString(R.string.wifi_dns1_hint));
|
||||
} else {
|
||||
dnsAddr = getIPv4Address(dns);
|
||||
if (dnsAddr == null) {
|
||||
return R.string.wifi_ip_settings_invalid_dns;
|
||||
String gateway = mGatewayView.getText().toString();
|
||||
if (TextUtils.isEmpty(gateway)) {
|
||||
try {
|
||||
//Extract a default gateway from IP address
|
||||
InetAddress netPart = NetUtils.getNetworkPart(inetAddr, networkPrefixLength);
|
||||
byte[] addr = netPart.getAddress();
|
||||
addr[addr.length - 1] = 1;
|
||||
mGatewayView.setText(InetAddress.getByAddress(addr).getHostAddress());
|
||||
} catch (RuntimeException ee) {
|
||||
} catch (java.net.UnknownHostException u) {
|
||||
}
|
||||
} else {
|
||||
InetAddress gatewayAddr = getIPv4Address(gateway);
|
||||
if (gatewayAddr == null) {
|
||||
return R.string.wifi_ip_settings_invalid_gateway;
|
||||
}
|
||||
if (gatewayAddr.isMulticastAddress()) {
|
||||
return R.string.wifi_ip_settings_invalid_gateway;
|
||||
}
|
||||
staticIPBuilder.setGateway(gatewayAddr);
|
||||
}
|
||||
staticIpConfiguration.dnsServers.add(dnsAddr);
|
||||
}
|
||||
|
||||
if (mDns2View.length() > 0) {
|
||||
dns = mDns2View.getText().toString();
|
||||
dnsAddr = getIPv4Address(dns);
|
||||
if (dnsAddr == null) {
|
||||
return R.string.wifi_ip_settings_invalid_dns;
|
||||
String dns = mDns1View.getText().toString();
|
||||
InetAddress dnsAddr = null;
|
||||
final ArrayList<InetAddress> dnsServers = new ArrayList<>();
|
||||
|
||||
if (TextUtils.isEmpty(dns)) {
|
||||
//If everything else is valid, provide hint as a default option
|
||||
mDns1View.setText(mConfigUi.getContext().getString(R.string.wifi_dns1_hint));
|
||||
} else {
|
||||
dnsAddr = getIPv4Address(dns);
|
||||
if (dnsAddr == null) {
|
||||
return R.string.wifi_ip_settings_invalid_dns;
|
||||
}
|
||||
dnsServers.add(dnsAddr);
|
||||
}
|
||||
staticIpConfiguration.dnsServers.add(dnsAddr);
|
||||
|
||||
if (mDns2View.length() > 0) {
|
||||
dns = mDns2View.getText().toString();
|
||||
dnsAddr = getIPv4Address(dns);
|
||||
if (dnsAddr == null) {
|
||||
return R.string.wifi_ip_settings_invalid_dns;
|
||||
}
|
||||
dnsServers.add(dnsAddr);
|
||||
}
|
||||
staticIPBuilder.setDnsServers(dnsServers);
|
||||
return 0;
|
||||
} finally {
|
||||
// Caller of this method may rely on staticIpConfiguration, so build the final result
|
||||
// at the end of the method.
|
||||
staticIpConfiguration = staticIPBuilder.build();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void showSecurityFields(boolean refreshEapMethods, boolean refreshCertificates) {
|
||||
|
||||
@@ -79,6 +79,7 @@ import com.android.wifitrackerlib.WifiEntry.ConnectedInfo;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
@@ -305,9 +306,9 @@ public class WifiConfigController2 implements TextWatcher,
|
||||
// Display IP address.
|
||||
StaticIpConfiguration staticConfig = config.getIpConfiguration()
|
||||
.getStaticIpConfiguration();
|
||||
if (staticConfig != null && staticConfig.ipAddress != null) {
|
||||
if (staticConfig != null && staticConfig.getIpAddress() != null) {
|
||||
addRow(group, R.string.wifi_ip_address,
|
||||
staticConfig.ipAddress.getAddress().getHostAddress());
|
||||
staticConfig.getIpAddress().getAddress().getHostAddress());
|
||||
}
|
||||
} else {
|
||||
mIpSettingsSpinner.setSelection(DHCP);
|
||||
@@ -822,7 +823,8 @@ public class WifiConfigController2 implements TextWatcher,
|
||||
result = R.string.proxy_error_invalid_port;
|
||||
}
|
||||
if (result == 0) {
|
||||
mHttpProxy = new ProxyInfo(host, port, exclusionList);
|
||||
mHttpProxy = ProxyInfo.buildDirectProxy(
|
||||
host, port, Arrays.asList(exclusionList.split(",")));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -836,7 +838,7 @@ public class WifiConfigController2 implements TextWatcher,
|
||||
if (uri == null) {
|
||||
return false;
|
||||
}
|
||||
mHttpProxy = new ProxyInfo(uri);
|
||||
mHttpProxy = ProxyInfo.buildPacProxy(uri);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -860,66 +862,83 @@ public class WifiConfigController2 implements TextWatcher,
|
||||
return R.string.wifi_ip_settings_invalid_ip_address;
|
||||
}
|
||||
|
||||
int networkPrefixLength = -1;
|
||||
// Copy all fields into the builder first and set desired value later with builder.
|
||||
final StaticIpConfiguration.Builder staticIPBuilder = new StaticIpConfiguration.Builder()
|
||||
.setDnsServers(staticIpConfiguration.getDnsServers())
|
||||
.setDomains(staticIpConfiguration.getDomains())
|
||||
.setGateway(staticIpConfiguration.getGateway())
|
||||
.setIpAddress(staticIpConfiguration.getIpAddress());
|
||||
try {
|
||||
networkPrefixLength = Integer.parseInt(mNetworkPrefixLengthView.getText().toString());
|
||||
if (networkPrefixLength < 0 || networkPrefixLength > 32) {
|
||||
return R.string.wifi_ip_settings_invalid_network_prefix_length;
|
||||
}
|
||||
staticIpConfiguration.ipAddress = new LinkAddress(inetAddr, networkPrefixLength);
|
||||
} catch (NumberFormatException e) {
|
||||
// Set the hint as default after user types in ip address
|
||||
mNetworkPrefixLengthView.setText(mConfigUi.getContext().getString(
|
||||
R.string.wifi_network_prefix_length_hint));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return R.string.wifi_ip_settings_invalid_ip_address;
|
||||
}
|
||||
|
||||
String gateway = mGatewayView.getText().toString();
|
||||
if (TextUtils.isEmpty(gateway)) {
|
||||
int networkPrefixLength = -1;
|
||||
try {
|
||||
//Extract a default gateway from IP address
|
||||
InetAddress netPart = NetUtils.getNetworkPart(inetAddr, networkPrefixLength);
|
||||
byte[] addr = netPart.getAddress();
|
||||
addr[addr.length - 1] = 1;
|
||||
mGatewayView.setText(InetAddress.getByAddress(addr).getHostAddress());
|
||||
} catch (RuntimeException ee) {
|
||||
} catch (java.net.UnknownHostException u) {
|
||||
networkPrefixLength =
|
||||
Integer.parseInt(mNetworkPrefixLengthView.getText().toString());
|
||||
if (networkPrefixLength < 0 || networkPrefixLength > 32) {
|
||||
return R.string.wifi_ip_settings_invalid_network_prefix_length;
|
||||
}
|
||||
staticIPBuilder.setIpAddress(new LinkAddress(inetAddr, networkPrefixLength));
|
||||
} catch (NumberFormatException e) {
|
||||
// Set the hint as default after user types in ip address
|
||||
mNetworkPrefixLengthView.setText(mConfigUi.getContext().getString(
|
||||
R.string.wifi_network_prefix_length_hint));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return R.string.wifi_ip_settings_invalid_ip_address;
|
||||
}
|
||||
} else {
|
||||
InetAddress gatewayAddr = getIPv4Address(gateway);
|
||||
if (gatewayAddr == null) {
|
||||
return R.string.wifi_ip_settings_invalid_gateway;
|
||||
}
|
||||
if (gatewayAddr.isMulticastAddress()) {
|
||||
return R.string.wifi_ip_settings_invalid_gateway;
|
||||
}
|
||||
staticIpConfiguration.gateway = gatewayAddr;
|
||||
}
|
||||
|
||||
String dns = mDns1View.getText().toString();
|
||||
InetAddress dnsAddr = null;
|
||||
|
||||
if (TextUtils.isEmpty(dns)) {
|
||||
//If everything else is valid, provide hint as a default option
|
||||
mDns1View.setText(mConfigUi.getContext().getString(R.string.wifi_dns1_hint));
|
||||
} else {
|
||||
dnsAddr = getIPv4Address(dns);
|
||||
if (dnsAddr == null) {
|
||||
return R.string.wifi_ip_settings_invalid_dns;
|
||||
String gateway = mGatewayView.getText().toString();
|
||||
if (TextUtils.isEmpty(gateway)) {
|
||||
try {
|
||||
//Extract a default gateway from IP address
|
||||
InetAddress netPart = NetUtils.getNetworkPart(inetAddr, networkPrefixLength);
|
||||
byte[] addr = netPart.getAddress();
|
||||
addr[addr.length - 1] = 1;
|
||||
mGatewayView.setText(InetAddress.getByAddress(addr).getHostAddress());
|
||||
} catch (RuntimeException ee) {
|
||||
} catch (java.net.UnknownHostException u) {
|
||||
}
|
||||
} else {
|
||||
InetAddress gatewayAddr = getIPv4Address(gateway);
|
||||
if (gatewayAddr == null) {
|
||||
return R.string.wifi_ip_settings_invalid_gateway;
|
||||
}
|
||||
if (gatewayAddr.isMulticastAddress()) {
|
||||
return R.string.wifi_ip_settings_invalid_gateway;
|
||||
}
|
||||
staticIPBuilder.setGateway(gatewayAddr);
|
||||
}
|
||||
staticIpConfiguration.dnsServers.add(dnsAddr);
|
||||
}
|
||||
|
||||
if (mDns2View.length() > 0) {
|
||||
dns = mDns2View.getText().toString();
|
||||
dnsAddr = getIPv4Address(dns);
|
||||
if (dnsAddr == null) {
|
||||
return R.string.wifi_ip_settings_invalid_dns;
|
||||
String dns = mDns1View.getText().toString();
|
||||
InetAddress dnsAddr = null;
|
||||
final ArrayList<InetAddress> dnsServers = new ArrayList<>();
|
||||
|
||||
if (TextUtils.isEmpty(dns)) {
|
||||
//If everything else is valid, provide hint as a default option
|
||||
mDns1View.setText(mConfigUi.getContext().getString(R.string.wifi_dns1_hint));
|
||||
} else {
|
||||
dnsAddr = getIPv4Address(dns);
|
||||
if (dnsAddr == null) {
|
||||
return R.string.wifi_ip_settings_invalid_dns;
|
||||
}
|
||||
dnsServers.add(dnsAddr);
|
||||
staticIpConfiguration.dnsServers.add(dnsAddr);
|
||||
}
|
||||
staticIpConfiguration.dnsServers.add(dnsAddr);
|
||||
|
||||
if (mDns2View.length() > 0) {
|
||||
dns = mDns2View.getText().toString();
|
||||
dnsAddr = getIPv4Address(dns);
|
||||
if (dnsAddr == null) {
|
||||
return R.string.wifi_ip_settings_invalid_dns;
|
||||
}
|
||||
dnsServers.add(dnsAddr);
|
||||
staticIpConfiguration.dnsServers.add(dnsAddr);
|
||||
}
|
||||
staticIPBuilder.setDnsServers(dnsServers);
|
||||
return 0;
|
||||
} finally {
|
||||
// Caller of this method may rely on staticIpConfiguration, so build the final result
|
||||
// at the end of the method.
|
||||
staticIpConfiguration = staticIPBuilder.build();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void showSecurityFields(boolean refreshEapMethods, boolean refreshCertificates) {
|
||||
@@ -1330,18 +1349,18 @@ public class WifiConfigController2 implements TextWatcher,
|
||||
StaticIpConfiguration staticConfig = config.getIpConfiguration()
|
||||
.getStaticIpConfiguration();
|
||||
if (staticConfig != null) {
|
||||
if (staticConfig.ipAddress != null) {
|
||||
if (staticConfig.getIpAddress() != null) {
|
||||
mIpAddressView.setText(
|
||||
staticConfig.ipAddress.getAddress().getHostAddress());
|
||||
mNetworkPrefixLengthView.setText(Integer.toString(staticConfig.ipAddress
|
||||
.getPrefixLength()));
|
||||
staticConfig.getIpAddress().getAddress().getHostAddress());
|
||||
mNetworkPrefixLengthView.setText(Integer.toString(
|
||||
staticConfig.getIpAddress().getPrefixLength()));
|
||||
}
|
||||
|
||||
if (staticConfig.gateway != null) {
|
||||
mGatewayView.setText(staticConfig.gateway.getHostAddress());
|
||||
mGatewayView.setText(staticConfig.getGateway().getHostAddress());
|
||||
}
|
||||
|
||||
Iterator<InetAddress> dnsIterator = staticConfig.dnsServers.iterator();
|
||||
Iterator<InetAddress> dnsIterator = staticConfig.getDnsServers().iterator();
|
||||
if (dnsIterator.hasNext()) {
|
||||
mDns1View.setText(dnsIterator.next().getHostAddress());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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.wifi.tether;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.wifi.SoftApConfiguration;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
/**
|
||||
* This controller helps to manage the state of maximize compatibility switch preference.
|
||||
*/
|
||||
public class WifiTetherMaximizeCompatibilityPreferenceController extends
|
||||
WifiTetherBasePreferenceController {
|
||||
|
||||
private static final String TAG = "WifiTetherMaximizeCompatibilityPref";
|
||||
public static final String PREF_KEY = "wifi_tether_maximize_compatibility";
|
||||
|
||||
private boolean mIsChecked;
|
||||
|
||||
public WifiTetherMaximizeCompatibilityPreferenceController(Context context,
|
||||
WifiTetherBasePreferenceController.OnTetherConfigUpdateListener listener) {
|
||||
super(context, listener);
|
||||
mIsChecked = isMaximizeCompatibilityEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return PREF_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDisplay() {
|
||||
if (mPreference == null) {
|
||||
return;
|
||||
}
|
||||
mPreference.setEnabled(is5GhzBandSupported());
|
||||
((SwitchPreference) mPreference).setChecked(mIsChecked);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
mIsChecked = (Boolean) newValue;
|
||||
if (mListener != null) {
|
||||
mListener.onTetherConfigUpdated(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean is5GhzBandSupported() {
|
||||
if (mWifiManager == null) {
|
||||
return false;
|
||||
}
|
||||
if (!mWifiManager.is5GHzBandSupported() || mWifiManager.getCountryCode() == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean isMaximizeCompatibilityEnabled() {
|
||||
if (mWifiManager == null) {
|
||||
return false;
|
||||
}
|
||||
final SoftApConfiguration config = mWifiManager.getSoftApConfiguration();
|
||||
if (config == null) {
|
||||
return false;
|
||||
}
|
||||
if (mWifiManager.isBridgedApConcurrencySupported()) {
|
||||
final boolean isEnabled = config.isBridgedModeOpportunisticShutdownEnabled();
|
||||
Log.d(TAG, "isBridgedModeOpportunisticShutdownEnabled:" + isEnabled);
|
||||
return isEnabled;
|
||||
}
|
||||
|
||||
// If the BridgedAp Concurrency is not supported in early Pixel devices (e.g. Pixel 2~5),
|
||||
// show toggle on if the band includes SoftApConfiguration.BAND_5GHZ.
|
||||
final int band = config.getBand();
|
||||
Log.d(TAG, "getBand:" + band);
|
||||
return (band & SoftApConfiguration.BAND_5GHZ) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the Maximize Compatibility setting to the SoftAp Configuration
|
||||
*
|
||||
* @param builder The builder to build the SoftApConfiguration.
|
||||
*/
|
||||
public void setupMaximizeCompatibility(SoftApConfiguration.Builder builder) {
|
||||
if (builder == null) {
|
||||
return;
|
||||
}
|
||||
final boolean enabled = mIsChecked;
|
||||
if (mWifiManager.isBridgedApConcurrencySupported()) {
|
||||
int[] bands = {
|
||||
SoftApConfiguration.BAND_2GHZ,
|
||||
SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ};
|
||||
builder.setBands(bands);
|
||||
Log.d(TAG, "setBridgedModeOpportunisticShutdownEnabled:" + enabled);
|
||||
builder.setBridgedModeOpportunisticShutdownEnabled(enabled);
|
||||
} else {
|
||||
int band = enabled
|
||||
? SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ
|
||||
: SoftApConfiguration.BAND_2GHZ;
|
||||
Log.d(TAG, "setBand:" + band);
|
||||
builder.setBand(band);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,8 +54,7 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
private static final String TAG = "WifiTetherSettings";
|
||||
private static final IntentFilter TETHER_STATE_CHANGE_FILTER;
|
||||
private static final String KEY_WIFI_TETHER_SCREEN = "wifi_tether_settings_screen";
|
||||
private static final int EXPANDED_CHILD_COUNT_WITH_SECURITY_NON = 3;
|
||||
private static final int EXPANDED_CHILD_COUNT_DEFAULT = 4;
|
||||
private static final int EXPANDED_CHILD_COUNT_DEFAULT = 3;
|
||||
|
||||
@VisibleForTesting
|
||||
static final String KEY_WIFI_TETHER_NETWORK_NAME = "wifi_tether_network_name";
|
||||
@@ -64,13 +63,14 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
@VisibleForTesting
|
||||
static final String KEY_WIFI_TETHER_AUTO_OFF = "wifi_tether_auto_turn_off";
|
||||
@VisibleForTesting
|
||||
static final String KEY_WIFI_TETHER_NETWORK_AP_BAND = "wifi_tether_network_ap_band";
|
||||
static final String KEY_WIFI_TETHER_MAXIMIZE_COMPATIBILITY =
|
||||
WifiTetherMaximizeCompatibilityPreferenceController.PREF_KEY;
|
||||
|
||||
private WifiTetherSwitchBarController mSwitchBarController;
|
||||
private WifiTetherSSIDPreferenceController mSSIDPreferenceController;
|
||||
private WifiTetherPasswordPreferenceController mPasswordPreferenceController;
|
||||
private WifiTetherApBandPreferenceController mApBandPreferenceController;
|
||||
private WifiTetherSecurityPreferenceController mSecurityPreferenceController;
|
||||
private WifiTetherMaximizeCompatibilityPreferenceController mMaxCompatibilityPrefController;
|
||||
|
||||
private WifiManager mWifiManager;
|
||||
private boolean mRestartWifiApAfterConfigChange;
|
||||
@@ -116,7 +116,8 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
mSSIDPreferenceController = use(WifiTetherSSIDPreferenceController.class);
|
||||
mSecurityPreferenceController = use(WifiTetherSecurityPreferenceController.class);
|
||||
mPasswordPreferenceController = use(WifiTetherPasswordPreferenceController.class);
|
||||
mApBandPreferenceController = use(WifiTetherApBandPreferenceController.class);
|
||||
mMaxCompatibilityPrefController =
|
||||
use(WifiTetherMaximizeCompatibilityPreferenceController.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -180,10 +181,9 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
controllers.add(new WifiTetherSSIDPreferenceController(context, listener));
|
||||
controllers.add(new WifiTetherSecurityPreferenceController(context, listener));
|
||||
controllers.add(new WifiTetherPasswordPreferenceController(context, listener));
|
||||
controllers.add(new WifiTetherApBandPreferenceController(context, listener));
|
||||
controllers.add(
|
||||
new WifiTetherAutoOffPreferenceController(context, KEY_WIFI_TETHER_AUTO_OFF));
|
||||
|
||||
controllers.add(new WifiTetherMaximizeCompatibilityPreferenceController(context, listener));
|
||||
return controllers;
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
mPasswordPreferenceController.getPasswordValidated(securityType),
|
||||
securityType);
|
||||
}
|
||||
configBuilder.setBand(mApBandPreferenceController.getBandIndex());
|
||||
mMaxCompatibilityPrefController.setupMaximizeCompatibility(configBuilder);
|
||||
return configBuilder.build();
|
||||
}
|
||||
|
||||
@@ -229,14 +229,10 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
}
|
||||
|
||||
private void updateDisplayWithNewConfig() {
|
||||
use(WifiTetherSSIDPreferenceController.class)
|
||||
.updateDisplay();
|
||||
use(WifiTetherSecurityPreferenceController.class)
|
||||
.updateDisplay();
|
||||
use(WifiTetherPasswordPreferenceController.class)
|
||||
.updateDisplay();
|
||||
use(WifiTetherApBandPreferenceController.class)
|
||||
.updateDisplay();
|
||||
use(WifiTetherSSIDPreferenceController.class).updateDisplay();
|
||||
use(WifiTetherSecurityPreferenceController.class).updateDisplay();
|
||||
use(WifiTetherPasswordPreferenceController.class).updateDisplay();
|
||||
use(WifiTetherMaximizeCompatibilityPreferenceController.class).updateDisplay();
|
||||
}
|
||||
|
||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
@@ -250,7 +246,7 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
keys.add(KEY_WIFI_TETHER_NETWORK_NAME);
|
||||
keys.add(KEY_WIFI_TETHER_NETWORK_PASSWORD);
|
||||
keys.add(KEY_WIFI_TETHER_AUTO_OFF);
|
||||
keys.add(KEY_WIFI_TETHER_NETWORK_AP_BAND);
|
||||
keys.add(KEY_WIFI_TETHER_MAXIMIZE_COMPATIBILITY);
|
||||
}
|
||||
|
||||
// Remove duplicate
|
||||
@@ -294,22 +290,17 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
|
||||
private void reConfigInitialExpandedChildCount() {
|
||||
final PreferenceGroup screen = getPreferenceScreen();
|
||||
if (mSecurityPreferenceController.getSecurityType()
|
||||
== SoftApConfiguration.SECURITY_TYPE_OPEN) {
|
||||
screen.setInitialExpandedChildrenCount(EXPANDED_CHILD_COUNT_WITH_SECURITY_NON);
|
||||
return;
|
||||
if (screen != null) {
|
||||
screen.setInitialExpandedChildrenCount(getInitialExpandedChildCount());
|
||||
}
|
||||
screen.setInitialExpandedChildrenCount(EXPANDED_CHILD_COUNT_DEFAULT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInitialExpandedChildCount() {
|
||||
if (mSecurityPreferenceController == null) {
|
||||
return EXPANDED_CHILD_COUNT_DEFAULT;
|
||||
if (mSecurityPreferenceController != null && mSecurityPreferenceController.getSecurityType()
|
||||
== SoftApConfiguration.SECURITY_TYPE_OPEN) {
|
||||
return (EXPANDED_CHILD_COUNT_DEFAULT - 1);
|
||||
}
|
||||
|
||||
return (mSecurityPreferenceController.getSecurityType()
|
||||
== SoftApConfiguration.SECURITY_TYPE_OPEN)
|
||||
? EXPANDED_CHILD_COUNT_WITH_SECURITY_NON : EXPANDED_CHILD_COUNT_DEFAULT;
|
||||
return EXPANDED_CHILD_COUNT_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.XmlTestUtils;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Tests for {@link AccessibilityButtonFragment}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityButtonFragmentTest {
|
||||
|
||||
private Context mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@Test
|
||||
public void getNonIndexableKeys_existInXmlLayout() {
|
||||
final List<String> niks = AccessibilityButtonFragment.SEARCH_INDEX_DATA_PROVIDER
|
||||
.getNonIndexableKeys(mContext);
|
||||
final List<String> keys =
|
||||
XmlTestUtils.getKeysFromPreferenceXml(mContext,
|
||||
R.xml.accessibility_button_settings);
|
||||
|
||||
assertThat(keys).containsAtLeastElementsIn(niks);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link AccessibilityButtonLocationPreferenceController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityButtonLocationPreferenceControllerTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Spy
|
||||
private final Resources mResources = mContext.getResources();
|
||||
private final ContentResolver mContentResolver = mContext.getContentResolver();
|
||||
private final ListPreference mListPreference = new ListPreference(mContext);
|
||||
private AccessibilityButtonLocationPreferenceController mController;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mController = new AccessibilityButtonLocationPreferenceController(mContext,
|
||||
"test_key");
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_navigationGestureEnabled_returnDisabledDependentSetting() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_GESTURAL);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_navigationGestureDisabled_returnAvailable() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_2BUTTON);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_a11yBtnModeNavigationBar_navigationBarValue() {
|
||||
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
|
||||
ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
|
||||
|
||||
mController.updateState(mListPreference);
|
||||
|
||||
final String navigationBarValue = String.valueOf(ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
|
||||
assertThat(mListPreference.getValue()).isEqualTo(navigationBarValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_a11yBtnModeFloatingMenu_floatingMenuValue() {
|
||||
final String floatingMenuValue = String.valueOf(ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU);
|
||||
|
||||
mController.onPreferenceChange(mListPreference, floatingMenuValue);
|
||||
|
||||
assertThat(mListPreference.getValue()).isEqualTo(floatingMenuValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.provider.Settings;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link AccessibilityButtonPreviewPreferenceController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityButtonPreviewPreferenceControllerTest {
|
||||
|
||||
@Rule
|
||||
public MockitoRule mocks = MockitoJUnit.rule();
|
||||
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Mock
|
||||
private ContentResolver mContentResolver;
|
||||
private AccessibilityButtonPreviewPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
when(mContext.getContentResolver()).thenReturn(mContentResolver);
|
||||
mController = new AccessibilityButtonPreviewPreferenceController(mContext, "test_key");
|
||||
mController.mPreview = new ImageView(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onChange_a11yBtnModeNavigationBar_getNavigationBarDrawable() {
|
||||
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
|
||||
ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
|
||||
|
||||
mController.mContentObserver.onChange(false);
|
||||
|
||||
final Drawable navigationBarDrawable = mContext.getDrawable(
|
||||
R.drawable.accessibility_button_navigation);
|
||||
assertThat(mController.mPreview.getDrawable().getConstantState()).isEqualTo(
|
||||
navigationBarDrawable.getConstantState());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onChange_updatePreviewPreferenceWithConfig_expectedPreviewDrawable() {
|
||||
Settings.Secure.putInt(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU);
|
||||
Settings.Secure.putInt(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, /* small size */ 0);
|
||||
Settings.Secure.putFloat(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, 0.1f);
|
||||
|
||||
mController.mContentObserver.onChange(false);
|
||||
|
||||
final Drawable smallFloatingMenuWithTenOpacityDrawable =
|
||||
FloatingMenuLayerDrawable.createLayerDrawable(mContext,
|
||||
R.drawable.accessibility_button_preview_small_floating_menu, 10);
|
||||
assertThat(mController.mPreview.getDrawable().getConstantState()).isEqualTo(
|
||||
smallFloatingMenuWithTenOpacityDrawable.getConstantState());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onResume_registerSpecificContentObserver() {
|
||||
mController.onResume();
|
||||
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_MODE), false,
|
||||
mController.mContentObserver);
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE), false,
|
||||
mController.mContentObserver);
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY),
|
||||
false,
|
||||
mController.mContentObserver);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPause_unregisterContentObserver() {
|
||||
mController.onPause();
|
||||
|
||||
verify(mContentResolver).unregisterContentObserver(mController.mContentObserver);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link FloatingMenuFadePreferenceController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class FloatingMenuFadePreferenceControllerTest {
|
||||
|
||||
@Rule
|
||||
public MockitoRule mocks = MockitoJUnit.rule();
|
||||
|
||||
private static final int OFF = 0;
|
||||
private static final int ON = 1;
|
||||
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Mock
|
||||
private ContentResolver mContentResolver;
|
||||
private final SwitchPreference mSwitchPreference = new SwitchPreference(mContext);
|
||||
private FloatingMenuFadePreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
when(mContext.getContentResolver()).thenReturn(mContentResolver);
|
||||
mController = new FloatingMenuFadePreferenceController(mContext, "test_key");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_a11yBtnModeFloatingMenu_returnAvailable() {
|
||||
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
|
||||
ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_a11yBtnModeNavigationBar_returnDisabledDependentSetting() {
|
||||
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
|
||||
ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_keyFloatingMenuFadeDisabled_fadeIsDisabled() {
|
||||
Settings.Secure.putInt(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED, OFF);
|
||||
|
||||
mController.updateState(mSwitchPreference);
|
||||
|
||||
assertThat(mSwitchPreference.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_floatingMenuFadeEnabled_keyFloatingMenuFadeIsOn() {
|
||||
mController.onPreferenceChange(mSwitchPreference, Boolean.TRUE);
|
||||
|
||||
final int actualValue = Settings.Secure.getInt(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED, OFF);
|
||||
assertThat(actualValue).isEqualTo(ON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onChange_floatingMenuFadeChangeToDisabled_preferenceDisabled() {
|
||||
mController.mPreference = mSwitchPreference;
|
||||
Settings.Secure.putInt(mContentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED, OFF);
|
||||
|
||||
mController.mContentObserver.onChange(false);
|
||||
|
||||
assertThat(mController.mPreference.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onResume_registerSpecificContentObserver() {
|
||||
mController.onResume();
|
||||
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_MODE), false,
|
||||
mController.mContentObserver);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPause_unregisterContentObserver() {
|
||||
mController.onPause();
|
||||
|
||||
verify(mContentResolver).unregisterContentObserver(mController.mContentObserver);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link FloatingMenuLayerDrawable}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class FloatingMenuLayerDrawableTest {
|
||||
|
||||
private static final int TEST_RES_ID =
|
||||
com.android.internal.R.drawable.ic_accessibility_magnification;
|
||||
private static final int TEST_RES_ID_2 =
|
||||
com.android.internal.R.drawable.ic_accessibility_color_inversion;
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@Test
|
||||
public void createLayerDrawable_configCorrect() {
|
||||
final Drawable expected1stDrawable = mContext.getDrawable(
|
||||
R.drawable.accessibility_button_preview_base);
|
||||
final Drawable expected2ndDrawable = mContext.getDrawable(TEST_RES_ID);
|
||||
|
||||
final FloatingMenuLayerDrawable actualDrawable =
|
||||
FloatingMenuLayerDrawable.createLayerDrawable(mContext, TEST_RES_ID,
|
||||
/* opacity= */ 27);
|
||||
|
||||
final Drawable actual1stDrawable = actualDrawable.getDrawable(0);
|
||||
final Drawable actual2ndDrawable = actualDrawable.getDrawable(1);
|
||||
// These are VectorDrawables, so it can use getConstantState() to compare.
|
||||
assertThat(actual1stDrawable.getConstantState()).isEqualTo(
|
||||
expected1stDrawable.getConstantState());
|
||||
assertThat(actual2ndDrawable.getConstantState()).isEqualTo(
|
||||
expected2ndDrawable.getConstantState());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateLayerDrawable_expectedFloatingMenuLayerDrawableState() {
|
||||
final FloatingMenuLayerDrawable originalDrawable =
|
||||
FloatingMenuLayerDrawable.createLayerDrawable(mContext, TEST_RES_ID, /* opacity= */
|
||||
72);
|
||||
|
||||
originalDrawable.updateLayerDrawable(mContext, TEST_RES_ID_2, /* opacity= */ 27);
|
||||
|
||||
assertThat(originalDrawable.getConstantState()).isEqualTo(
|
||||
new FloatingMenuLayerDrawable.FloatingMenuLayerDrawableState(mContext,
|
||||
TEST_RES_ID_2, /* opacity= */ 27));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR;
|
||||
|
||||
import static com.android.settings.accessibility.FloatingMenuOpacityPreferenceController.DEFAULT_OPACITY;
|
||||
import static com.android.settings.accessibility.FloatingMenuOpacityPreferenceController.PRECISION;
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.widget.SeekBarPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link FloatingMenuOpacityPreferenceController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class FloatingMenuOpacityPreferenceControllerTest {
|
||||
|
||||
@Rule
|
||||
public MockitoRule mocks = MockitoJUnit.rule();
|
||||
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Mock
|
||||
private ContentResolver mContentResolver;
|
||||
private FloatingMenuOpacityPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
when(mContext.getContentResolver()).thenReturn(mContentResolver);
|
||||
mController = new FloatingMenuOpacityPreferenceController(mContext, "test_key");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_a11yBtnModeFloatingMenu_returnAvailable() {
|
||||
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
|
||||
ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_a11yBtnModeNavigationBar_returnDisabledDependentSetting() {
|
||||
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
|
||||
ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onChange_a11yBtnModeChangeToNavigationBar_preferenceDisabled() {
|
||||
mController.mPreference = new SeekBarPreference(mContext);
|
||||
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
|
||||
ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
|
||||
|
||||
mController.mContentObserver.onChange(false);
|
||||
|
||||
assertThat(mController.mPreference.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSliderPosition_putNormalOpacityValue_expectedValue() {
|
||||
Settings.Secure.putFloat(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, 0.35f);
|
||||
|
||||
assertThat(mController.getSliderPosition()).isEqualTo(35);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSliderPosition_putOutOfBoundOpacityValue_defaultValue() {
|
||||
Settings.Secure.putFloat(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, 0.01f);
|
||||
|
||||
final int defaultValue = Math.round(DEFAULT_OPACITY * PRECISION);
|
||||
assertThat(mController.getSliderPosition()).isEqualTo(defaultValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setSliderPosition_expectedValue() {
|
||||
mController.setSliderPosition(27);
|
||||
|
||||
final float value = Settings.Secure.getFloat(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, -1);
|
||||
assertThat(value).isEqualTo(0.27f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onResume_registerSpecificContentObserver() {
|
||||
mController.onResume();
|
||||
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_MODE), false,
|
||||
mController.mContentObserver);
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED),
|
||||
false,
|
||||
mController.mContentObserver);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPause_unregisterContentObserver() {
|
||||
mController.onPause();
|
||||
|
||||
verify(mContentResolver).unregisterContentObserver(mController.mContentObserver);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.accessibility;
|
||||
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link FloatingMenuSizePreferenceController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class FloatingMenuSizePreferenceControllerTest {
|
||||
|
||||
@Rule
|
||||
public MockitoRule mocks = MockitoJUnit.rule();
|
||||
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Mock
|
||||
private ContentResolver mContentResolver;
|
||||
private final ListPreference mListPreference = new ListPreference(mContext);
|
||||
private FloatingMenuSizePreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
when(mContext.getContentResolver()).thenReturn(mContentResolver);
|
||||
mController = new FloatingMenuSizePreferenceController(mContext, "test_key");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_a11yBtnModeFloatingMenu_returnAvailable() {
|
||||
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
|
||||
ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_a11yBtnModeNavigationBar_returnDisabledDependentSetting() {
|
||||
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
|
||||
ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_floatingMenuLargeSizeAndFullCircle_largeSizeValue() {
|
||||
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE,
|
||||
FloatingMenuSizePreferenceController.Size.LARGE);
|
||||
|
||||
mController.updateState(mListPreference);
|
||||
|
||||
final String largeSize = String.valueOf(FloatingMenuSizePreferenceController.Size.LARGE);
|
||||
assertThat(mListPreference.getValue()).isEqualTo(largeSize);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onChange_a11yBtnModeChangeToNavigationBar_preferenceDisabled() {
|
||||
mController.mPreference = mListPreference;
|
||||
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
|
||||
ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
|
||||
|
||||
mController.mContentObserver.onChange(false);
|
||||
|
||||
assertThat(mController.mPreference.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onResume_registerSpecificContentObserver() {
|
||||
mController.onResume();
|
||||
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_MODE), false,
|
||||
mController.mContentObserver);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPause_unregisterContentObserver() {
|
||||
mController.onPause();
|
||||
|
||||
verify(mContentResolver).unregisterContentObserver(mController.mContentObserver);
|
||||
}
|
||||
}
|
||||
@@ -120,7 +120,6 @@ public class AvatarViewMixinTest {
|
||||
@Test
|
||||
@Config(qualifiers = "mcc999",
|
||||
shadows = {
|
||||
BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
|
||||
BatteryFixSliceTest.ShadowBatteryTipLoader.class
|
||||
})
|
||||
public void onStart_useMockAvatarViewMixin_shouldBeExecuted() {
|
||||
|
||||
@@ -30,7 +30,6 @@ import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.Bundle;
|
||||
import android.os.UidBatteryConsumer;
|
||||
@@ -39,15 +38,12 @@ import androidx.loader.app.LoaderManager;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.os.BatterySipper;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
|
||||
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;
|
||||
@@ -73,13 +69,7 @@ public class AppBatteryPreferenceControllerTest {
|
||||
@Mock
|
||||
private UidBatteryConsumer mUidBatteryConsumer;
|
||||
@Mock
|
||||
private BatterySipper mBatterySipper;
|
||||
@Mock
|
||||
private BatterySipper mOtherBatterySipper;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private BatteryStatsHelper mBatteryStatsHelper;
|
||||
@Mock
|
||||
private BatteryStats.Uid mUid;
|
||||
private UidBatteryConsumer mOtherUidBatteryConsumer;
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
@Mock
|
||||
@@ -102,10 +92,8 @@ public class AppBatteryPreferenceControllerTest {
|
||||
|
||||
mBatteryPreference = spy(new Preference(RuntimeEnvironment.application));
|
||||
|
||||
mBatterySipper.drainType = BatterySipper.DrainType.IDLE;
|
||||
mBatterySipper.uidObj = mUid;
|
||||
doReturn(TARGET_UID).when(mBatterySipper).getUid();
|
||||
doReturn(OTHER_UID).when(mOtherBatterySipper).getUid();
|
||||
when(mUidBatteryConsumer.getUid()).thenReturn(TARGET_UID);
|
||||
when(mOtherUidBatteryConsumer.getUid()).thenReturn(OTHER_UID);
|
||||
|
||||
mController = spy(new AppBatteryPreferenceController(
|
||||
RuntimeEnvironment.application, mFragment, "package1", null /* lifecycle */));
|
||||
@@ -125,14 +113,14 @@ public class AppBatteryPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findTargetSipper_findCorrectSipper() {
|
||||
final List<BatterySipper> usageList = new ArrayList<>();
|
||||
usageList.add(mBatterySipper);
|
||||
usageList.add(mOtherBatterySipper);
|
||||
when(mBatteryStatsHelper.getUsageList()).thenReturn(usageList);
|
||||
public void findTargetBatteryConsumer_findCorrectBatteryConsumer() {
|
||||
final List<UidBatteryConsumer> uidBatteryConsumers = new ArrayList<>();
|
||||
uidBatteryConsumers.add(mUidBatteryConsumer);
|
||||
uidBatteryConsumers.add(mOtherUidBatteryConsumer);
|
||||
when(mBatteryUsageStats.getUidBatteryConsumers()).thenReturn(uidBatteryConsumers);
|
||||
|
||||
assertThat(mController.findTargetSipper(mBatteryStatsHelper, TARGET_UID))
|
||||
.isEqualTo(mBatterySipper);
|
||||
assertThat(mController.findTargetUidBatteryConsumer(mBatteryUsageStats, TARGET_UID))
|
||||
.isEqualTo(mUidBatteryConsumer);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -147,13 +135,10 @@ public class AppBatteryPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void updateBattery_hasBatteryStats_summaryPercent() {
|
||||
mController.mBatteryHelper = mBatteryStatsHelper;
|
||||
mController.mSipper = mBatterySipper;
|
||||
mController.mBatteryUsageStats = mBatteryUsageStats;
|
||||
mController.mUidBatteryConsumer = mUidBatteryConsumer;
|
||||
doReturn(BATTERY_LEVEL).when(mBatteryUtils).calculateBatteryPercent(anyDouble(),
|
||||
anyDouble(), anyInt());
|
||||
doReturn(new ArrayList<>()).when(mBatteryStatsHelper).getUsageList();
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
mController.updateBattery();
|
||||
@@ -163,8 +148,6 @@ public class AppBatteryPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void isBatteryStatsAvailable_hasBatteryStatsHelperAndSipper_returnTrue() {
|
||||
mController.mBatteryHelper = mBatteryStatsHelper;
|
||||
mController.mSipper = mBatterySipper;
|
||||
mController.mBatteryUsageStats = mBatteryUsageStats;
|
||||
mController.mUidBatteryConsumer = mUidBatteryConsumer;
|
||||
|
||||
@@ -183,8 +166,6 @@ public class AppBatteryPreferenceControllerTest {
|
||||
when(mFragment.getActivity()).thenReturn(mActivity);
|
||||
final String key = mController.getPreferenceKey();
|
||||
when(mBatteryPreference.getKey()).thenReturn(key);
|
||||
mController.mSipper = mBatterySipper;
|
||||
mController.mBatteryHelper = mBatteryStatsHelper;
|
||||
mController.mBatteryUsageStats = mBatteryUsageStats;
|
||||
mController.mUidBatteryConsumer = mUidBatteryConsumer;
|
||||
|
||||
@@ -199,8 +180,8 @@ public class AppBatteryPreferenceControllerTest {
|
||||
mController.onResume();
|
||||
|
||||
verify(mLoaderManager)
|
||||
.restartLoader(AppInfoDashboardFragment.LOADER_BATTERY, Bundle.EMPTY,
|
||||
mController.mBatteryStatsHelperLoaderCallbacks);
|
||||
.restartLoader(AppInfoDashboardFragment.LOADER_BATTERY_USAGE_STATS, Bundle.EMPTY,
|
||||
mController.mBatteryUsageStatsLoaderCallbacks);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -209,6 +190,6 @@ public class AppBatteryPreferenceControllerTest {
|
||||
|
||||
mController.onPause();
|
||||
|
||||
verify(mLoaderManager).destroyLoader(AppInfoDashboardFragment.LOADER_BATTERY);
|
||||
verify(mLoaderManager).destroyLoader(AppInfoDashboardFragment.LOADER_BATTERY_USAGE_STATS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings.applications.appinfo;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -62,4 +64,13 @@ public class AppVersionPreferenceControllerTest {
|
||||
|
||||
verify(mPreference).setSummary("version test1234");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_packageInfoNull_shouldNotCrash() {
|
||||
when(mFragment.getPackageInfo()).thenReturn(null);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mController.getSummary()).isNull();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,17 +18,16 @@ package com.android.settings.datetime;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.robolectric.shadow.api.Shadow.extract;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowConnectivityManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -36,27 +35,28 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = ShadowConnectivityManager.class)
|
||||
public class AutoTimeZonePreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private UpdateTimeAndDateCallback mCallback;
|
||||
|
||||
@Mock
|
||||
private Context mContext;
|
||||
private AutoTimeZonePreferenceController mController;
|
||||
private Preference mPreference;
|
||||
private ShadowConnectivityManager connectivityManager;
|
||||
@Mock
|
||||
private TelephonyManager mTelephonyManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
|
||||
mPreference = new Preference(mContext);
|
||||
connectivityManager = extract(mContext.getSystemService(ConnectivityManager.class));
|
||||
connectivityManager.setNetworkSupported(ConnectivityManager.TYPE_MOBILE, true);
|
||||
|
||||
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
|
||||
when(mTelephonyManager.isDataCapable()).thenReturn(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -77,8 +77,7 @@ public class AutoTimeZonePreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void isWifiOnly_notAvailable() {
|
||||
connectivityManager.setNetworkSupported(ConnectivityManager.TYPE_MOBILE, false);
|
||||
|
||||
when(mTelephonyManager.isDataCapable()).thenReturn(false);
|
||||
mController = new AutoTimeZonePreferenceController(
|
||||
mContext, null /* callback */, false /* fromSUW */);
|
||||
|
||||
@@ -95,8 +94,7 @@ public class AutoTimeZonePreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void isWifiOnly_notEnable() {
|
||||
connectivityManager.setNetworkSupported(ConnectivityManager.TYPE_MOBILE, false);
|
||||
|
||||
when(mTelephonyManager.isDataCapable()).thenReturn(false);
|
||||
mController = new AutoTimeZonePreferenceController(
|
||||
mContext, null /* callback */, false /* fromSUW */);
|
||||
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.android.settings.datetime;
|
||||
|
||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_NOT_APPLICABLE;
|
||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_NOT_SUPPORTED;
|
||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_POSSESSED;
|
||||
import static android.app.time.Capabilities.CAPABILITY_NOT_APPLICABLE;
|
||||
import static android.app.time.Capabilities.CAPABILITY_NOT_SUPPORTED;
|
||||
import static android.app.time.Capabilities.CAPABILITY_POSSESSED;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.time.Capabilities;
|
||||
import android.app.time.TimeManager;
|
||||
import android.app.time.TimeZoneCapabilities;
|
||||
import android.app.time.TimeZoneCapabilitiesAndConfig;
|
||||
@@ -142,7 +143,7 @@ public class LocationTimeZoneDetectionPreferenceControllerTest {
|
||||
}
|
||||
|
||||
private static TimeZoneCapabilities createTimeZoneCapabilities(
|
||||
@TimeZoneCapabilities.CapabilityState int geoDetectionCapability) {
|
||||
@Capabilities.CapabilityState int geoDetectionCapability) {
|
||||
UserHandle arbitraryUserHandle = UserHandle.of(123);
|
||||
return new TimeZoneCapabilities.Builder(arbitraryUserHandle)
|
||||
.setConfigureAutoDetectionEnabledCapability(CAPABILITY_POSSESSED)
|
||||
|
||||
@@ -21,44 +21,42 @@ import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.robolectric.shadow.api.Shadow.extract;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.sysprop.TelephonyProperties;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowConnectivityManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = ShadowConnectivityManager.class)
|
||||
public class BasebandVersionPreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private Context mContext;
|
||||
private BasebandVersionPreferenceController mController;
|
||||
@Mock
|
||||
private TelephonyManager mTelephonyManager;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mController = new BasebandVersionPreferenceController(mContext, "key");
|
||||
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailability_wifiOnly_unavailable() {
|
||||
final ShadowConnectivityManager connectivityManager =
|
||||
extract(mContext.getSystemService(ConnectivityManager.class));
|
||||
connectivityManager.setNetworkSupported(ConnectivityManager.TYPE_MOBILE, false);
|
||||
|
||||
when(mTelephonyManager.isDataCapable()).thenReturn(false);
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
|
||||
}
|
||||
|
||||
@@ -66,10 +64,7 @@ public class BasebandVersionPreferenceControllerTest {
|
||||
public void getAvailability_hasMobile_available() {
|
||||
final String text = "test";
|
||||
TelephonyProperties.baseband_version(Arrays.asList(new String[]{text}));
|
||||
ShadowConnectivityManager connectivityManager =
|
||||
extract(mContext.getSystemService(ConnectivityManager.class));
|
||||
connectivityManager.setNetworkSupported(ConnectivityManager.TYPE_MOBILE, true);
|
||||
|
||||
when(mTelephonyManager.isDataCapable()).thenReturn(true);
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,4 +202,20 @@ public class TopLevelWallpaperPreferenceControllerTest {
|
||||
assertThat(Shadows.shadowOf(mContext).getNextStartedActivityForResult()
|
||||
.intent.hasExtra("com.android.wallpaper.LAUNCH_SOURCE")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handlePreferenceTreeClick_launchClearTask() {
|
||||
mShadowPackageManager.setResolveInfosForIntent(
|
||||
mWallpaperIntent, Lists.newArrayList());
|
||||
mShadowPackageManager.setResolveInfosForIntent(
|
||||
mStylesAndWallpaperIntent, Lists.newArrayList(mock(ResolveInfo.class)));
|
||||
|
||||
Preference preference = new Preference(mContext);
|
||||
preference.setKey(TEST_KEY);
|
||||
|
||||
mController.handlePreferenceTreeClick(preference);
|
||||
|
||||
assertThat((Shadows.shadowOf(mContext).getNextStartedActivityForResult()
|
||||
.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_TASK) != 0).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,6 @@ public class BatteryBroadcastReceiverTest {
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
|
||||
BatteryFixSliceTest.ShadowBatteryTipLoader.class
|
||||
})
|
||||
public void testOnReceive_batteryLevelChanged_dataUpdated() {
|
||||
@@ -93,7 +92,6 @@ public class BatteryBroadcastReceiverTest {
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
|
||||
BatteryFixSliceTest.ShadowBatteryTipLoader.class
|
||||
})
|
||||
public void testOnReceive_batteryHealthChanged_dataUpdated() {
|
||||
@@ -108,7 +106,6 @@ public class BatteryBroadcastReceiverTest {
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
|
||||
BatteryFixSliceTest.ShadowBatteryTipLoader.class
|
||||
})
|
||||
public void onReceive_batteryNotPresent_shouldShowHelpMessage() {
|
||||
@@ -121,7 +118,6 @@ public class BatteryBroadcastReceiverTest {
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
|
||||
BatteryFixSliceTest.ShadowBatteryTipLoader.class
|
||||
})
|
||||
public void testOnReceive_powerSaveModeChanged_listenerInvoked() {
|
||||
@@ -133,7 +129,6 @@ public class BatteryBroadcastReceiverTest {
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
|
||||
BatteryFixSliceTest.ShadowBatteryTipLoader.class
|
||||
})
|
||||
public void testOnReceive_batteryDataNotChanged_listenerNotInvoked() {
|
||||
@@ -154,7 +149,6 @@ public class BatteryBroadcastReceiverTest {
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
|
||||
BatteryFixSliceTest.ShadowBatteryTipLoader.class
|
||||
})
|
||||
public void testRegister_updateBatteryStatus() {
|
||||
|
||||
@@ -1,64 +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 org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
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.net.ConnectivityManager;
|
||||
|
||||
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 BatteryStatsHelperLoaderTest {
|
||||
@Mock
|
||||
private BatteryUtils mBatteryUtils;
|
||||
@Mock
|
||||
private ConnectivityManager mConnectivityManager;
|
||||
|
||||
private Context mContext;
|
||||
private BatteryStatsHelperLoader mBatteryStatsHelperLoader;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
doReturn(mConnectivityManager).when(mContext).getSystemService(
|
||||
Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
mBatteryStatsHelperLoader = spy(new BatteryStatsHelperLoader(mContext));
|
||||
mBatteryStatsHelperLoader.mBatteryUtils = mBatteryUtils;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadInBackground_loadWithoutBundle() {
|
||||
when(mBatteryStatsHelperLoader.getContext()).thenReturn(mContext);
|
||||
mBatteryStatsHelperLoader.loadInBackground();
|
||||
|
||||
verify(mBatteryUtils).initBatteryStatsHelper(any(), eq(null), any());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.BatteryStatsManager;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.BatteryUsageStatsQuery;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class BatteryUsageStatsLoaderTest {
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private BatteryStatsManager mBatteryStatsManager;
|
||||
@Mock
|
||||
private BatteryUsageStats mBatteryUsageStats;
|
||||
@Captor
|
||||
private ArgumentCaptor<BatteryUsageStatsQuery> mUsageStatsQueryCaptor;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
doReturn(mBatteryStatsManager).when(mContext).getSystemService(
|
||||
Context.BATTERY_STATS_SERVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadInBackground_loadWithoutHistory() {
|
||||
BatteryUsageStatsLoader loader = new BatteryUsageStatsLoader(
|
||||
mContext, /* includeBatteryHistory */ false);
|
||||
|
||||
when(mBatteryStatsManager.getBatteryUsageStats(mUsageStatsQueryCaptor.capture()))
|
||||
.thenReturn(mBatteryUsageStats);
|
||||
|
||||
loader.loadInBackground();
|
||||
|
||||
final int queryFlags = mUsageStatsQueryCaptor.getValue().getFlags();
|
||||
assertThat(queryFlags
|
||||
& BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadInBackground_loadWithHistory() {
|
||||
BatteryUsageStatsLoader loader = new BatteryUsageStatsLoader(
|
||||
mContext, /* includeBatteryHistory */ true);
|
||||
|
||||
when(mBatteryStatsManager.getBatteryUsageStats(mUsageStatsQueryCaptor.capture()))
|
||||
.thenReturn(mBatteryUsageStats);
|
||||
|
||||
loader.loadInBackground();
|
||||
|
||||
final int queryFlags = mUsageStatsQueryCaptor.getValue().getFlags();
|
||||
assertThat(queryFlags
|
||||
& BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY).isNotEqualTo(0);
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.BatteryStatsManager;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Process;
|
||||
@@ -120,6 +121,8 @@ public class BatteryUtilsTest {
|
||||
@Mock
|
||||
private BatteryStats.Timer mTimer;
|
||||
@Mock
|
||||
private BatteryUsageStats mBatteryUsageStats;
|
||||
@Mock
|
||||
private SystemBatteryConsumer mSystemBatteryConsumer;
|
||||
@Mock
|
||||
private BatterySipper mNormalBatterySipper;
|
||||
@@ -336,81 +339,6 @@ public class BatteryUtilsTest {
|
||||
assertThat(mBatteryUtils.shouldHideSystemBatteryConsumer(mSystemBatteryConsumer)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldHideSipper_TypeUnAccounted_ReturnTrue() {
|
||||
mNormalBatterySipper.drainType = BatterySipper.DrainType.UNACCOUNTED;
|
||||
assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldHideSipper_TypeOverAccounted_ReturnTrue() {
|
||||
mNormalBatterySipper.drainType = BatterySipper.DrainType.OVERCOUNTED;
|
||||
assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldHideSipper_TypeIdle_ReturnTrue() {
|
||||
mNormalBatterySipper.drainType = BatterySipper.DrainType.IDLE;
|
||||
assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldHideSipper_TypeCell_ReturnTrue() {
|
||||
mNormalBatterySipper.drainType = BatterySipper.DrainType.CELL;
|
||||
assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldHideSipper_TypeScreen_ReturnTrue() {
|
||||
mNormalBatterySipper.drainType = BatterySipper.DrainType.SCREEN;
|
||||
assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldHideSipper_TypeWifi_ReturnTrue() {
|
||||
mNormalBatterySipper.drainType = BatterySipper.DrainType.WIFI;
|
||||
assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldHideSipper_TypeBluetooth_ReturnTrue() {
|
||||
mNormalBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH;
|
||||
assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldHideSipper_TypeSystem_ReturnTrue() {
|
||||
mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
|
||||
when(mNormalBatterySipper.getUid()).thenReturn(Process.ROOT_UID);
|
||||
when(mProvider.isTypeSystem(any())).thenReturn(true);
|
||||
assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldHideSipper_UidNormal_ReturnFalse() {
|
||||
mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
|
||||
when(mNormalBatterySipper.getUid()).thenReturn(UID);
|
||||
assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldHideSipper_TypeService_ReturnTrue() {
|
||||
mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
|
||||
when(mNormalBatterySipper.getUid()).thenReturn(UID);
|
||||
when(mProvider.isTypeService(any())).thenReturn(true);
|
||||
|
||||
assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldHideSipper_hiddenSystemModule_ReturnTrue() {
|
||||
mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
|
||||
when(mNormalBatterySipper.getUid()).thenReturn(UID);
|
||||
when(mBatteryUtils.isHiddenSystemModule(mNormalBatterySipper)).thenReturn(true);
|
||||
|
||||
assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCalculateBatteryPercent() {
|
||||
assertThat(mBatteryUtils.calculateBatteryPercent(BATTERY_SYSTEM_USAGE, TOTAL_BATTERY_USAGE,
|
||||
@@ -418,20 +346,14 @@ public class BatteryUtilsTest {
|
||||
.isWithin(PRECISION).of(PERCENT_SYSTEM_USAGE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCalculateRunningTimeBasedOnStatsType() {
|
||||
assertThat(mBatteryUtils.calculateRunningTimeBasedOnStatsType(mBatteryStatsHelper,
|
||||
BatteryStats.STATS_SINCE_CHARGED)).isEqualTo(TIME_SINCE_LAST_FULL_CHARGE_MS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCalculateLastFullChargeTime() {
|
||||
final long currentTimeMs = System.currentTimeMillis();
|
||||
when(mBatteryStatsHelper.getStats().getStartClockTime()).thenReturn(
|
||||
when(mBatteryUsageStats.getStatsStartRealtime()).thenReturn(
|
||||
currentTimeMs - TIME_SINCE_LAST_FULL_CHARGE_MS);
|
||||
|
||||
assertThat(mBatteryUtils.calculateLastFullChargeTime(
|
||||
mBatteryStatsHelper, currentTimeMs)).isEqualTo(TIME_SINCE_LAST_FULL_CHARGE_MS);
|
||||
assertThat(mBatteryUtils.calculateLastFullChargeTime(mBatteryUsageStats, currentTimeMs))
|
||||
.isEqualTo(TIME_SINCE_LAST_FULL_CHARGE_MS);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -27,7 +27,6 @@ import android.os.Bundle;
|
||||
|
||||
import androidx.loader.app.LoaderManager;
|
||||
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.testutils.shadow.ShadowDashboardFragment;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
@@ -45,8 +44,6 @@ import java.util.List;
|
||||
@Config(shadows = ShadowDashboardFragment.class)
|
||||
public class PowerUsageBaseTest {
|
||||
|
||||
@Mock
|
||||
private BatteryStatsHelper mBatteryStatsHelper;
|
||||
@Mock
|
||||
private LoaderManager mLoaderManager;
|
||||
private TestFragment mFragment;
|
||||
@@ -56,7 +53,6 @@ public class PowerUsageBaseTest {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mFragment = spy(new TestFragment());
|
||||
mFragment.setBatteryStatsHelper(mBatteryStatsHelper);
|
||||
doReturn(mLoaderManager).when(mFragment).getLoaderManager();
|
||||
}
|
||||
|
||||
@@ -98,9 +94,5 @@ public class PowerUsageBaseTest {
|
||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void setBatteryStatsHelper(BatteryStatsHelper batteryStatsHelper) {
|
||||
mStatsHelper = batteryStatsHelper;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
@@ -40,8 +39,6 @@ import android.provider.Settings;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.os.BatterySipper;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
|
||||
@@ -54,7 +51,6 @@ import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
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;
|
||||
@@ -62,35 +58,19 @@ import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
// TODO: Improve this test class so that it starts up the real activity and fragment.
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class PowerUsageSummaryTest {
|
||||
|
||||
private static final int UID = 123;
|
||||
private static final int POWER_MAH = 100;
|
||||
private static final long TIME_SINCE_LAST_FULL_CHARGE_MS = 120 * 60 * 1000;
|
||||
private static final long TIME_SINCE_LAST_FULL_CHARGE_US =
|
||||
TIME_SINCE_LAST_FULL_CHARGE_MS * 1000;
|
||||
private static final long USAGE_TIME_MS = 65 * 60 * 1000;
|
||||
private static final double TOTAL_POWER = 200;
|
||||
private static Intent sAdditionalBatteryInfoIntent;
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
sAdditionalBatteryInfoIntent = new Intent("com.example.app.ADDITIONAL_BATTERY_INFO");
|
||||
}
|
||||
|
||||
@Mock
|
||||
private BatterySipper mNormalBatterySipper;
|
||||
@Mock
|
||||
private BatterySipper mScreenBatterySipper;
|
||||
@Mock
|
||||
private BatterySipper mCellBatterySipper;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private BatteryStatsHelper mBatteryHelper;
|
||||
@Mock
|
||||
private SettingsActivity mSettingsActivity;
|
||||
@Mock
|
||||
@@ -104,7 +84,6 @@ public class PowerUsageSummaryTest {
|
||||
@Mock
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
|
||||
private List<BatterySipper> mUsageList;
|
||||
private Context mRealContext;
|
||||
private TestFragment mFragment;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
@@ -123,27 +102,6 @@ public class PowerUsageSummaryTest {
|
||||
when(mFragment.getActivity()).thenReturn(mSettingsActivity);
|
||||
when(mFeatureFactory.powerUsageFeatureProvider.getAdditionalBatteryInfoIntent())
|
||||
.thenReturn(sAdditionalBatteryInfoIntent);
|
||||
when(mBatteryHelper.getTotalPower()).thenReturn(TOTAL_POWER);
|
||||
when(mBatteryHelper.getStats().computeBatteryRealtime(anyLong(), anyInt()))
|
||||
.thenReturn(TIME_SINCE_LAST_FULL_CHARGE_US);
|
||||
|
||||
when(mNormalBatterySipper.getUid()).thenReturn(UID);
|
||||
mNormalBatterySipper.totalPowerMah = POWER_MAH;
|
||||
mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
|
||||
|
||||
mCellBatterySipper.drainType = BatterySipper.DrainType.CELL;
|
||||
mCellBatterySipper.totalPowerMah = POWER_MAH;
|
||||
|
||||
mScreenBatterySipper.drainType = BatterySipper.DrainType.SCREEN;
|
||||
mScreenBatterySipper.usageTimeMs = USAGE_TIME_MS;
|
||||
|
||||
mUsageList = new ArrayList<>();
|
||||
mUsageList.add(mNormalBatterySipper);
|
||||
mUsageList.add(mScreenBatterySipper);
|
||||
mUsageList.add(mCellBatterySipper);
|
||||
|
||||
mFragment.mStatsHelper = mBatteryHelper;
|
||||
when(mBatteryHelper.getUsageList()).thenReturn(mUsageList);
|
||||
mFragment.mBatteryUtils = spy(new BatteryUtils(mRealContext));
|
||||
ReflectionHelpers.setField(mFragment, "mVisibilityLoggerMixin", mVisibilityLoggerMixin);
|
||||
ReflectionHelpers.setField(mFragment, "mBatteryBroadcastReceiver",
|
||||
|
||||
@@ -24,9 +24,9 @@ import static org.mockito.Mockito.spy;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.PowerManager;
|
||||
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.fuelgauge.BatteryInfo;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.AppLabelPredicate;
|
||||
@@ -57,7 +57,7 @@ public class BatteryTipLoaderTest {
|
||||
BatteryTip.TipType.SUMMARY,
|
||||
BatteryTip.TipType.SMART_BATTERY_MANAGER};
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private BatteryStatsHelper mBatteryStatsHelper;
|
||||
private BatteryUsageStats mBatteryUsageStats;
|
||||
@Mock
|
||||
private PowerManager mPowerManager;
|
||||
@Mock
|
||||
@@ -78,7 +78,7 @@ public class BatteryTipLoaderTest {
|
||||
doReturn(mPowerManager).when(mContext).getSystemService(Context.POWER_SERVICE);
|
||||
doReturn(mIntent).when(mContext).registerReceiver(any(), any());
|
||||
doReturn(mBatteryInfo).when(mBatteryUtils).getBatteryInfo(any());
|
||||
mBatteryTipLoader = new BatteryTipLoader(mContext, mBatteryStatsHelper);
|
||||
mBatteryTipLoader = new BatteryTipLoader(mContext, mBatteryUsageStats);
|
||||
mBatteryTipLoader.mBatteryUtils = mBatteryUtils;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,23 +19,20 @@ package com.android.settings.fuelgauge.batterytip.detectors;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.BatteryStatsManager;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.BatteryUsageStatsQuery;
|
||||
import android.os.UidBatteryConsumer;
|
||||
|
||||
import com.android.internal.os.BatterySipper;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
|
||||
@@ -46,7 +43,6 @@ import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
|
||||
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;
|
||||
@@ -64,15 +60,14 @@ public class HighUsageDetectorTest {
|
||||
private static final int UID_LOW = 345;
|
||||
private static final double POWER_HIGH = 20000;
|
||||
private static final double POWER_LOW = 10000;
|
||||
|
||||
private Context mContext;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private BatteryStatsHelper mBatteryStatsHelper;
|
||||
@Mock
|
||||
private BatterySipper mHighBatterySipper;
|
||||
private UidBatteryConsumer mHighBatteryConsumer;
|
||||
@Mock
|
||||
private BatterySipper mLowBatterySipper;
|
||||
private UidBatteryConsumer mLowBatteryConsumer;
|
||||
@Mock
|
||||
private BatterySipper mSystemBatterySipper;
|
||||
private UidBatteryConsumer mSystemBatteryConsumer;
|
||||
@Mock
|
||||
private HighUsageDataParser mDataParser;
|
||||
@Mock
|
||||
@@ -85,7 +80,6 @@ public class HighUsageDetectorTest {
|
||||
private BatteryTipPolicy mPolicy;
|
||||
private BatteryUtils mBatteryUtils;
|
||||
private HighUsageDetector mHighUsageDetector;
|
||||
private List<BatterySipper> mUsageList;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -100,27 +94,22 @@ public class HighUsageDetectorTest {
|
||||
when(mBatteryStatsManager.getBatteryUsageStats(any(BatteryUsageStatsQuery.class)))
|
||||
.thenReturn(mBatteryUsageStats);
|
||||
|
||||
mContext.sendStickyBroadcast(new Intent(Intent.ACTION_BATTERY_CHANGED));
|
||||
mContext.sendStickyBroadcast(new Intent(Intent.ACTION_BATTERY_CHANGED)
|
||||
.putExtra(BatteryManager.EXTRA_PLUGGED, 0));
|
||||
|
||||
mHighUsageDetector = spy(new HighUsageDetector(mContext, mPolicy, mBatteryStatsHelper,
|
||||
mHighUsageDetector = spy(new HighUsageDetector(mContext, mPolicy, mBatteryUsageStats,
|
||||
mBatteryUtils.getBatteryInfo(TAG)));
|
||||
mHighUsageDetector.mBatteryUtils = mBatteryUtils;
|
||||
mHighUsageDetector.mDataParser = mDataParser;
|
||||
doNothing().when(mHighUsageDetector).parseBatteryData();
|
||||
doReturn(UID_HIGH).when(mHighBatterySipper).getUid();
|
||||
doReturn(UID_LOW).when(mLowBatterySipper).getUid();
|
||||
mHighBatterySipper.uidObj = mock(BatteryStats.Uid.class);
|
||||
mHighBatterySipper.drainType = BatterySipper.DrainType.APP;
|
||||
mHighBatterySipper.totalSmearedPowerMah = POWER_HIGH;
|
||||
mLowBatterySipper.uidObj = mock(BatteryStats.Uid.class);
|
||||
mLowBatterySipper.drainType = BatterySipper.DrainType.APP;
|
||||
mLowBatterySipper.totalSmearedPowerMah = POWER_LOW;
|
||||
when(mBatteryUtils.shouldHideSipper(mSystemBatterySipper)).thenReturn(true);
|
||||
when(mBatteryUtils.shouldHideSipper(mHighBatterySipper)).thenReturn(false);
|
||||
when(mBatteryUtils.shouldHideSipper(mLowBatterySipper)).thenReturn(false);
|
||||
when(mBatteryStatsHelper.getStats().getDischargeAmount(anyInt())).thenReturn(100);
|
||||
when(mBatteryStatsHelper.getTotalPower()).thenReturn(POWER_HIGH + POWER_LOW);
|
||||
|
||||
doReturn(UID_HIGH).when(mHighBatteryConsumer).getUid();
|
||||
doReturn(UID_LOW).when(mLowBatteryConsumer).getUid();
|
||||
doReturn(POWER_HIGH).when(mHighBatteryConsumer).getConsumedPower();
|
||||
doReturn(POWER_LOW).when(mLowBatteryConsumer).getConsumedPower();
|
||||
doReturn(false).when(mBatteryUtils).shouldHideUidBatteryConsumer(mHighBatteryConsumer);
|
||||
doReturn(false).when(mBatteryUtils).shouldHideUidBatteryConsumer(mLowBatteryConsumer);
|
||||
when(mBatteryUsageStats.getDischargePercentage()).thenReturn(100);
|
||||
when(mBatteryUsageStats.getConsumedPower()).thenReturn(POWER_HIGH + POWER_LOW);
|
||||
|
||||
mHighAppInfo = new AppInfo.Builder()
|
||||
.setUid(UID_HIGH)
|
||||
@@ -129,11 +118,11 @@ public class HighUsageDetectorTest {
|
||||
.setUid(UID_LOW)
|
||||
.build();
|
||||
|
||||
mUsageList = new ArrayList<>();
|
||||
mUsageList.add(mSystemBatterySipper);
|
||||
mUsageList.add(mLowBatterySipper);
|
||||
mUsageList.add(mHighBatterySipper);
|
||||
when(mBatteryStatsHelper.getUsageList()).thenReturn(mUsageList);
|
||||
ArrayList<UidBatteryConsumer> consumers = new ArrayList<>();
|
||||
consumers.add(mSystemBatteryConsumer);
|
||||
consumers.add(mLowBatteryConsumer);
|
||||
consumers.add(mHighBatteryConsumer);
|
||||
when(mBatteryUsageStats.getUidBatteryConsumers()).thenReturn(consumers);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -68,7 +68,6 @@ public class SettingsHomepageActivityTest {
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
|
||||
BatteryFixSliceTest.ShadowBatteryTipLoader.class
|
||||
})
|
||||
public void onStart_isNotDebuggable_shouldHideSystemOverlay() {
|
||||
@@ -88,7 +87,6 @@ public class SettingsHomepageActivityTest {
|
||||
|
||||
@Test
|
||||
@Config(shadows = {
|
||||
BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
|
||||
BatteryFixSliceTest.ShadowBatteryTipLoader.class,
|
||||
})
|
||||
public void onStop_isNotDebuggable_shouldRemoveHideSystemOverlay() {
|
||||
|
||||
@@ -23,15 +23,15 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.BatteryUsageStats;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceMetadata;
|
||||
import androidx.slice.SliceProvider;
|
||||
import androidx.slice.widget.SliceLiveData;
|
||||
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.BatteryStatsHelperLoader;
|
||||
import com.android.settings.fuelgauge.BatteryUsageStatsLoader;
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipLoader;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
@@ -57,7 +57,7 @@ import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
|
||||
BatteryFixSliceTest.ShadowBatteryUsageStatsLoader.class,
|
||||
BatteryFixSliceTest.ShadowBatteryTipLoader.class
|
||||
})
|
||||
public class BatteryFixSliceTest {
|
||||
@@ -135,11 +135,11 @@ public class BatteryFixSliceTest {
|
||||
assertThat(ShadowEarlyWarningTip.isIconTintColorIdCalled()).isTrue();
|
||||
}
|
||||
|
||||
@Implements(BatteryStatsHelperLoader.class)
|
||||
public static class ShadowBatteryStatsHelperLoader {
|
||||
@Implements(BatteryUsageStatsLoader.class)
|
||||
public static class ShadowBatteryUsageStatsLoader {
|
||||
|
||||
@Implementation
|
||||
protected BatteryStatsHelper loadInBackground() {
|
||||
protected BatteryUsageStats loadInBackground() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,13 +19,8 @@ package com.android.settings.location;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -39,7 +34,6 @@ import org.robolectric.annotation.Config;
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class LocationServicesPreferenceControllerTest {
|
||||
@Mock
|
||||
private WifiManager mWifiManager;
|
||||
private Context mContext;
|
||||
private LocationServicesPreferenceController mController;
|
||||
|
||||
@@ -47,7 +41,6 @@ public class LocationServicesPreferenceControllerTest {
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
when(mContext.getSystemService(WifiManager.class)).thenReturn(mWifiManager);
|
||||
mController = new LocationServicesPreferenceController(mContext, "key");
|
||||
}
|
||||
|
||||
@@ -56,42 +49,6 @@ public class LocationServicesPreferenceControllerTest {
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocationScanning_WifiOnBleOn() {
|
||||
when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 1);
|
||||
assertThat(mController.getSummary()).isEqualTo(
|
||||
mContext.getString(R.string.scanning_status_text_wifi_on_ble_on));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocationScanning_WifiOnBleOff() {
|
||||
when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0);
|
||||
assertThat(mController.getSummary()).isEqualTo(
|
||||
mContext.getString(R.string.scanning_status_text_wifi_on_ble_off));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocationScanning_WifiOffBleOn() {
|
||||
when(mWifiManager.isScanAlwaysAvailable()).thenReturn(false);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 1);
|
||||
assertThat(mController.getSummary()).isEqualTo(
|
||||
mContext.getString(R.string.scanning_status_text_wifi_off_ble_on));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocationScanning_WifiOffBleOff() {
|
||||
when(mWifiManager.isScanAlwaysAvailable()).thenReturn(false);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0);
|
||||
assertThat(mController.getSummary()).isEqualTo(
|
||||
mContext.getString(R.string.scanning_status_text_wifi_off_ble_off));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "mcc999")
|
||||
public void testLocationScanning_ifDisabled_shouldNotBeShown() {
|
||||
|
||||
@@ -74,7 +74,7 @@ public class MobileNetworkSettingsTest {
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
|
||||
when(mActivity.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
|
||||
when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
|
||||
when(mContext.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
|
||||
ShadowEntityHeaderController.setUseMock(mock(EntityHeaderController.class));
|
||||
|
||||
@@ -101,7 +101,7 @@ public class WifiTetherSettingsTest {
|
||||
assertThat(niks).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_NAME);
|
||||
assertThat(niks).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_PASSWORD);
|
||||
assertThat(niks).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_AUTO_OFF);
|
||||
assertThat(niks).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_AP_BAND);
|
||||
assertThat(niks).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_MAXIMIZE_COMPATIBILITY);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -115,7 +115,7 @@ public class WifiTetherSettingsTest {
|
||||
assertThat(niks).contains(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_NAME);
|
||||
assertThat(niks).contains(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_PASSWORD);
|
||||
assertThat(niks).contains(WifiTetherSettings.KEY_WIFI_TETHER_AUTO_OFF);
|
||||
assertThat(niks).contains(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_AP_BAND);
|
||||
assertThat(niks).contains(WifiTetherSettings.KEY_WIFI_TETHER_MAXIMIZE_COMPATIBILITY);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -34,7 +34,6 @@ import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.Uri;
|
||||
import android.os.PersistableBundle;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
@@ -43,8 +42,6 @@ import android.telephony.TelephonyManager;
|
||||
import android.text.Html;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.builders.GridRowBuilder;
|
||||
import androidx.slice.builders.GridRowBuilder.CellBuilder;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
@@ -114,20 +111,6 @@ public class ProviderModelSliceHelperTest {
|
||||
mProviderModelSliceHelper = new MockProviderModelSliceHelper(mContext, testCustomSliceable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createMessageGridRow_inputTheResourceId_verifyTitle() {
|
||||
int messageResId = ResourcesUtils.getResourcesId(mContext, "string",
|
||||
"non_carrier_network_unavailable");
|
||||
CharSequence title = ResourcesUtils.getResourcesString(mContext,
|
||||
"non_carrier_network_unavailable");
|
||||
|
||||
GridRowBuilder testGridRow = mProviderModelSliceHelper.createMessageGridRow(messageResId,
|
||||
Settings.ACTION_AIRPLANE_MODE_SETTINGS);
|
||||
List<CellBuilder> cellItem = testGridRow.getCells();
|
||||
|
||||
assertThat(cellItem.get(0).getTitle()).isEqualTo(title);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConnectedWifiItem_inputListInvolveOneConnectedWifiItem_verifyReturnItem() {
|
||||
when(mWifiSliceItem1.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTED);
|
||||
|
||||
@@ -22,7 +22,6 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -42,7 +41,6 @@ import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceProvider;
|
||||
import androidx.slice.builders.GridRowBuilder;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
import androidx.slice.widget.SliceLiveData;
|
||||
@@ -97,12 +95,6 @@ public class ProviderModelSliceTest {
|
||||
private WifiSliceItem mMockWifiSliceItem3;
|
||||
@Mock
|
||||
ListBuilder.RowBuilder mMockCarrierRowBuild;
|
||||
@Mock
|
||||
ListBuilder.HeaderBuilder mMockHeader;
|
||||
@Mock
|
||||
GridRowBuilder mMockGridRowBuilderNonCarrierNetworkUnavailable;
|
||||
@Mock
|
||||
GridRowBuilder mMockGridRowBuilderAllNetworkUnavailable;
|
||||
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
@Mock
|
||||
@@ -147,35 +139,7 @@ public class ProviderModelSliceTest {
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void getSlice_noWorkerAndNoCarrier_getOneHeaderOneGridRowWithAllNetworkUnavailable() {
|
||||
mWifiList.clear();
|
||||
mMockProviderModelSlice = new MockProviderModelSlice(mContext, null);
|
||||
mockHelperCondition(false, false, false, null);
|
||||
|
||||
final Slice slice = mMockProviderModelSlice.getSlice();
|
||||
|
||||
assertThat(slice).isNotNull();
|
||||
verify(mListBuilder, times(1)).setHeader(mMockHeader);
|
||||
verify(mListBuilder, times(1)).addGridRow(mMockGridRowBuilderAllNetworkUnavailable);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void getSlice_noWifiAndNoCarrier_getOneHeaderOneGridRowWithAllNetworkUnavailable() {
|
||||
mWifiList.clear();
|
||||
mMockNetworkProviderWorker.updateSelfResults(null);
|
||||
mockHelperCondition(false, false, false, null);
|
||||
|
||||
final Slice slice = mMockProviderModelSlice.getSlice();
|
||||
|
||||
assertThat(slice).isNotNull();
|
||||
verify(mListBuilder, times(1)).setHeader(mMockHeader);
|
||||
verify(mListBuilder, times(1)).addGridRow(mMockGridRowBuilderAllNetworkUnavailable);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void getSlice_noWifiAndHasCarrierNoData_oneCarrierOneGridRowWithAllNetworkUnavailable() {
|
||||
public void getSlice_noWifiAndHasCarrierNoData_oneCarrier() {
|
||||
mWifiList.clear();
|
||||
mMockNetworkProviderWorker.updateSelfResults(null);
|
||||
mockHelperCondition(false, true, false, null);
|
||||
@@ -184,12 +148,11 @@ public class ProviderModelSliceTest {
|
||||
|
||||
assertThat(slice).isNotNull();
|
||||
verify(mListBuilder, times(1)).addRow(mMockCarrierRowBuild);
|
||||
verify(mListBuilder, times(1)).addGridRow(mMockGridRowBuilderAllNetworkUnavailable);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void getSlice_noWifiAndNoCarrier_oneCarrierOneGridRowWithNonCarrierNetworkUnavailable() {
|
||||
public void getSlice_noWifiAndNoCarrier_oneCarrier() {
|
||||
mWifiList.clear();
|
||||
mMockProviderModelSlice = new MockProviderModelSlice(mContext, null);
|
||||
mockHelperCondition(false, true, true, null);
|
||||
@@ -198,7 +161,6 @@ public class ProviderModelSliceTest {
|
||||
|
||||
assertThat(slice).isNotNull();
|
||||
verify(mListBuilder, times(1)).addRow(mMockCarrierRowBuild);
|
||||
verify(mListBuilder, times(1)).addGridRow(mMockGridRowBuilderNonCarrierNetworkUnavailable);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -331,19 +293,6 @@ public class ProviderModelSliceTest {
|
||||
|
||||
private void mockBuilder() {
|
||||
SliceAction mockSliceAction = getPrimarySliceAction();
|
||||
when(mMockHeader.getTitle()).thenReturn("mockHeader");
|
||||
when(mMockHeader.getPrimaryAction()).thenReturn(mockSliceAction);
|
||||
when(mProviderModelSliceHelper.createHeader(anyString())).thenReturn(mMockHeader);
|
||||
|
||||
int resId = ResourcesUtils.getResourcesId(mContext, "string",
|
||||
"non_carrier_network_unavailable");
|
||||
when(mProviderModelSliceHelper.createMessageGridRow(eq(resId), anyString())).thenReturn(
|
||||
mMockGridRowBuilderNonCarrierNetworkUnavailable);
|
||||
resId = ResourcesUtils.getResourcesId(mContext, "string",
|
||||
"all_network_unavailable");
|
||||
when(mProviderModelSliceHelper.createMessageGridRow(eq(resId), anyString())).thenReturn(
|
||||
mMockGridRowBuilderAllNetworkUnavailable);
|
||||
|
||||
when(mMockCarrierRowBuild.getTitle()).thenReturn("mockRow");
|
||||
when(mMockCarrierRowBuild.getPrimaryAction()).thenReturn(mockSliceAction);
|
||||
when(mProviderModelSliceHelper.createCarrierRow(anyString())).thenReturn(
|
||||
|
||||
@@ -22,15 +22,19 @@ import static org.mockito.Mockito.clearInvocations;
|
||||
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.net.Uri;
|
||||
import android.net.wifi.ScanResult;
|
||||
import android.net.wifi.WifiManager;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.network.AirplaneModePreferenceController;
|
||||
import com.android.settings.network.InternetUpdater;
|
||||
import com.android.settings.network.ProviderModelSliceHelper;
|
||||
import com.android.settings.slices.CustomSliceRegistry;
|
||||
import com.android.settings.testutils.ResourcesUtils;
|
||||
|
||||
@@ -42,6 +46,7 @@ import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@@ -55,6 +60,12 @@ public class InternetConnectivityPanelTest {
|
||||
ApplicationProvider.getApplicationContext(), "wifi_is_turned_on_subtitle");
|
||||
public static final String BUTTON_SETTINGS = ResourcesUtils.getResourcesString(
|
||||
ApplicationProvider.getApplicationContext(), "settings_button");
|
||||
public static final String SUBTITLE_NON_CARRIER_NETWORK_UNAVAILABLE =
|
||||
ResourcesUtils.getResourcesString(ApplicationProvider.getApplicationContext(),
|
||||
"non_carrier_network_unavailable");
|
||||
public static final String SUBTITLE_ALL_NETWORK_UNAVAILABLE =
|
||||
ResourcesUtils.getResourcesString(ApplicationProvider.getApplicationContext(),
|
||||
"all_network_unavailable");
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMocks = MockitoJUnit.rule();
|
||||
@@ -62,6 +73,10 @@ public class InternetConnectivityPanelTest {
|
||||
PanelContentCallback mPanelContentCallback;
|
||||
@Mock
|
||||
InternetUpdater mInternetUpdater;
|
||||
@Mock
|
||||
private WifiManager mWifiManager;
|
||||
@Mock
|
||||
private ProviderModelSliceHelper mProviderModelSliceHelper;
|
||||
|
||||
private Context mContext;
|
||||
private InternetConnectivityPanel mPanel;
|
||||
@@ -69,11 +84,14 @@ public class InternetConnectivityPanelTest {
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
when(mContext.getApplicationContext()).thenReturn(mContext);
|
||||
when(mContext.getSystemService(WifiManager.class)).thenReturn(mWifiManager);
|
||||
|
||||
mPanel = InternetConnectivityPanel.create(mContext);
|
||||
mPanel.registerCallback(mPanelContentCallback);
|
||||
mPanel.mIsProviderModelEnabled = true;
|
||||
mPanel.mInternetUpdater = mInternetUpdater;
|
||||
mPanel.mProviderModelSliceHelper = mProviderModelSliceHelper;
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -90,13 +108,6 @@ public class InternetConnectivityPanelTest {
|
||||
assertThat(mPanel.getTitle()).isEqualTo(TITLE_APM);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSubTitle_apmOff_shouldBeNull() {
|
||||
doReturn(false).when(mInternetUpdater).isAirplaneModeOn();
|
||||
|
||||
assertThat(mPanel.getSubTitle()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSubTitle_apmOnWifiOff_shouldBeNull() {
|
||||
doReturn(true).when(mInternetUpdater).isAirplaneModeOn();
|
||||
@@ -110,9 +121,43 @@ public class InternetConnectivityPanelTest {
|
||||
doReturn(true).when(mInternetUpdater).isAirplaneModeOn();
|
||||
doReturn(true).when(mInternetUpdater).isWifiEnabled();
|
||||
|
||||
mPanel.updatePanelTitle();
|
||||
|
||||
assertThat(mPanel.getSubTitle()).isEqualTo(SUBTITLE_WIFI_IS_TURNED_ON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSubTitle_apmOffWifiOnNoWifiListHasCarrierData_NonCarrierNetworkUnavailable() {
|
||||
List wifiList = new ArrayList<ScanResult>();
|
||||
mockCondition(false, true, true, true, wifiList);
|
||||
|
||||
mPanel.updatePanelTitle();
|
||||
|
||||
assertThat(mPanel.getSubTitle()).isEqualTo(SUBTITLE_NON_CARRIER_NETWORK_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSubTitle_apmOffWifiOnNoWifiListNoCarrierData_AllNetworkUnavailable() {
|
||||
List wifiList = new ArrayList<ScanResult>();
|
||||
mockCondition(false, true, false, true, wifiList);
|
||||
|
||||
mPanel.updatePanelTitle();
|
||||
|
||||
assertThat(mPanel.getSubTitle()).isEqualTo(SUBTITLE_ALL_NETWORK_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSubTitle_apmOffWifiOnTwoWifiItemsNoCarrierData_shouldBeNull() {
|
||||
List wifiList = new ArrayList<ScanResult>();
|
||||
wifiList.add(new ScanResult());
|
||||
wifiList.add(new ScanResult());
|
||||
mockCondition(false, true, false, true, wifiList);
|
||||
|
||||
mPanel.updatePanelTitle();
|
||||
|
||||
assertThat(mPanel.getSubTitle()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCustomizedButtonTitle_apmOff_shouldBeSettings() {
|
||||
doReturn(false).when(mInternetUpdater).isAirplaneModeOn();
|
||||
@@ -244,4 +289,13 @@ public class InternetConnectivityPanelTest {
|
||||
|
||||
verify(mPanelContentCallback).onCustomizedButtonStateChanged();
|
||||
}
|
||||
|
||||
private void mockCondition(boolean airplaneMode, boolean hasCarrier,
|
||||
boolean isDataSimActive, boolean isWifiEnabled, List<ScanResult> wifiItems) {
|
||||
doReturn(airplaneMode).when(mInternetUpdater).isAirplaneModeOn();
|
||||
when(mProviderModelSliceHelper.hasCarrier()).thenReturn(hasCarrier);
|
||||
when(mProviderModelSliceHelper.isDataSimActive()).thenReturn(isDataSimActive);
|
||||
doReturn(isWifiEnabled).when(mInternetUpdater).isWifiEnabled();
|
||||
doReturn(wifiItems).when(mWifiManager).getScanResults();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* 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.wifi.tether;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.wifi.SoftApConfiguration;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class WifiTetherMaximizeCompatibilityPreferenceControllerTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
@Mock
|
||||
private WifiManager mWifiManager;
|
||||
@Mock
|
||||
private WifiTetherBasePreferenceController.OnTetherConfigUpdateListener mListener;
|
||||
|
||||
private WifiTetherMaximizeCompatibilityPreferenceController mController;
|
||||
private SwitchPreference mPreference;
|
||||
private SoftApConfiguration mConfig;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
final Context context = 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(true).when(mWifiManager).isBridgedApConcurrencySupported();
|
||||
doReturn(mConfig).when(mWifiManager).getSoftApConfiguration();
|
||||
|
||||
mController = new WifiTetherMaximizeCompatibilityPreferenceController(context, mListener);
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
final PreferenceManager preferenceManager = new PreferenceManager(context);
|
||||
final PreferenceScreen screen = preferenceManager.createPreferenceScreen(context);
|
||||
mPreference = new SwitchPreference(context);
|
||||
mPreference.setKey(WifiTetherMaximizeCompatibilityPreferenceController.PREF_KEY);
|
||||
screen.addPreference(mPreference);
|
||||
mController.displayPreference(screen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPreferenceKey_shouldBeCorrect() {
|
||||
assertThat(mController.getPreferenceKey())
|
||||
.isEqualTo(WifiTetherMaximizeCompatibilityPreferenceController.PREF_KEY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDisplay_notSupport5GHzBand_setPreferenceDisabled() {
|
||||
doReturn(false).when(mWifiManager).is5GHzBandSupported();
|
||||
|
||||
mController.updateDisplay();
|
||||
|
||||
assertThat(mPreference.isEnabled()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDisplay_getNullCountryCode_setPreferenceDisabled() {
|
||||
doReturn(null).when(mWifiManager).getCountryCode();
|
||||
|
||||
mController.updateDisplay();
|
||||
|
||||
assertThat(mPreference.isEnabled()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDisplay_supported5GHzBandAndCountryCodeIsNotNull_setPreferenceEnabled() {
|
||||
doReturn(true).when(mWifiManager).is5GHzBandSupported();
|
||||
doReturn("US").when(mWifiManager).getCountryCode();
|
||||
|
||||
mController.updateDisplay();
|
||||
|
||||
assertThat(mPreference.isEnabled()).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_callbackOnTetherConfigUpdated() {
|
||||
mController.onPreferenceChange(mPreference, true);
|
||||
verify(mListener).onTetherConfigUpdated(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isMaximizeCompatibilityEnabled_concurrencySupportedAndEnabled_returnTure() {
|
||||
// The preconditions are ready in setup().
|
||||
|
||||
assertThat(mController.isMaximizeCompatibilityEnabled()).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isMaximizeCompatibilityEnabled_concurrencySupportedAndDisabled_returnFalse() {
|
||||
SoftApConfiguration config = new SoftApConfiguration.Builder()
|
||||
.setBridgedModeOpportunisticShutdownEnabled(false)
|
||||
.build();
|
||||
doReturn(config).when(mWifiManager).getSoftApConfiguration();
|
||||
|
||||
assertThat(mController.isMaximizeCompatibilityEnabled()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isMaximizeCompatibilityEnabled_noConcurrencyAndGetBand2gOnly_returnFalse() {
|
||||
doReturn(false).when(mWifiManager).isBridgedApConcurrencySupported();
|
||||
SoftApConfiguration config = new SoftApConfiguration.Builder()
|
||||
.setBand(SoftApConfiguration.BAND_2GHZ)
|
||||
.build();
|
||||
doReturn(config).when(mWifiManager).getSoftApConfiguration();
|
||||
|
||||
assertThat(mController.isMaximizeCompatibilityEnabled()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isMaximizeCompatibilityEnabled_noConcurrencyAndGetBand5gOnly_returnTrue() {
|
||||
doReturn(false).when(mWifiManager).isBridgedApConcurrencySupported();
|
||||
SoftApConfiguration config = new SoftApConfiguration.Builder()
|
||||
.setBand(SoftApConfiguration.BAND_5GHZ)
|
||||
.build();
|
||||
doReturn(config).when(mWifiManager).getSoftApConfiguration();
|
||||
|
||||
assertThat(mController.isMaximizeCompatibilityEnabled()).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isMaximizeCompatibilityEnabled_noConcurrencyAndGetBand2gAnd5g_returnTrue() {
|
||||
doReturn(false).when(mWifiManager).isBridgedApConcurrencySupported();
|
||||
SoftApConfiguration config = new SoftApConfiguration.Builder()
|
||||
.setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ)
|
||||
.build();
|
||||
doReturn(config).when(mWifiManager).getSoftApConfiguration();
|
||||
|
||||
assertThat(mController.isMaximizeCompatibilityEnabled()).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupMaximizeCompatibility_concurrencySupportedAndDisabled_setDisabled() {
|
||||
// The precondition of the concurrency supported is ready in setup().
|
||||
mController.onPreferenceChange(mPreference, false);
|
||||
|
||||
SoftApConfiguration.Builder builder = new SoftApConfiguration.Builder();
|
||||
mController.setupMaximizeCompatibility(builder);
|
||||
|
||||
assertThat(builder.build().isBridgedModeOpportunisticShutdownEnabled()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupMaximizeCompatibility_concurrencySupportedAndEnabled_setEnabled() {
|
||||
// The precondition of the concurrency supported is ready in setup().
|
||||
mController.onPreferenceChange(mPreference, true);
|
||||
|
||||
SoftApConfiguration.Builder builder = new SoftApConfiguration.Builder();
|
||||
mController.setupMaximizeCompatibility(builder);
|
||||
|
||||
assertThat(builder.build().isBridgedModeOpportunisticShutdownEnabled()).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupMaximizeCompatibility_noConcurrencyAndSetDisabled_setBand2gOnly() {
|
||||
doReturn(false).when(mWifiManager).isBridgedApConcurrencySupported();
|
||||
mController.onPreferenceChange(mPreference, false);
|
||||
|
||||
SoftApConfiguration.Builder builder = new SoftApConfiguration.Builder();
|
||||
mController.setupMaximizeCompatibility(builder);
|
||||
|
||||
assertThat(builder.build().getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupMaximizeCompatibility_noConcurrencyAndSetEnabled_setBand2gAnd5g() {
|
||||
doReturn(false).when(mWifiManager).isBridgedApConcurrencySupported();
|
||||
mController.onPreferenceChange(mPreference, true);
|
||||
|
||||
SoftApConfiguration.Builder builder = new SoftApConfiguration.Builder();
|
||||
mController.setupMaximizeCompatibility(builder);
|
||||
|
||||
assertThat(builder.build().getBand())
|
||||
.isEqualTo(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user