Snap for 4801384 from 2e0709b3b8 to pi-release
Change-Id: I5954c59bd42debb8cab1a6fa46c71bf5485cbc34
This commit is contained in:
@@ -21,5 +21,8 @@
|
||||
android:tint="?android:attr/colorError">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M15.67,4L14,4L14,2h-4v2L8.33,4C7.6,4 7,4.6 7,5.33v15.33C7,21.4 7.6,22 8.33,22h7.33c0.74,0 1.34,-0.6 1.34,-1.33L17,5.33C17,4.6 16.4,4 15.67,4zM13,18h-2v-2h2v2zM13,14h-2L11,9h2v5z"/>
|
||||
android:pathData="M13,17h-2v-2h2V17zM13,13h-2V8h2V13z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M16.2,22.5H7.8c-1.3,0 -2.3,-1 -2.3,-2.3V5.8c0,-1.3 1,-2.3 2.3,-2.3h0.7v-2h7v2h0.7c1.3,0 2.3,1.1 2.3,2.3v14.3C18.5,21.5 17.5,22.5 16.2,22.5zM7.8,5.5c-0.2,0 -0.3,0.2 -0.3,0.3v14.3c0,0.2 0.2,0.3 0.3,0.3h8.3c0.2,0 0.3,-0.1 0.3,-0.3V5.8c0,-0.2 -0.1,-0.3 -0.3,-0.3h-2.7v-2h-3v2H7.8z"/>
|
||||
</vector>
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:pathData="M15.67,4H14V2h-4v2H8.33C7.6,4 7,4.6 7,5.33v15.33C7,21.4 7.6,22 8.33,22h7.33c0.74,0 1.34,-0.6 1.34,-1.33V5.33C17,4.6 16.4,4 15.67,4zM11,20v-5.5H9L13,7v5.5h2L11,20z"
|
||||
android:fillColor="#000000"/>
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M16.2,22.5H7.8c-1.3,0 -2.3,-1 -2.3,-2.3V5.8c0,-1.3 1,-2.3 2.3,-2.3h0.7v-2h7v2h0.7c1.3,0 2.3,1.1 2.3,2.3v14.3C18.5,21.5 17.5,22.5 16.2,22.5zM7.8,5.5c-0.2,0 -0.3,0.2 -0.3,0.3v14.3c0,0.2 0.2,0.3 0.3,0.3h8.3c0.2,0 0.3,-0.1 0.3,-0.3V5.8c0,-0.2 -0.1,-0.3 -0.3,-0.3h-2.7v-2h-3v2H7.8z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M11.17,18.42v-4.58H9.5l3.33,-6.25v4.58h1.67L11.17,18.42z"/>
|
||||
</vector>
|
||||
|
||||
29
res/drawable/ic_battery_saver_accent_24dp.xml
Normal file
29
res/drawable/ic_battery_saver_accent_24dp.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<!--
|
||||
Copyright (C) 2018 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?android:attr/colorAccent">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M15,14l-2,0l0,2l-2,0l0,-2l-2,0l0,-2l2,0l0,-2l2,0l0,2l2,0z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M16.2,22.5H7.8c-1.3,0 -2.3,-1 -2.3,-2.3V5.8c0,-1.3 1,-2.3 2.3,-2.3h0.7v-2h7v2h0.7c1.3,0 2.3,1.1 2.3,2.3v14.3C18.5,21.5 17.5,22.5 16.2,22.5zM7.8,5.5c-0.2,0 -0.3,0.2 -0.3,0.3v14.3c0,0.2 0.2,0.3 0.3,0.3h8.3c0.2,0 0.3,-0.1 0.3,-0.3V5.8c0,-0.2 -0.1,-0.3 -0.3,-0.3h-2.7v-2h-3v2H7.8z"/>
|
||||
</vector>
|
||||
@@ -18,9 +18,10 @@ Copyright (C) 2018 The Android Open Source Project
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
|
||||
<path
|
||||
android:fillColor="?attr/batteryBadColor"
|
||||
android:pathData="M15.78,4h-1.72V2h-4.04v2H8.31C7.61,4,7,4.6,7,5.3v15.3C7,21.4,7.61,22,8.31,22h7.37c0.71,0,1.31-0.6,1.31-1.3V5.3
|
||||
C17.09,4.6,16.48,4,15.78,4z M15,14h-2v2h-2v-2H9v-2h2v-2h2v2h2V14z"/>
|
||||
android:pathData="M15,14l-2,0l0,2l-2,0l0,-2l-2,0l0,-2l2,0l0,-2l2,0l0,2l2,0z"/>
|
||||
<path
|
||||
android:fillColor="?attr/batteryBadColor"
|
||||
android:pathData="M16.2,22.5H7.8c-1.3,0 -2.3,-1 -2.3,-2.3V5.8c0,-1.3 1,-2.3 2.3,-2.3h0.7v-2h7v2h0.7c1.3,0 2.3,1.1 2.3,2.3v14.3C18.5,21.5 17.5,22.5 16.2,22.5zM7.8,5.5c-0.2,0 -0.3,0.2 -0.3,0.3v14.3c0,0.2 0.2,0.3 0.3,0.3h8.3c0.2,0 0.3,-0.1 0.3,-0.3V5.8c0,-0.2 -0.1,-0.3 -0.3,-0.3h-2.7v-2h-3v2H7.8z"/>
|
||||
</vector>
|
||||
|
||||
@@ -18,9 +18,10 @@ Copyright (C) 2018 The Android Open Source Project
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
|
||||
<path
|
||||
android:fillColor="?attr/batteryGoodColor"
|
||||
android:pathData="M15.78,4h-1.72V2h-4.04v2H8.31C7.61,4,7,4.6,7,5.3v15.3C7,21.4,7.61,22,8.31,22h7.37c0.71,0,1.31-0.6,1.31-1.3V5.3
|
||||
C17.09,4.6,16.48,4,15.78,4z M10.94,16.37l-3.18-3.18l1.42-1.42l1.77,1.76l3.9-3.9l1.42,1.42L10.94,16.37z"/>
|
||||
android:pathData="M16.2,22.5H7.8c-1.3,0 -2.3,-1 -2.3,-2.3V5.8c0,-1.3 1,-2.3 2.3,-2.3h0.7v-2h7v2h0.7c1.3,0 2.3,1.1 2.3,2.3v14.3C18.5,21.5 17.5,22.5 16.2,22.5zM7.8,5.5c-0.2,0 -0.3,0.2 -0.3,0.3v14.3c0,0.2 0.2,0.3 0.3,0.3h8.3c0.2,0 0.3,-0.1 0.3,-0.3V5.8c0,-0.2 -0.1,-0.3 -0.3,-0.3h-2.7v-2h-3v2H7.8z"/>
|
||||
<path
|
||||
android:fillColor="?attr/batteryGoodColor"
|
||||
android:pathData="M16.1,11.1l-1.4,-1.5l-3.9,3.9l-1.5,-1.4l-1.4,1.4l2.9,2.9z"/>
|
||||
</vector>
|
||||
|
||||
@@ -18,9 +18,10 @@ Copyright (C) 2018 The Android Open Source Project
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
|
||||
<path
|
||||
android:fillColor="?attr/batteryMaybeColor"
|
||||
android:pathData="M15.78,4h-1.72V2h-4.04v2H8.31C7.61,4,7,4.6,7,5.3v15.3C7,21.4,7.61,22,8.31,22h7.37c0.71,0,1.31-0.6,1.31-1.3V5.3
|
||||
C17.09,4.6,16.48,4,15.78,4z M13,17.5h-2v-2h2V17.5z M13,13.5h-2v-5h2V13.5z"/>
|
||||
android:pathData="M13,17h-2v-2h2V17zM13,13h-2V8h2V13z"/>
|
||||
<path
|
||||
android:fillColor="?attr/batteryMaybeColor"
|
||||
android:pathData="M16.2,22.5H7.8c-1.3,0 -2.3,-1 -2.3,-2.3V5.8c0,-1.3 1,-2.3 2.3,-2.3h0.7v-2h7v2h0.7c1.3,0 2.3,1.1 2.3,2.3v14.3C18.5,21.5 17.5,22.5 16.2,22.5zM7.8,5.5c-0.2,0 -0.3,0.2 -0.3,0.3v14.3c0,0.2 0.2,0.3 0.3,0.3h8.3c0.2,0 0.3,-0.1 0.3,-0.3V5.8c0,-0.2 -0.1,-0.3 -0.3,-0.3h-2.7v-2h-3v2H7.8z"/>
|
||||
</vector>
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M10,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8c0,-1.1 -0.9,-2 -2,-2h-8l-2,-2z"/>
|
||||
android:pathData="M20,6h-8l-2,-2H4C2.9,4 2.01,4.9 2.01,6L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8C22,6.9 21.1,6 20,6zM20,18H4V8h16V18z"/>
|
||||
</vector>
|
||||
28
res/drawable/ic_media_stream_off.xml
Normal file
28
res/drawable/ic_media_stream_off.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<!--
|
||||
Copyright (C) 2018 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M21.19,21.19L14,14l-2,-2l-9.2,-9.2L1.39,4.22l8.79,8.79c-0.06,0 -0.12,-0.01 -0.18,-0.01C7.79,13 6,14.79 6,17c0,2.21 1.79,4 4.01,4S14,19.21 14,17v-0.17l5.78,5.78L21.19,21.19zM10.01,19c-1.1,0 -2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2C12.01,18.1 11.11,19 10.01,19z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M14,11.17l0,-4.17l4,0l0,-4l-6,0l0,6.17z"/>
|
||||
</vector>
|
||||
@@ -21,6 +21,9 @@
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:pathData="M19.4,13.0c0.0,-0.3 0.1,-0.6 0.1,-1.0s0.0,-0.7 -0.1,-1.0l2.1,-1.7c0.2,-0.2 0.2,-0.4 0.1,-0.6l-2.0,-3.5C19.5,5.1 19.3,5.0 19.0,5.1l-2.5,1.0c-0.5,-0.4 -1.1,-0.7 -1.7,-1.0l-0.4,-2.6C14.5,2.2 14.2,2.0 14.0,2.0l-4.0,0.0C9.8,2.0 9.5,2.2 9.5,2.4L9.1,5.1C8.5,5.3 8.0,5.7 7.4,6.1L5.0,5.1C4.7,5.0 4.5,5.1 4.3,5.3l-2.0,3.5C2.2,8.9 2.3,9.2 2.5,9.4L4.6,11.0c0.0,0.3 -0.1,0.6 -0.1,1.0s0.0,0.7 0.1,1.0l-2.1,1.7c-0.2,0.2 -0.2,0.4 -0.1,0.6l2.0,3.5C4.5,18.9 4.7,19.0 5.0,18.9l2.5,-1.0c0.5,0.4 1.1,0.7 1.7,1.0l0.4,2.6c0.0,0.2 0.2,0.4 0.5,0.4l4.0,0.0c0.2,0.0 0.5,-0.2 0.5,-0.4l0.4,-2.6c0.6,-0.3 1.2,-0.6 1.7,-1.0l2.5,1.0c0.2,0.1 0.5,0.0 0.6,-0.2l2.0,-3.5c0.1,-0.2 0.1,-0.5 -0.1,-0.6L19.4,13.0zM12.0,15.5c-1.9,0.0 -3.5,-1.6 -3.5,-3.5s1.6,-3.5 3.5,-3.5s3.5,1.6 3.5,3.5S13.9,15.5 12.0,15.5z"
|
||||
android:fillColor="#ffffffff" />
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M13.85,22.25h-3.7c-0.74,0 -1.36,-0.54 -1.45,-1.27l-0.27,-1.89c-0.27,-0.14 -0.53,-0.29 -0.79,-0.46l-1.8,0.72c-0.7,0.26 -1.47,-0.03 -1.81,-0.65L2.2,15.53c-0.35,-0.66 -0.2,-1.44 0.36,-1.88l1.53,-1.19c-0.01,-0.15 -0.02,-0.3 -0.02,-0.46c0,-0.15 0.01,-0.31 0.02,-0.46l-1.52,-1.19C1.98,9.9 1.83,9.09 2.2,8.47l1.85,-3.19c0.34,-0.62 1.11,-0.9 1.79,-0.63l1.81,0.73c0.26,-0.17 0.52,-0.32 0.78,-0.46l0.27,-1.91c0.09,-0.7 0.71,-1.25 1.44,-1.25h3.7c0.74,0 1.36,0.54 1.45,1.27l0.27,1.89c0.27,0.14 0.53,0.29 0.79,0.46l1.8,-0.72c0.71,-0.26 1.48,0.03 1.82,0.65l1.84,3.18c0.36,0.66 0.2,1.44 -0.36,1.88l-1.52,1.19c0.01,0.15 0.02,0.3 0.02,0.46s-0.01,0.31 -0.02,0.46l1.52,1.19c0.56,0.45 0.72,1.23 0.37,1.86l-1.86,3.22c-0.34,0.62 -1.11,0.9 -1.8,0.63l-1.8,-0.72c-0.26,0.17 -0.52,0.32 -0.78,0.46l-0.27,1.91C15.21,21.71 14.59,22.25 13.85,22.25zM13.32,20.72c0,0.01 0,0.01 0,0.02L13.32,20.72zM10.68,20.7l0,0.02C10.69,20.72 10.69,20.71 10.68,20.7zM10.62,20.25h2.76l0.37,-2.55l0.53,-0.22c0.44,-0.18 0.88,-0.44 1.34,-0.78l0.45,-0.34l2.38,0.96l1.38,-2.4l-2.03,-1.58l0.07,-0.56c0.03,-0.26 0.06,-0.51 0.06,-0.78c0,-0.27 -0.03,-0.53 -0.06,-0.78l-0.07,-0.56l2.03,-1.58l-1.39,-2.4l-2.39,0.96l-0.45,-0.35c-0.42,-0.32 -0.87,-0.58 -1.33,-0.77L13.75,6.3l-0.37,-2.55h-2.76L10.25,6.3L9.72,6.51C9.28,6.7 8.84,6.95 8.38,7.3L7.93,7.63L5.55,6.68L4.16,9.07l2.03,1.58l-0.07,0.56C6.09,11.47 6.06,11.74 6.06,12c0,0.26 0.02,0.53 0.06,0.78l0.07,0.56l-2.03,1.58l1.38,2.4l2.39,-0.96l0.45,0.35c0.43,0.33 0.86,0.58 1.33,0.77l0.53,0.22L10.62,20.25zM18.22,17.72c0,0.01 -0.01,0.02 -0.01,0.03L18.22,17.72zM5.77,17.71l0.01,0.02C5.78,17.72 5.77,17.71 5.77,17.71zM3.93,9.47L3.93,9.47C3.93,9.47 3.93,9.47 3.93,9.47zM18.22,6.27c0,0.01 0.01,0.02 0.01,0.02L18.22,6.27zM5.79,6.25L5.78,6.27C5.78,6.27 5.79,6.26 5.79,6.25zM13.31,3.28c0,0.01 0,0.01 0,0.02L13.31,3.28zM10.69,3.26l0,0.02C10.69,3.27 10.69,3.27 10.69,3.26z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M12,12m-3.5,0a3.5,3.5 0,1 1,7 0a3.5,3.5 0,1 1,-7 0"/>
|
||||
</vector>
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?android:attr/colorForegroundInverse">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66
|
||||
-0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3
|
||||
-0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2
|
||||
14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59
|
||||
-1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49
|
||||
0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66
|
||||
0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3
|
||||
0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42
|
||||
0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25
|
||||
1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49
|
||||
-0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57
|
||||
-3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/>
|
||||
</vector>
|
||||
@@ -14,15 +14,14 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24.0dp"
|
||||
android:height="24.0dp"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M3.0,5.0
|
||||
l0.0,14.0c0.0,1.0 0.89,2.0 2.0,2.0l14.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0
|
||||
L21.0,5.0c0.0,-1.1 -0.9,-2.0 -2.0,-2.0
|
||||
L5.0,3.0c-1.11,0.0 -2.0,0.9 -2.0,2.0zm12.0,4.0c0.0,1.66 -1.34,3.0 -3.0,3.0s-3.0,-1.34 -3.0,-3.0 1.34,-3.0 3.0,-3.0 3.0,1.34 3.0,3.0zm-9.0,8.0c0.0,-2.0 4.0,-3.1 6.0,-3.1s6.0,1.1 6.0,3.1l0.0,1.0
|
||||
l-12.0,0l0.0,-1.0z"/>
|
||||
android:pathData="M19,3H5C3.89,3 3,3.9 3,5v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V5C21,3.9 20.1,3 19,3zM19,5v10.79C16.52,14.37 13.23,14 12,14s-4.52,0.37 -7,1.79V5H19zM5,19v-0.77C6.74,16.66 10.32,16 12,16s5.26,0.66 7,2.23V19H5z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M12,13c1.94,0 3.5,-1.56 3.5,-3.5C15.5,7.56 13.94,6 12,6c-1.94,0 -3.5,1.56 -3.5,3.5C8.5,11.44 10.06,13 12,13zM12,8c0.83,0 1.5,0.67 1.5,1.5c0,0.83 -0.67,1.5 -1.5,1.5c-0.83,0 -1.5,-0.67 -1.5,-1.5C10.5,8.67 11.17,8 12,8z"/>
|
||||
</vector>
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24.0dp"
|
||||
android:height="24.0dp"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M19.35,10.04C18.67,6.59 15.64,4.0 12.0,4.0 9.11,4.0 6.6,5.64 5.35,8.04 2.34,8.36 0.0,10.91 0.0,14.0c0.0,3.31 2.69,6.0 6.0,6.0l13.0,0.0c2.76,0.0 5.0,-2.24 5.0,-5.0 0.0,-2.64 -2.05,-4.78 -4.65,-4.96zM14.0,13.0l0.0,4.0l-4.0,0.0l0.0,-4.0L7.0,13.0l5.0,-5.0 5.0,5.0l-3.0,0.0z"/>
|
||||
android:pathData="M17.92,10.02C17.45,7.18 14.97,5 12,5C9.82,5 7.83,6.18 6.78,8.06C4.09,8.41 2,10.74 2,13.5C2,16.53 4.47,19 7.5,19h10c2.48,0 4.5,-2.02 4.5,-4.5C22,12.16 20.21,10.23 17.92,10.02zM17.5,17h-10C5.57,17 4,15.43 4,13.5c0,-1.89 1.54,-3.46 3.44,-3.49L8.08,10l0.26,-0.59C8.97,7.94 10.41,7 12,7c2.21,0 4,1.79 4,4v1h1.5c1.38,0 2.5,1.12 2.5,2.5S18.88,17 17.5,17zM14.09,11.09l1.41,1.41l-2.79,2.79L12,16l-0.71,-0.71L8.5,12.5l1.41,-1.41L11,12.17V9.5h2v2.67L14.09,11.09z"/>
|
||||
</vector>
|
||||
|
||||
@@ -21,8 +21,5 @@
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M20,15.31l2.6-2.6c0.39-0.39,0.39-1.02,0-1.41L20,8.69V5c0-0.55-0.45-1-1-1h-3.69l-2.6-2.6c-0.39-0.39-1.02-0.39-1.41,0
|
||||
L8.69,4H5C4.45,4,4,4.45,4,5v3.69l-2.6,2.6c-0.39,0.39-0.39,1.02,0,1.41l2.6,2.6V19c0,0.55,0.45,1,1,1h3.69l2.6,2.6
|
||||
c0.39,0.39,1.02,0.39,1.41,0l2.6-2.6H19c0.55,0,1-0.45,1-1V15.31z
|
||||
M12,18V6c3.31,0,6,2.69,6,6S15.31,18,12,18z"/>
|
||||
android:pathData="M20,8.69V4h-4.69L12,0.69L8.69,4H4v4.69L0.69,12L4,15.31V20h4.69L12,23.31L15.31,20H20v-4.69L23.31,12L20,8.69zM18,14.48V18h-3.52L12,20.48L9.52,18H6v-3.52L3.52,12L6,9.52V6h3.52L12,3.52L14.48,6H18v3.52L20.48,12L18,14.48zM12,17c2.76,0 5,-2.24 5,-5s-2.24,-5 -5,-5V17z"/>
|
||||
</vector>
|
||||
|
||||
@@ -20,8 +20,5 @@
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M20,15.31l2.6-2.6c0.39-0.39,0.39-1.02,0-1.41L20,8.69V5c0-0.55-0.45-1-1-1h-3.69l-2.6-2.6c-0.39-0.39-1.02-0.39-1.41,0
|
||||
L8.69,4H5C4.45,4,4,4.45,4,5v3.69l-2.6,2.6c-0.39,0.39-0.39,1.02,0,1.41l2.6,2.6V19c0,0.55,0.45,1,1,1h3.69l2.6,2.6
|
||||
c0.39,0.39,1.02,0.39,1.41,0l2.6-2.6H19c0.55,0,1-0.45,1-1V15.31z
|
||||
M12,18V6c3.31,0,6,2.69,6,6S15.31,18,12,18z"/>
|
||||
android:pathData="M20,8.69V4h-4.69L12,0.69L8.69,4H4v4.69L0.69,12L4,15.31V20h4.69L12,23.31L15.31,20H20v-4.69L23.31,12L20,8.69zM18,14.48V18h-3.52L12,20.48L9.52,18H6v-3.52L3.52,12L6,9.52V6h3.52L12,3.52L14.48,6H18v3.52L20.48,12L18,14.48zM12,17c2.76,0 5,-2.24 5,-5s-2.24,-5 -5,-5V17z"/>
|
||||
</vector>
|
||||
|
||||
@@ -21,5 +21,8 @@
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M12.0,2.0C8.13,2.0 5.0,5.13 5.0,9.0c0.0,5.25 7.0,13.0 7.0,13.0s7.0,-7.75 7.0,-13.0c0.0,-3.87 -3.13,-7.0 -7.0,-7.0zm0.0,9.5c-1.38,0.0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"/>
|
||||
android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M12,9m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/>
|
||||
</vector>
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M12.0,12.0c2.21,0.0 4.0,-1.79 4.0,-4.0s-1.79,-4.0 -4.0,-4.0 -4.0,1.79 -4.0,4.0 1.79,4.0 4.0,4.0zm0.0,2.0c-2.67,0.0 -8.0,1.34 -8.0,4.0l0.0,2.0l16.0,0.0l0.0,-2.0c0.0,-2.66 -5.33,-4.0 -8.0,-4.0z"/>
|
||||
android:pathData="M12,6c1.1,0 2,0.9 2,2s-0.9,2 -2,2s-2,-0.9 -2,-2S10.9,6 12,6M12,15c2.7,0 5.8,1.29 6,2v1H6l0,-0.99C6.2,16.29 9.3,15 12,15M12,4C9.79,4 8,5.79 8,8s1.79,4 4,4s4,-1.79 4,-4S14.21,4 12,4L12,4zM12,13c-2.67,0 -8,1.34 -8,4v3h16v-3C20,14.34 14.67,13 12,13L12,13z"/>
|
||||
</vector>
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.76 -2.24,-5.0 -5.0,-5.0S7.0,3.24 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.0 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0c0.0,-1.1 -0.9,-2.0 -2.0,-2.0zm-6.0,9.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0 2.0,0.9 2.0,2.0 -0.9,2.0 -2.0,2.0zm3.1,-9.0L8.9,8.0L8.9,6.0c0.0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0.0 3.1,1.39 3.1,3.1l0.0,2.0z"/>
|
||||
android:pathData="M18,8h-1V6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2H6c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V10C20,8.9 19.1,8 18,8zM9,6c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v2H9V6zM18,20H6V10h12V20zM12,17c1.1,0 2,-0.9 2,-2c0,-1.1 -0.9,-2 -2,-2c-1.1,0 -2,0.9 -2,2C10,16.1 10.9,17 12,17z"/>
|
||||
</vector>
|
||||
|
||||
@@ -20,5 +20,5 @@
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.76 -2.24,-5.0 -5.0,-5.0S7.0,3.24 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.0 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0c0.0,-1.1 -0.9,-2.0 -2.0,-2.0zm-6.0,9.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0 2.0,0.9 2.0,2.0 -0.9,2.0 -2.0,2.0zm3.1,-9.0L8.9,8.0L8.9,6.0c0.0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0.0 3.1,1.39 3.1,3.1l0.0,2.0z"/>
|
||||
android:pathData="M18,8h-1V6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2H6c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V10C20,8.9 19.1,8 18,8zM9,6c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v2H9V6zM18,20H6V10h12V20zM12,17c1.1,0 2,-0.9 2,-2c0,-1.1 -0.9,-2 -2,-2c-1.1,0 -2,0.9 -2,2C10,16.1 10.9,17 12,17z"/>
|
||||
</vector>
|
||||
|
||||
@@ -20,6 +20,6 @@
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:pathData="M17,1.01L7,1c-1.1,0 -2,0.9 -2,2v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2L19,3c0,-1.1 -0.9,-1.99 -2,-1.99zM17,19L7,19L7,5h10v14zM16,13h-3L13,8h-2v5L8,13l4,4 4,-4z"
|
||||
android:fillColor="#FFFFFFFF"/>
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7zM16,12.5l-4,4l-4,-4l1.41,-1.41L11,12.67V8.5V8h2v0.5v4.17l1.59,-1.59L16,12.5z"/>
|
||||
</vector>
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M17,1.01L7,1c-1.1,0 -2,0.9 -2,2v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2L19,3c0,-1.1 -0.9,-1.99 -2,-1.99zM17,19L7,19L7,5h10v14zM16,13h-3L13,8h-2v5L8,13l4,4 4,-4z"/>
|
||||
android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7zM16,12.5l-4,4l-4,-4l1.41,-1.41L11,12.67V8.5V8h2v0.5v4.17l1.59,-1.59L16,12.5z"/>
|
||||
</vector>
|
||||
@@ -39,7 +39,7 @@
|
||||
android:layout_height="56dp"
|
||||
android:contentDescription="@string/configure"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_settings_24dp_inverse"
|
||||
android:src="@drawable/ic_settings_24dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -604,6 +604,7 @@
|
||||
<LinearLayout android:id="@+id/hidden_settings_field"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
style="@style/wifi_item">
|
||||
|
||||
<TextView android:id="@+id/hidden_settings_title"
|
||||
|
||||
@@ -1120,6 +1120,20 @@
|
||||
<item>no</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Titles for SystemUI theme preference. -->
|
||||
<string-array name="systemui_theme_entries" >
|
||||
<item>@string/systemui_theme_wallpaper</item>
|
||||
<item>@string/systemui_theme_light</item>
|
||||
<item>@string/systemui_theme_dark</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Values for SystemUI theme preference. -->
|
||||
<string-array name="systemui_theme_values" translatable="false" >
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="gesture_prevent_ringing_entries" translatable="false">
|
||||
<item>@string/prevent_ringing_option_vibrate</item>
|
||||
<item>@string/prevent_ringing_option_mute</item>
|
||||
|
||||
@@ -38,9 +38,6 @@
|
||||
<!-- When true enable color temperature setting. -->
|
||||
<bool name="config_enableColorTemperature">false</bool>
|
||||
|
||||
<!-- Whether to show Connectivity Monitor switch in Developer Options -->
|
||||
<bool name="config_show_connectivity_monitor">false</bool>
|
||||
|
||||
<!-- Whether to show Camera laser sensor switch in Developer Options -->
|
||||
<bool name="config_show_camera_laser_sensor">false</bool>
|
||||
|
||||
|
||||
@@ -9112,15 +9112,6 @@
|
||||
<!-- Toast message letting the user know the color temperature setting is not immediate -->
|
||||
<string name="color_temperature_toast">To apply color change, turn off screen</string>
|
||||
|
||||
<!-- UI debug setting: title for ConnectivityMonitor switch [CHAR LIMIT=50] -->
|
||||
<string name="connectivity_monitor_switch">Connectivity Monitor</string>
|
||||
|
||||
<!-- UI debug setting: summary for switch of ConnectivityMonitor [CHAR LIMIT=500] -->
|
||||
<string name="connectivity_monitor_switch_summary">ConnectivityMonitor will collect logs when it detects a connectivity problem and prompt notification to user to file a bug</string>
|
||||
|
||||
<!-- Toast message letting the user know the how to apply connectivity monitor change -->
|
||||
<string name="connectivity_monitor_toast">To apply connectivity monitor change, reboot device</string>
|
||||
|
||||
<!-- Title for Camera laser sensor switch [CHAR LIMIT=NONE] -->
|
||||
<string name="camera_laser_sensor_switch">Camera Laser Sensor</string>
|
||||
|
||||
@@ -9883,12 +9874,21 @@
|
||||
</string>
|
||||
|
||||
<!-- Name of setting for switching device theme [CHAR LIMIT=60] -->
|
||||
<string name="device_theme">Device theme</string>
|
||||
<string name="color_theme">Color theme</string>
|
||||
<!-- Name of default device theme [CHAR LIMIT=60] -->
|
||||
<string name="default_theme">Default</string>
|
||||
<!-- Temporary reboot string, will be removed -->
|
||||
<string name="change_theme_reboot" translatable="false">Changing the theme requires a restart.</string>
|
||||
|
||||
<!-- Name of setting for switching the SystemUI theme [CHAR LIMIT=60] -->
|
||||
<string name="device_theme">Device theme</string>
|
||||
<!-- When SystemUI theme is chosen based on the wallpaper color [CHAR LIMIT=60] -->
|
||||
<string name="systemui_theme_wallpaper">Automatic (based on wallpaper)</string>
|
||||
<!-- When SystemUI theme is light [CHAR LIMIT=60] -->
|
||||
<string name="systemui_theme_light">Light</string>
|
||||
<!-- When SystemUI theme is dark [CHAR LIMIT=60] -->
|
||||
<string name="systemui_theme_dark">Dark</string>
|
||||
|
||||
<!-- Switch label to show operator name in the status bar [CHAR LIMIT=60] -->
|
||||
<string name="show_operator_name_title">Network name</string>
|
||||
<!-- Switch summary to show operator name in the status bar [CHAR LIMIT=NONE] -->
|
||||
|
||||
@@ -18,32 +18,35 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/battery_saver"
|
||||
android:key="battery_saver">
|
||||
android:key="battery_saver_page">
|
||||
|
||||
<!-- Turn on automatically -->
|
||||
<SwitchPreference
|
||||
android:key="auto_battery_saver"
|
||||
android:title="@string/battery_saver_auto_title"
|
||||
settings:controller="com.android.settings.fuelgauge.batterysaver.AutoBatterySaverPreferenceController"/>
|
||||
settings:controller="com.android.settings.fuelgauge.batterysaver.AutoBatterySaverPreferenceController" />
|
||||
|
||||
<com.android.settings.widget.SeekBarPreference
|
||||
android:key="battery_saver_seek_bar"
|
||||
android:title="@string/battery_saver_seekbar_title_placeholder"
|
||||
android:max="75"
|
||||
android:min="5"/>
|
||||
android:min="5" />
|
||||
|
||||
<com.android.settings.widget.TwoStateButtonPreference
|
||||
android:key="battery_saver_button_container"
|
||||
android:key="battery_saver"
|
||||
android:title="@string/battery_saver"
|
||||
android:selectable="false"
|
||||
settings:textOn="@string/battery_saver_button_turn_on"
|
||||
settings:textOff="@string/battery_saver_button_turn_off"/>
|
||||
settings:textOff="@string/battery_saver_button_turn_off"
|
||||
settings:platform_slice="true"
|
||||
settings:controller="com.android.settings.fuelgauge.batterysaver.BatterySaverButtonPreferenceController" />
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="battery_saver_footer">
|
||||
<com.android.settingslib.widget.FooterPreference
|
||||
android:key="battery_saver_footer_preference"
|
||||
android:title="@*android:string/battery_saver_description"
|
||||
android:selectable="false"/>
|
||||
android:selectable="false" />
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -183,11 +183,6 @@
|
||||
android:entries="@array/select_logpersist_titles"
|
||||
android:entryValues="@array/select_logpersist_values" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="connectivity_monitor_switch"
|
||||
android:title="@string/connectivity_monitor_switch"
|
||||
android:summary="@string/connectivity_monitor_switch_summary" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="camera_laser_sensor_switch"
|
||||
android:title="@string/camera_laser_sensor_switch" />
|
||||
|
||||
@@ -131,9 +131,16 @@
|
||||
|
||||
<ListPreference
|
||||
android:key="theme"
|
||||
android:title="@string/device_theme"
|
||||
android:title="@string/color_theme"
|
||||
android:summary="@string/summary_placeholder" />
|
||||
|
||||
<ListPreference
|
||||
android:key="systemui_theme"
|
||||
android:title="@string/device_theme"
|
||||
android:entries="@array/systemui_theme_entries"
|
||||
android:entryValues="@array/systemui_theme_values"
|
||||
settings:controller="com.android.settings.display.SystemUiThemePreferenceController" />
|
||||
|
||||
<Preference
|
||||
android:key="vr_display_pref"
|
||||
android:title="@string/display_vr_pref_title"
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<!-- Media volume -->
|
||||
<com.android.settings.notification.VolumeSeekBarPreference
|
||||
android:key="media_volume"
|
||||
android:icon="@*android:drawable/ic_audio_media"
|
||||
android:icon="@drawable/ic_media_stream"
|
||||
android:title="@string/media_volume_option_title"
|
||||
android:order="-180"
|
||||
settings:controller="com.android.settings.notification.MediaVolumePreferenceController"/>
|
||||
@@ -57,7 +57,7 @@
|
||||
<!-- Ring volume -->
|
||||
<com.android.settings.notification.VolumeSeekBarPreference
|
||||
android:key="ring_volume"
|
||||
android:icon="@*android:drawable/ic_audio_ring_notif"
|
||||
android:icon="@drawable/ic_notifications"
|
||||
android:title="@string/ring_volume_option_title"
|
||||
android:order="-160"
|
||||
settings:controller="com.android.settings.notification.RingVolumePreferenceController"/>
|
||||
@@ -73,7 +73,7 @@
|
||||
<!-- Notification volume -->
|
||||
<com.android.settings.notification.VolumeSeekBarPreference
|
||||
android:key="notification_volume"
|
||||
android:icon="@*android:drawable/ic_audio_ring_notif"
|
||||
android:icon="@drawable/ic_notifications"
|
||||
android:title="@string/notification_volume_option_title"
|
||||
android:order="-140"
|
||||
settings:controller="com.android.settings.notification.NotificationVolumePreferenceController"/>
|
||||
|
||||
@@ -15,9 +15,13 @@
|
||||
*/
|
||||
package com.android.settings.applications;
|
||||
|
||||
import android.app.usage.IUsageStatsManager;
|
||||
import android.app.usage.UsageEvents;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.view.View;
|
||||
@@ -25,6 +29,7 @@ import android.view.ViewGroup;
|
||||
import android.widget.Switch;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
@@ -33,6 +38,7 @@ import com.android.settingslib.utils.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -42,17 +48,24 @@ import java.util.Map;
|
||||
public class AppStateNotificationBridge extends AppStateBaseBridge {
|
||||
|
||||
private final Context mContext;
|
||||
private UsageStatsManager mUsageStatsManager;
|
||||
private IUsageStatsManager mUsageStatsManager;
|
||||
protected List<Integer> mUserIds;
|
||||
private NotificationBackend mBackend;
|
||||
private static final int DAYS_TO_CHECK = 7;
|
||||
|
||||
public AppStateNotificationBridge(Context context, ApplicationsState appState,
|
||||
Callback callback, UsageStatsManager usageStatsManager,
|
||||
NotificationBackend backend) {
|
||||
Callback callback, IUsageStatsManager usageStatsManager,
|
||||
UserManager userManager, NotificationBackend backend) {
|
||||
super(appState, callback);
|
||||
mContext = context;
|
||||
mUsageStatsManager = usageStatsManager;
|
||||
mBackend = backend;
|
||||
mUserIds = new ArrayList<>();
|
||||
mUserIds.add(mContext.getUserId());
|
||||
int workUserId = Utils.getManagedProfileId(userManager, mContext.getUserId());
|
||||
if (workUserId != UserHandle.USER_NULL) {
|
||||
mUserIds.add(workUserId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,7 +75,8 @@ public class AppStateNotificationBridge extends AppStateBaseBridge {
|
||||
|
||||
final Map<String, NotificationsSentState> map = getAggregatedUsageEvents();
|
||||
for (AppEntry entry : apps) {
|
||||
NotificationsSentState stats = map.get(entry.info.packageName);
|
||||
NotificationsSentState stats =
|
||||
map.get(getKey(UserHandle.getUserId(entry.info.uid), entry.info.packageName));
|
||||
calculateAvgSentCounts(stats);
|
||||
addBlockStatus(entry, stats);
|
||||
entry.extraInfo = stats;
|
||||
@@ -71,8 +85,8 @@ public class AppStateNotificationBridge extends AppStateBaseBridge {
|
||||
|
||||
@Override
|
||||
protected void updateExtraInfo(AppEntry entry, String pkg, int uid) {
|
||||
Map<String, NotificationsSentState> map = getAggregatedUsageEvents();
|
||||
NotificationsSentState stats = map.get(entry.info.packageName);
|
||||
NotificationsSentState stats = getAggregatedUsageEvents(
|
||||
UserHandle.getUserId(entry.info.uid), entry.info.packageName);
|
||||
calculateAvgSentCounts(stats);
|
||||
addBlockStatus(entry, stats);
|
||||
entry.extraInfo = stats;
|
||||
@@ -116,15 +130,23 @@ public class AppStateNotificationBridge extends AppStateBaseBridge {
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
long startTime = now - (DateUtils.DAY_IN_MILLIS * DAYS_TO_CHECK);
|
||||
UsageEvents events = mUsageStatsManager.queryEvents(startTime, now);
|
||||
for (int userId : mUserIds) {
|
||||
UsageEvents events = null;
|
||||
try {
|
||||
events = mUsageStatsManager.queryEventsForUser(
|
||||
startTime, now, userId, mContext.getPackageName());
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (events != null) {
|
||||
UsageEvents.Event event = new UsageEvents.Event();
|
||||
while (events.hasNextEvent()) {
|
||||
events.getNextEvent(event);
|
||||
NotificationsSentState stats = aggregatedStats.get(event.getPackageName());
|
||||
NotificationsSentState stats =
|
||||
aggregatedStats.get(getKey(userId, event.getPackageName()));
|
||||
if (stats == null) {
|
||||
stats = new NotificationsSentState();
|
||||
aggregatedStats.put(event.getPackageName(), stats);
|
||||
aggregatedStats.put(getKey(userId, event.getPackageName()), stats);
|
||||
}
|
||||
|
||||
if (event.getEventType() == UsageEvents.Event.NOTIFICATION_INTERRUPTION) {
|
||||
@@ -136,9 +158,42 @@ public class AppStateNotificationBridge extends AppStateBaseBridge {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return aggregatedStats;
|
||||
}
|
||||
|
||||
protected NotificationsSentState getAggregatedUsageEvents(int userId, String pkg) {
|
||||
NotificationsSentState stats = null;
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
long startTime = now - (DateUtils.DAY_IN_MILLIS * DAYS_TO_CHECK);
|
||||
UsageEvents events = null;
|
||||
try {
|
||||
events = mUsageStatsManager.queryEventsForPackageForUser(
|
||||
startTime, now, userId, pkg, mContext.getPackageName());
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (events != null) {
|
||||
UsageEvents.Event event = new UsageEvents.Event();
|
||||
while (events.hasNextEvent()) {
|
||||
events.getNextEvent(event);
|
||||
|
||||
if (event.getEventType() == UsageEvents.Event.NOTIFICATION_INTERRUPTION) {
|
||||
if (stats == null) {
|
||||
stats = new NotificationsSentState();
|
||||
}
|
||||
if (event.getTimeStamp() > stats.lastSent) {
|
||||
stats.lastSent = event.getTimeStamp();
|
||||
}
|
||||
stats.sentCount++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
|
||||
private static NotificationsSentState getNotificationsSentState(AppEntry entry) {
|
||||
if (entry == null || entry.extraInfo == null) {
|
||||
return null;
|
||||
@@ -149,6 +204,10 @@ public class AppStateNotificationBridge extends AppStateBaseBridge {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static String getKey(int userId, String pkg) {
|
||||
return userId + "|" + pkg;
|
||||
}
|
||||
|
||||
public View.OnClickListener getSwitchOnClickListener(final AppEntry entry) {
|
||||
if (entry != null) {
|
||||
return v -> {
|
||||
|
||||
@@ -41,6 +41,7 @@ import static com.android.settings.applications.manageapplications.AppFilterRegi
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.StringRes;
|
||||
import android.app.Activity;
|
||||
import android.app.usage.IUsageStatsManager;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -48,6 +49,7 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageItemInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.preference.PreferenceFrameLayout;
|
||||
@@ -224,7 +226,8 @@ public class ManageApplications extends InstrumentedFragment
|
||||
private View mSpinnerHeader;
|
||||
private Spinner mFilterSpinner;
|
||||
private FilterSpinnerAdapter mFilterAdapter;
|
||||
private UsageStatsManager mUsageStatsManager;
|
||||
private IUsageStatsManager mUsageStatsManager;
|
||||
private UserManager mUserManager;
|
||||
private NotificationBackend mNotificationBackend;
|
||||
private ResetAppsHelper mResetAppsHelper;
|
||||
private String mVolumeUuid;
|
||||
@@ -293,8 +296,9 @@ public class ManageApplications extends InstrumentedFragment
|
||||
screenTitle = R.string.change_wifi_state_title;
|
||||
} else if (className.equals(Settings.NotificationAppListActivity.class.getName())) {
|
||||
mListType = LIST_TYPE_NOTIFICATION;
|
||||
mUsageStatsManager =
|
||||
(UsageStatsManager) getContext().getSystemService(Context.USAGE_STATS_SERVICE);
|
||||
mUsageStatsManager = IUsageStatsManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.USAGE_STATS_SERVICE));
|
||||
mUserManager = UserManager.get(getContext());
|
||||
mNotificationBackend = new NotificationBackend();
|
||||
mSortOrder = R.id.sort_order_recent_notification;
|
||||
screenTitle = R.string.app_notifications_title;
|
||||
@@ -875,6 +879,7 @@ public class ManageApplications extends InstrumentedFragment
|
||||
if (mManageApplications.mListType == LIST_TYPE_NOTIFICATION) {
|
||||
mExtraInfoBridge = new AppStateNotificationBridge(mContext, mState, this,
|
||||
manageApplications.mUsageStatsManager,
|
||||
manageApplications.mUserManager,
|
||||
manageApplications.mNotificationBackend);
|
||||
} else if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) {
|
||||
mExtraInfoBridge = new AppStateUsageBridge(mContext, mState, this);
|
||||
|
||||
@@ -17,6 +17,8 @@ package com.android.settings.bluetooth;
|
||||
|
||||
import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
|
||||
|
||||
import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.app.PendingIntent;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
|
||||
@@ -47,7 +47,7 @@ public class BatterySaverCondition extends Condition implements
|
||||
|
||||
@Override
|
||||
public Drawable getIcon() {
|
||||
return new BatterySaverDrawable(mManager.getContext(), 0);
|
||||
return mManager.getContext().getDrawable(R.drawable.ic_battery_saver_accent_24dp);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -69,9 +69,16 @@ public class BluetoothA2dpHwOffloadPreferenceController extends DeveloperOptions
|
||||
@Override
|
||||
protected void onDeveloperOptionsSwitchDisabled() {
|
||||
super.onDeveloperOptionsSwitchDisabled();
|
||||
final boolean offloadSupported =
|
||||
SystemProperties.getBoolean(A2DP_OFFLOAD_SUPPORTED_PROPERTY, false);
|
||||
if (offloadSupported) {
|
||||
((SwitchPreference) mPreference).setChecked(false);
|
||||
SystemProperties.set(A2DP_OFFLOAD_DISABLED_PROPERTY, "false");
|
||||
} else {
|
||||
((SwitchPreference) mPreference).setChecked(true);
|
||||
SystemProperties.set(A2DP_OFFLOAD_DISABLED_PROPERTY, "true");
|
||||
}
|
||||
}
|
||||
|
||||
public void onA2dpHwDialogConfirmed() {
|
||||
final boolean offloadDisabled =
|
||||
|
||||
@@ -1,100 +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.development;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.SystemProperties;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
|
||||
|
||||
public class ConnectivityMonitorPreferenceController extends DeveloperOptionsPreferenceController
|
||||
implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
|
||||
|
||||
private static final String KEY_CONNECTIVITY_MONITOR_SWITCH = "connectivity_monitor_switch";
|
||||
@VisibleForTesting
|
||||
static final String BUILD_TYPE = "ro.build.type";
|
||||
@VisibleForTesting
|
||||
static final String PROPERTY_CONNECTIVITY_MONITOR = "persist.radio.enable_tel_mon";
|
||||
|
||||
@VisibleForTesting
|
||||
static final String ENABLED_STATUS = "enabled";
|
||||
@VisibleForTesting
|
||||
static final String DISABLED_STATUS = "disabled";
|
||||
@VisibleForTesting
|
||||
static final String USER_ENABLED_STATUS = "user_enabled";
|
||||
@VisibleForTesting
|
||||
static final String USER_DISABLED_STATUS = "user_disabled";
|
||||
|
||||
@VisibleForTesting
|
||||
static final String USERDEBUG_BUILD = "userdebug";
|
||||
@VisibleForTesting
|
||||
static final String ENG_BUILD = "eng";
|
||||
|
||||
public ConnectivityMonitorPreferenceController(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_CONNECTIVITY_MONITOR_SWITCH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
final String buildType = SystemProperties.get(BUILD_TYPE);
|
||||
return mContext.getResources().getBoolean(R.bool.config_show_connectivity_monitor)
|
||||
&& (TextUtils.equals(buildType, USERDEBUG_BUILD)
|
||||
|| TextUtils.equals(buildType, ENG_BUILD));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final boolean isEnabled = (Boolean) newValue;
|
||||
SystemProperties.set(PROPERTY_CONNECTIVITY_MONITOR,
|
||||
isEnabled ? USER_ENABLED_STATUS : USER_DISABLED_STATUS);
|
||||
Toast.makeText(mContext, R.string.connectivity_monitor_toast,
|
||||
Toast.LENGTH_LONG).show();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
final boolean enabled = isConnectivityMonitorEnabled();
|
||||
((SwitchPreference) mPreference).setChecked(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeveloperOptionsSwitchDisabled() {
|
||||
super.onDeveloperOptionsSwitchDisabled();
|
||||
SystemProperties.set(PROPERTY_CONNECTIVITY_MONITOR, USER_DISABLED_STATUS);
|
||||
((SwitchPreference) mPreference).setChecked(false);
|
||||
}
|
||||
|
||||
private boolean isConnectivityMonitorEnabled() {
|
||||
final String cmStatus = SystemProperties.get(PROPERTY_CONNECTIVITY_MONITOR,
|
||||
DISABLED_STATUS);
|
||||
return TextUtils.equals(ENABLED_STATUS, cmStatus) || TextUtils.equals(USER_ENABLED_STATUS,
|
||||
cmStatus);
|
||||
}
|
||||
}
|
||||
@@ -403,7 +403,6 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
controllers.add(new VerifyAppsOverUsbPreferenceController(context));
|
||||
controllers.add(new LogdSizePreferenceController(context));
|
||||
controllers.add(new LogPersistPreferenceController(context, fragment, lifecycle));
|
||||
controllers.add(new ConnectivityMonitorPreferenceController(context));
|
||||
controllers.add(new CameraLaserSensorPreferenceController(context));
|
||||
controllers.add(new LogicalCameraDefaultPreferenceController(context));
|
||||
controllers.add(new WifiDisplayCertificationPreferenceController(context));
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package com.android.settings.display;
|
||||
|
||||
import static android.provider.Settings.Secure.THEME_MODE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.support.v7.preference.ListPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
/**
|
||||
* Setting where user can pick if SystemUI will be light, dark or try to match
|
||||
* the wallpaper colors.
|
||||
*/
|
||||
public class SystemUiThemePreferenceController extends BasePreferenceController
|
||||
implements Preference.OnPreferenceChangeListener {
|
||||
|
||||
private ListPreference mSystemUiThemePref;
|
||||
|
||||
public SystemUiThemePreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
boolean enabled = FeatureFlagUtils.isEnabled(mContext, "settings_systemui_theme");
|
||||
return enabled ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mSystemUiThemePref = (ListPreference) screen.findPreference(getPreferenceKey());
|
||||
int value = Settings.Secure.getInt(mContext.getContentResolver(), THEME_MODE, 0);
|
||||
mSystemUiThemePref.setValue(Integer.toString(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
int value = Integer.parseInt((String) newValue);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), THEME_MODE, value);
|
||||
refreshSummary(preference);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
int value = Settings.Secure.getInt(mContext.getContentResolver(), THEME_MODE, 0);
|
||||
int index = mSystemUiThemePref.findIndexOfValue(Integer.toString(value));
|
||||
return mSystemUiThemePref.getEntries()[index];
|
||||
}
|
||||
}
|
||||
@@ -18,12 +18,12 @@ package com.android.settings.fuelgauge.batterysaver;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.PowerManager;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
import com.android.settings.fuelgauge.BatterySaverReceiver;
|
||||
import com.android.settings.widget.TwoStateButtonPreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settings.widget.TwoStateButtonPreference;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||
@@ -33,21 +33,29 @@ import com.android.settingslib.fuelgauge.BatterySaverUtils;
|
||||
* Controller to update the battery saver button
|
||||
*/
|
||||
public class BatterySaverButtonPreferenceController extends
|
||||
TwoStateButtonPreferenceController implements
|
||||
TogglePreferenceController implements
|
||||
LifecycleObserver, OnStart, OnStop, BatterySaverReceiver.BatterySaverListener {
|
||||
private static final String KEY = "battery_saver_button_container";
|
||||
private BatterySaverReceiver mBatterySaverReceiver;
|
||||
@VisibleForTesting
|
||||
PowerManager mPowerManager;
|
||||
|
||||
public BatterySaverButtonPreferenceController(Context context, Lifecycle lifecycle) {
|
||||
super(context, KEY);
|
||||
private final BatterySaverReceiver mBatterySaverReceiver;
|
||||
private final PowerManager mPowerManager;
|
||||
|
||||
private TwoStateButtonPreference mPreference;
|
||||
|
||||
public BatterySaverButtonPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
mBatterySaverReceiver = new BatterySaverReceiver(context);
|
||||
mBatterySaverReceiver.setBatterySaverListener(this);
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSliceable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,30 +68,44 @@ public class BatterySaverButtonPreferenceController extends
|
||||
mBatterySaverReceiver.setListening(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = (TwoStateButtonPreference) screen.findPreference(getPreferenceKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return mPowerManager.isPowerSaveMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setChecked(boolean stateOn) {
|
||||
// This screen already shows a warning, so we don't need another warning.
|
||||
return BatterySaverUtils.setPowerSaveMode(mContext, stateOn,
|
||||
false /* needFirstTimeWarning */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
setButtonVisibility(!mPowerManager.isPowerSaveMode());
|
||||
if (mPreference != null) {
|
||||
mPreference.setChecked(isChecked());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onButtonClicked(boolean stateOn) {
|
||||
// This screen already shows a warning, so we don't need another warning.
|
||||
BatterySaverUtils.setPowerSaveMode(mContext, stateOn, /*needFirstTimeWarning*/ false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPowerSaveModeChanged() {
|
||||
setButtonVisibility(!mPowerManager.isPowerSaveMode());
|
||||
final boolean isChecked = isChecked();
|
||||
if (mPreference != null && mPreference.isChecked() != isChecked) {
|
||||
mPreference.setChecked(isChecked);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBatteryChanged(boolean pluggedIn) {
|
||||
setButtonEnabled(!pluggedIn);
|
||||
if (mPreference != null) {
|
||||
mPreference.setButtonEnabled(!pluggedIn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@ public class BatterySaverSettings extends DashboardFragment {
|
||||
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new AutoBatterySaverPreferenceController(context));
|
||||
controllers.add(new AutoBatterySeekBarPreferenceController(context, lifecycle));
|
||||
controllers.add(new BatterySaverButtonPreferenceController(context, lifecycle));
|
||||
return controllers;
|
||||
}
|
||||
|
||||
|
||||
94
src/com/android/settings/location/LocationSliceBuilder.java
Normal file
94
src/com/android/settings/location/LocationSliceBuilder.java
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.android.settings.location;
|
||||
|
||||
import static android.provider.SettingsSlicesContract.KEY_LOCATION;
|
||||
|
||||
import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SubSettings;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.search.DatabaseIndexingUtils;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
|
||||
import android.support.v4.graphics.drawable.IconCompat;
|
||||
|
||||
/**
|
||||
* Utility class to build an intent-based Location Slice.
|
||||
*/
|
||||
public class LocationSliceBuilder {
|
||||
|
||||
/**
|
||||
* Backing Uri for the Location Slice.
|
||||
*/
|
||||
public static final Uri LOCATION_URI = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsSlicesContract.AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath(KEY_LOCATION)
|
||||
.build();
|
||||
|
||||
private LocationSliceBuilder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Location Slice bound to {@link #LOCATION_URI}.
|
||||
*/
|
||||
public static Slice getSlice(Context context) {
|
||||
final IconCompat icon = IconCompat.createWithResource(context,
|
||||
R.drawable.ic_signal_location);
|
||||
final String title = context.getString(R.string.location_settings_title);
|
||||
@ColorInt final int color = Utils.getColorAccent(context);
|
||||
final PendingIntent primaryAction = getPrimaryAction(context);
|
||||
final SliceAction primarySliceAction = new SliceAction(primaryAction, icon, title);
|
||||
|
||||
return new ListBuilder(context, LOCATION_URI, ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
.addRow(b -> b
|
||||
.setTitle(title)
|
||||
.setTitleItem(icon, ICON_IMAGE)
|
||||
.setPrimaryAction(primarySliceAction))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static PendingIntent getPrimaryAction(Context context) {
|
||||
final String screenTitle = context.getText(R.string.location_settings_title).toString();
|
||||
final Uri contentUri = new Uri.Builder().appendPath(KEY_LOCATION).build();
|
||||
final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
|
||||
LocationSettings.class.getName(), KEY_LOCATION, screenTitle,
|
||||
MetricsEvent.LOCATION)
|
||||
.setClassName(context.getPackageName(), SubSettings.class.getName())
|
||||
.setData(contentUri);
|
||||
|
||||
return PendingIntent.getActivity(context, 0 /* requestCode */,
|
||||
intent, 0 /* flags */);
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,6 @@ public class MediaVolumePreferenceController extends
|
||||
|
||||
@Override
|
||||
public int getMuteIcon() {
|
||||
return com.android.internal.R.drawable.ic_audio_media_mute;
|
||||
return R.drawable.ic_media_stream_off;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,28 +83,6 @@ public abstract class NotificationPreferenceController extends AbstractPreferenc
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays or removes preference in this controller.
|
||||
*/
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
if (isAvailable()) {
|
||||
final Preference preference = screen.findPreference(getPreferenceKey());
|
||||
if (mPreference != null && preference == null) {
|
||||
screen.addPreference(mPreference);
|
||||
}
|
||||
if (preference != null) {
|
||||
mPreference = preference;
|
||||
}
|
||||
if (mPreference != null && this instanceof Preference.OnPreferenceChangeListener) {
|
||||
mPreference.setOnPreferenceChangeListener(
|
||||
(Preference.OnPreferenceChangeListener) this);
|
||||
}
|
||||
} else {
|
||||
findAndRemovePreference(screen, getPreferenceKey());
|
||||
}
|
||||
}
|
||||
|
||||
// finds the preference recursively and removes it from its parent
|
||||
private void findAndRemovePreference(PreferenceGroup prefGroup, String key) {
|
||||
final int preferenceCount = prefGroup.getPreferenceCount();
|
||||
|
||||
@@ -56,7 +56,7 @@ public class NotificationVolumePreferenceController extends
|
||||
|
||||
@Override
|
||||
public int getMuteIcon() {
|
||||
return com.android.internal.R.drawable.ic_audio_ring_notif_mute;
|
||||
return R.drawable.ic_notifications_off_24dp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -126,12 +126,12 @@ public class RingVolumePreferenceController extends VolumeSeekBarPreferenceContr
|
||||
if (mPreference != null) {
|
||||
if (mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
|
||||
mMuteIcon = R.drawable.ic_volume_ringer_vibrate;
|
||||
mPreference.showIcon(com.android.internal.R.drawable.ic_audio_ring_notif_vibrate);
|
||||
mPreference.showIcon(R.drawable.ic_volume_ringer_vibrate);
|
||||
} else if (mRingerMode == AudioManager.RINGER_MODE_SILENT) {
|
||||
mMuteIcon = R.drawable.ic_notifications_off_24dp;
|
||||
mPreference.showIcon(com.android.internal.R.drawable.ic_audio_ring_notif_mute);
|
||||
mPreference.showIcon(R.drawable.ic_notifications_off_24dp);
|
||||
} else {
|
||||
mPreference.showIcon(com.android.internal.R.drawable.ic_audio_ring_notif);
|
||||
mPreference.showIcon(R.drawable.ic_notifications);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.android.settings.notification;
|
||||
|
||||
import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
|
||||
|
||||
import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.android.settings.Utils;
|
||||
import com.android.settings.slices.SettingsSliceProvider;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
public interface DeviceIndexFeatureProvider {
|
||||
@@ -39,15 +40,21 @@ public interface DeviceIndexFeatureProvider {
|
||||
String TAG = "DeviceIndex";
|
||||
|
||||
String INDEX_VERSION = "settings:index_version";
|
||||
String INDEX_LANGUAGE = "settings:language";
|
||||
|
||||
// Increment when new items are added to ensure they get pushed to the device index.
|
||||
String VERSION = Build.FINGERPRINT;
|
||||
|
||||
// When the device language changes, re-index so Slices trigger in device language.
|
||||
Locale LANGUAGE = Locale.getDefault();
|
||||
|
||||
boolean isIndexingEnabled();
|
||||
|
||||
void index(Context context, CharSequence title, Uri sliceUri, Uri launchUri,
|
||||
List<String> keywords);
|
||||
|
||||
void clearIndex(Context context);
|
||||
|
||||
default void updateIndex(Context context, boolean force) {
|
||||
if (!isIndexingEnabled()) {
|
||||
Log.w(TAG, "Skipping: device index is not enabled");
|
||||
@@ -59,12 +66,14 @@ public interface DeviceIndexFeatureProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!force && Objects.equals(
|
||||
Settings.Secure.getString(context.getContentResolver(), INDEX_VERSION), VERSION)) {
|
||||
if (!force && skipIndex(context)) {
|
||||
// No need to update.
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent scheduling multiple jobs
|
||||
setIndexState(context);
|
||||
|
||||
final ComponentName jobComponent = new ComponentName(context.getPackageName(),
|
||||
DeviceIndexUpdateJobService.class.getName());
|
||||
final int jobId = context.getResources().getInteger(R.integer.device_index_update);
|
||||
@@ -77,7 +86,6 @@ public interface DeviceIndexFeatureProvider {
|
||||
.setOverrideDeadline(1)
|
||||
.build());
|
||||
|
||||
Settings.Secure.putString(context.getContentResolver(), INDEX_VERSION, VERSION);
|
||||
}
|
||||
|
||||
static Uri createDeepLink(String s) {
|
||||
@@ -86,4 +94,18 @@ public interface DeviceIndexFeatureProvider {
|
||||
.appendQueryParameter(INTENT, s)
|
||||
.build();
|
||||
}
|
||||
|
||||
static boolean skipIndex(Context context) {
|
||||
final boolean isSameVersion = Objects.equals(
|
||||
Settings.Secure.getString(context.getContentResolver(), INDEX_VERSION), VERSION);
|
||||
final boolean isSameLanguage = Objects.equals(
|
||||
Settings.Secure.getString(context.getContentResolver(), INDEX_LANGUAGE), LANGUAGE);
|
||||
return isSameLanguage && isSameVersion;
|
||||
}
|
||||
|
||||
static void setIndexState(Context context) {
|
||||
Settings.Secure.putString(context.getContentResolver(), INDEX_VERSION, VERSION);
|
||||
Settings.Secure.putString(context.getContentResolver(), INDEX_LANGUAGE,
|
||||
LANGUAGE.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,4 +31,9 @@ public class DeviceIndexFeatureProviderImpl implements DeviceIndexFeatureProvide
|
||||
List<String> keywords) {
|
||||
// Not enabled by default.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearIndex(Context context) {
|
||||
// Not enabled by default.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.content.ContentResolver;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.net.Uri.Builder;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
@@ -84,11 +85,19 @@ public class DeviceIndexUpdateJobService extends JobService {
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.build();
|
||||
final Uri platformBaseUri = new Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsSlicesContract.AUTHORITY)
|
||||
.build();
|
||||
final Collection<Uri> slices = manager.getSliceDescendants(baseUri);
|
||||
slices.addAll(manager.getSliceDescendants(platformBaseUri));
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Indexing " + slices.size() + " slices");
|
||||
}
|
||||
|
||||
indexProvider.clearIndex(this /* context */);
|
||||
|
||||
for (Uri slice : slices) {
|
||||
if (!mRunningJob) {
|
||||
return;
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.util.KeyValueListParser;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.settings.location.LocationSliceBuilder;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.wifi.WifiSliceBuilder;
|
||||
@@ -175,6 +176,13 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
|
||||
@Override
|
||||
public Slice onBindSlice(Uri sliceUri) {
|
||||
final Set<String> blockedKeys = getBlockedKeys();
|
||||
final String key = sliceUri.getLastPathSegment();
|
||||
if (blockedKeys.contains(key)) {
|
||||
Log.e(TAG, "Requested blocked slice with Uri: " + sliceUri);
|
||||
return null;
|
||||
}
|
||||
|
||||
// If adding a new Slice, do not directly match Slice URIs.
|
||||
// Use {@link SlicesDatabaseAccessor}.
|
||||
if (WifiCallingSliceHelper.WIFI_CALLING_URI.equals(sliceUri)) {
|
||||
@@ -188,6 +196,8 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
return ZenModeSliceBuilder.getSlice(getContext());
|
||||
} else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
|
||||
return BluetoothSliceBuilder.getSlice(getContext());
|
||||
} else if (LocationSliceBuilder.LOCATION_URI.equals(sliceUri)) {
|
||||
return LocationSliceBuilder.getSlice(getContext());
|
||||
}
|
||||
|
||||
SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);
|
||||
@@ -289,10 +299,17 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
void loadSlice(Uri uri) {
|
||||
long startBuildTime = System.currentTimeMillis();
|
||||
|
||||
final SliceData sliceData = mSlicesDatabaseAccessor.getSliceDataFromUri(uri);
|
||||
final SliceData sliceData;
|
||||
try {
|
||||
sliceData = mSlicesDatabaseAccessor.getSliceDataFromUri(uri);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.e(TAG, "Could not get slice data for uri: " + uri, e);
|
||||
return;
|
||||
}
|
||||
|
||||
final BasePreferenceController controller = SliceBuilderUtils.getPreferenceController(
|
||||
getContext(), sliceData);
|
||||
|
||||
final IntentFilter filter = controller.getIntentFilter();
|
||||
if (filter != null) {
|
||||
registerIntentToUri(filter, uri);
|
||||
@@ -336,7 +353,8 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
private List<Uri> getSpecialCasePlatformUris() {
|
||||
return Arrays.asList(
|
||||
WifiSliceBuilder.WIFI_URI,
|
||||
BluetoothSliceBuilder.BLUETOOTH_URI
|
||||
BluetoothSliceBuilder.BLUETOOTH_URI,
|
||||
LocationSliceBuilder.LOCATION_URI
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,8 +86,13 @@ public class SliceBuilderUtils {
|
||||
FeatureFactory.getFactory(context).getMetricsFeatureProvider()
|
||||
.action(context, MetricsEvent.ACTION_SETTINGS_SLICE_REQUESTED, sliceNamePair);
|
||||
|
||||
if (controller.getAvailabilityStatus() != AVAILABLE) {
|
||||
return buildUnavailableSlice(context, sliceData, controller);
|
||||
if (!controller.isAvailable()) {
|
||||
// Cannot guarantee setting page is accessible, let the presenter handle error case.
|
||||
return null;
|
||||
}
|
||||
|
||||
if (controller.getAvailabilityStatus() == DISABLED_DEPENDENT_SETTING) {
|
||||
return buildUnavailableSlice(context, sliceData);
|
||||
}
|
||||
|
||||
switch (sliceData.getSliceType()) {
|
||||
@@ -176,14 +181,6 @@ public class SliceBuilderUtils {
|
||||
return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link PendingIntent} to the Settings home page.
|
||||
*/
|
||||
public static PendingIntent getSettingsIntent(Context context) {
|
||||
final Intent intent = new Intent(Settings.ACTION_SETTINGS);
|
||||
return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the summary text for a {@link Slice} built for {@param sliceData}.
|
||||
*/
|
||||
@@ -282,6 +279,7 @@ public class SliceBuilderUtils {
|
||||
final PendingIntent actionIntent = getSliderAction(context, sliceData);
|
||||
final PendingIntent contentIntent = getContentPendingIntent(context, sliceData);
|
||||
final IconCompat icon = IconCompat.createWithResource(context, sliceData.getIconResource());
|
||||
final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
|
||||
@ColorInt final int color = Utils.getColorAccent(context);
|
||||
final SliceAction primaryAction = new SliceAction(contentIntent, icon,
|
||||
sliceData.getTitle());
|
||||
@@ -289,12 +287,14 @@ public class SliceBuilderUtils {
|
||||
|
||||
return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
.addInputRange(builder -> builder
|
||||
.setHeader(builder -> builder
|
||||
.setTitle(sliceData.getTitle())
|
||||
.setSubtitle(subtitleText)
|
||||
.setPrimaryAction(primaryAction))
|
||||
.addInputRange(builder -> builder
|
||||
.setMax(sliderController.getMaxSteps())
|
||||
.setValue(sliderController.getSliderPosition())
|
||||
.setInputAction(actionIntent)
|
||||
.setPrimaryAction(primaryAction))
|
||||
.setInputAction(actionIntent))
|
||||
.setKeywords(keywords)
|
||||
.build();
|
||||
}
|
||||
@@ -355,40 +355,20 @@ public class SliceBuilderUtils {
|
||||
return keywords;
|
||||
}
|
||||
|
||||
private static Slice buildUnavailableSlice(Context context, SliceData data,
|
||||
BasePreferenceController controller) {
|
||||
private static Slice buildUnavailableSlice(Context context, SliceData data) {
|
||||
final String title = data.getTitle();
|
||||
final List<String> keywords = buildSliceKeywords(data);
|
||||
@ColorInt final int color = Utils.getColorAccent(context);
|
||||
final String summary;
|
||||
final SliceAction primaryAction;
|
||||
final CharSequence summary = context.getText(R.string.disabled_dependent_setting_summary);
|
||||
final IconCompat icon = IconCompat.createWithResource(context, data.getIconResource());
|
||||
|
||||
switch (controller.getAvailabilityStatus()) {
|
||||
case UNSUPPORTED_ON_DEVICE:
|
||||
summary = context.getString(R.string.unsupported_setting_summary);
|
||||
primaryAction = new SliceAction(getSettingsIntent(context), icon, title);
|
||||
break;
|
||||
case DISABLED_FOR_USER:
|
||||
summary = context.getString(R.string.disabled_for_user_setting_summary);
|
||||
primaryAction = new SliceAction(getContentPendingIntent(context, data), icon,
|
||||
title);
|
||||
break;
|
||||
case DISABLED_DEPENDENT_SETTING:
|
||||
summary = context.getString(R.string.disabled_dependent_setting_summary);
|
||||
primaryAction = new SliceAction(getContentPendingIntent(context, data), icon,
|
||||
title);
|
||||
break;
|
||||
case CONDITIONALLY_UNAVAILABLE:
|
||||
default:
|
||||
summary = context.getString(R.string.unknown_unavailability_setting_summary);
|
||||
primaryAction = new SliceAction(getSettingsIntent(context), icon, title);
|
||||
}
|
||||
final SliceAction primaryAction = new SliceAction(getContentPendingIntent(context, data),
|
||||
icon, title);
|
||||
|
||||
return new ListBuilder(context, data.getUri(), ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
.addRow(builder -> builder
|
||||
.setTitle(title)
|
||||
.setTitleItem(icon)
|
||||
.setSubtitle(summary)
|
||||
.setPrimaryAction(primaryAction))
|
||||
.setKeywords(keywords)
|
||||
|
||||
@@ -18,8 +18,10 @@ package com.android.settings.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v4.content.res.TypedArrayUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.android.settings.R;
|
||||
@@ -28,12 +30,21 @@ import com.android.settings.applications.LayoutPreference;
|
||||
/**
|
||||
* Preference that presents a button with two states(On vs Off)
|
||||
*/
|
||||
public class TwoStateButtonPreference extends LayoutPreference {
|
||||
public class TwoStateButtonPreference extends LayoutPreference implements
|
||||
View.OnClickListener {
|
||||
|
||||
private boolean mIsChecked;
|
||||
private final Button mButtonOn;
|
||||
private final Button mButtonOff;
|
||||
|
||||
public TwoStateButtonPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs, TypedArrayUtils.getAttr(
|
||||
context, R.attr.twoStateButtonPreferenceStyle, android.R.attr.preferenceStyle));
|
||||
|
||||
if (attrs != null) {
|
||||
if (attrs == null) {
|
||||
mButtonOn = null;
|
||||
mButtonOff = null;
|
||||
} else {
|
||||
final TypedArray styledAttrs = context.obtainStyledAttributes(attrs,
|
||||
R.styleable.TwoStateButtonPreference);
|
||||
final int textOnId = styledAttrs.getResourceId(
|
||||
@@ -44,19 +55,52 @@ public class TwoStateButtonPreference extends LayoutPreference {
|
||||
R.string.summary_placeholder);
|
||||
styledAttrs.recycle();
|
||||
|
||||
final Button buttonOn = getStateOnButton();
|
||||
buttonOn.setText(textOnId);
|
||||
final Button buttonOff = getStateOffButton();
|
||||
buttonOff.setText(textOffId);
|
||||
mButtonOn = findViewById(R.id.state_on_button);
|
||||
mButtonOn.setText(textOnId);
|
||||
mButtonOn.setOnClickListener(this);
|
||||
mButtonOff = findViewById(R.id.state_off_button);
|
||||
mButtonOff.setText(textOffId);
|
||||
mButtonOff.setOnClickListener(this);
|
||||
setChecked(isChecked());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final boolean stateOn = v.getId() == R.id.state_on_button;
|
||||
setChecked(stateOn);
|
||||
callChangeListener(stateOn);
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked) {
|
||||
// Update state
|
||||
mIsChecked = checked;
|
||||
// And update UI
|
||||
if (checked) {
|
||||
mButtonOn.setVisibility(View.GONE);
|
||||
mButtonOff.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mButtonOn.setVisibility(View.VISIBLE);
|
||||
mButtonOff.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
return mIsChecked;
|
||||
}
|
||||
|
||||
public void setButtonEnabled(boolean enabled) {
|
||||
mButtonOn.setEnabled(enabled);
|
||||
mButtonOff.setEnabled(enabled);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public Button getStateOnButton() {
|
||||
return findViewById(R.id.state_on_button);
|
||||
return mButtonOn;
|
||||
}
|
||||
|
||||
|
||||
@VisibleForTesting
|
||||
public Button getStateOffButton() {
|
||||
return findViewById(R.id.state_off_button);
|
||||
return mButtonOff;
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
/**
|
||||
* Controller to update the button with two states(On vs Off).
|
||||
*/
|
||||
public abstract class TwoStateButtonPreferenceController extends BasePreferenceController
|
||||
implements View.OnClickListener {
|
||||
private Button mButtonOn;
|
||||
private Button mButtonOff;
|
||||
|
||||
public TwoStateButtonPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
final TwoStateButtonPreference preference =
|
||||
(TwoStateButtonPreference) screen.findPreference(getPreferenceKey());
|
||||
mButtonOn = preference.getStateOnButton();
|
||||
mButtonOn.setOnClickListener(this);
|
||||
mButtonOff = preference.getStateOffButton();
|
||||
mButtonOff.setOnClickListener(this);
|
||||
}
|
||||
|
||||
protected void setButtonVisibility(boolean stateOn) {
|
||||
if (stateOn) {
|
||||
mButtonOff.setVisibility(View.GONE);
|
||||
mButtonOn.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mButtonOff.setVisibility(View.VISIBLE);
|
||||
mButtonOn.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setButtonEnabled(boolean enabled) {
|
||||
mButtonOn.setEnabled(enabled);
|
||||
mButtonOff.setEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final boolean stateOn = v.getId() == R.id.state_on_button;
|
||||
onButtonClicked(stateOn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback when button is clicked
|
||||
*
|
||||
* @param stateOn {@code true} if stateOn button is clicked, otherwise it means stateOff
|
||||
* button is clicked
|
||||
*/
|
||||
public abstract void onButtonClicked(boolean stateOn);
|
||||
}
|
||||
@@ -220,8 +220,6 @@ public class WifiConfigController implements TextWatcher,
|
||||
mMeteredSettingsSpinner = mView.findViewById(R.id.metered_settings);
|
||||
mHiddenSettingsSpinner = mView.findViewById(R.id.hidden_settings);
|
||||
mHiddenSettingsSpinner.setOnItemSelectedListener(this);
|
||||
mHiddenSettingsSpinner.setVisibility(View.GONE);
|
||||
mHiddenSettingsSpinner.setEnabled(false);
|
||||
mHiddenWarningView = mView.findViewById(R.id.hidden_settings_warning);
|
||||
mHiddenWarningView.setVisibility(
|
||||
mHiddenSettingsSpinner.getSelectedItemPosition() == NOT_HIDDEN_NETWORK
|
||||
@@ -241,8 +239,7 @@ public class WifiConfigController implements TextWatcher,
|
||||
showProxyFields();
|
||||
mView.findViewById(R.id.wifi_advanced_toggle).setVisibility(View.VISIBLE);
|
||||
// Hidden option can be changed only when the user adds a network manually.
|
||||
mHiddenSettingsSpinner.setVisibility(View.VISIBLE);
|
||||
mHiddenSettingsSpinner.setEnabled(true);
|
||||
mView.findViewById(R.id.hidden_settings_field).setVisibility(View.VISIBLE);
|
||||
((CheckBox) mView.findViewById(R.id.wifi_advanced_togglebox))
|
||||
.setOnCheckedChangeListener(this);
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.android.settings.wifi;
|
||||
import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
|
||||
import static android.provider.SettingsSlicesContract.KEY_WIFI;
|
||||
|
||||
import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ContentResolver;
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.PersistableBundle;
|
||||
import android.provider.Settings;
|
||||
import android.support.v4.graphics.drawable.IconCompat;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
@@ -121,7 +122,7 @@ public class WifiCallingSliceHelper {
|
||||
return getNonActionableWifiCallingSlice(
|
||||
mContext.getString(R.string.wifi_calling_settings_title),
|
||||
mContext.getString(R.string.wifi_calling_not_supported, carrierName),
|
||||
sliceUri, SliceBuilderUtils.getSettingsIntent(mContext));
|
||||
sliceUri, getSettingsIntent(mContext));
|
||||
}
|
||||
|
||||
final ImsManager imsManager = getImsManager(subId);
|
||||
@@ -132,7 +133,7 @@ public class WifiCallingSliceHelper {
|
||||
return getNonActionableWifiCallingSlice(
|
||||
mContext.getString(R.string.wifi_calling_settings_title),
|
||||
mContext.getString(R.string.wifi_calling_not_supported, carrierName),
|
||||
sliceUri, SliceBuilderUtils.getSettingsIntent(mContext));
|
||||
sliceUri, getSettingsIntent(mContext));
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -338,6 +339,14 @@ public class WifiCallingSliceHelper {
|
||||
return intent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link PendingIntent} to the Settings home page.
|
||||
*/
|
||||
public static PendingIntent getSettingsIntent(Context context) {
|
||||
final Intent intent = new Intent(Settings.ACTION_SETTINGS);
|
||||
return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */);
|
||||
}
|
||||
|
||||
private PendingIntent getBroadcastIntent(String action) {
|
||||
final Intent intent = new Intent(action);
|
||||
intent.setClass(mContext, SliceBroadcastReceiver.class);
|
||||
|
||||
@@ -36,17 +36,21 @@ 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.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.usage.IUsageStatsManager;
|
||||
import android.app.usage.UsageEvents;
|
||||
import android.app.usage.UsageEvents.Event;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.os.Looper;
|
||||
import android.os.Parcel;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Switch;
|
||||
|
||||
@@ -79,7 +83,9 @@ public class AppStateNotificationBridgeTest {
|
||||
@Mock
|
||||
private ApplicationsState mState;
|
||||
@Mock
|
||||
private UsageStatsManager mUsageStats;
|
||||
private IUsageStatsManager mUsageStats;
|
||||
@Mock
|
||||
private UserManager mUserManager;
|
||||
@Mock
|
||||
private NotificationBackend mBackend;
|
||||
private Context mContext;
|
||||
@@ -92,10 +98,12 @@ public class AppStateNotificationBridgeTest {
|
||||
when(mState.getBackgroundLooper()).thenReturn(mock(Looper.class));
|
||||
when(mBackend.getNotificationsBanned(anyString(), anyInt())).thenReturn(true);
|
||||
when(mBackend.isSystemApp(any(), any())).thenReturn(true);
|
||||
// most tests assume no work profile
|
||||
when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});
|
||||
mContext = RuntimeEnvironment.application.getApplicationContext();
|
||||
|
||||
mBridge = new AppStateNotificationBridge(mContext, mState,
|
||||
mock(AppStateBaseBridge.Callback.class), mUsageStats, mBackend);
|
||||
mock(AppStateBaseBridge.Callback.class), mUsageStats, mUserManager, mBackend);
|
||||
}
|
||||
|
||||
private AppEntry getMockAppEntry(String pkg) {
|
||||
@@ -115,14 +123,15 @@ public class AppStateNotificationBridgeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAggregatedUsageEvents_noEvents() {
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(mock(UsageEvents.class));
|
||||
public void testGetAggregatedUsageEvents_noEvents() throws Exception {
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()))
|
||||
.thenReturn(mock(UsageEvents.class));
|
||||
|
||||
assertThat(mBridge.getAggregatedUsageEvents()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAggregatedUsageEvents_onlyNotificationEvents() {
|
||||
public void testGetAggregatedUsageEvents_onlyNotificationEvents() throws Exception {
|
||||
List<Event> events = new ArrayList<>();
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
@@ -136,14 +145,15 @@ public class AppStateNotificationBridgeTest {
|
||||
events.add(bad);
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()))
|
||||
.thenReturn(usageEvents);
|
||||
|
||||
Map<String, NotificationsSentState> map = mBridge.getAggregatedUsageEvents();
|
||||
assertThat(map.get(PKG1).sentCount).isEqualTo(1);
|
||||
assertThat(map.get(mBridge.getKey(0, PKG1)).sentCount).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAggregatedUsageEvents_multipleEventsAgg() {
|
||||
public void testGetAggregatedUsageEvents_multipleEventsAgg() throws Exception {
|
||||
List<Event> events = new ArrayList<>();
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
@@ -157,15 +167,16 @@ public class AppStateNotificationBridgeTest {
|
||||
events.add(good1);
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()))
|
||||
.thenReturn(usageEvents);
|
||||
|
||||
Map<String, NotificationsSentState> map = mBridge.getAggregatedUsageEvents();
|
||||
assertThat(map.get(PKG1).sentCount).isEqualTo(2);
|
||||
assertThat(map.get(PKG1).lastSent).isEqualTo(6);
|
||||
assertThat(map.get(mBridge.getKey(0, PKG1)).sentCount).isEqualTo(2);
|
||||
assertThat(map.get(mBridge.getKey(0, PKG1)).lastSent).isEqualTo(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAggregatedUsageEvents_multiplePkgs() {
|
||||
public void testGetAggregatedUsageEvents_multiplePkgs() throws Exception {
|
||||
List<Event> events = new ArrayList<>();
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
@@ -179,19 +190,21 @@ public class AppStateNotificationBridgeTest {
|
||||
events.add(good1);
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()))
|
||||
.thenReturn(usageEvents);
|
||||
|
||||
Map<String, NotificationsSentState> map
|
||||
= mBridge.getAggregatedUsageEvents();
|
||||
assertThat(map.get(PKG1).sentCount).isEqualTo(1);
|
||||
assertThat(map.get(PKG2).sentCount).isEqualTo(1);
|
||||
assertThat(map.get(PKG1).lastSent).isEqualTo(6);
|
||||
assertThat(map.get(PKG2).lastSent).isEqualTo(1);
|
||||
assertThat(map.get(mBridge.getKey(0, PKG1)).sentCount).isEqualTo(1);
|
||||
assertThat(map.get(mBridge.getKey(0, PKG2)).sentCount).isEqualTo(1);
|
||||
assertThat(map.get(mBridge.getKey(0, PKG1)).lastSent).isEqualTo(6);
|
||||
assertThat(map.get(mBridge.getKey(0, PKG2)).lastSent).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadAllExtraInfo_noEvents() {
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(mock(UsageEvents.class));
|
||||
public void testLoadAllExtraInfo_noEvents() throws RemoteException {
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()))
|
||||
.thenReturn(mock(UsageEvents.class));
|
||||
ArrayList<AppEntry> apps = new ArrayList<>();
|
||||
apps.add(getMockAppEntry(PKG1));
|
||||
when(mSession.getAllApps()).thenReturn(apps);
|
||||
@@ -201,7 +214,7 @@ public class AppStateNotificationBridgeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadAllExtraInfo_multipleEventsAgg() {
|
||||
public void testLoadAllExtraInfo_multipleEventsAgg() throws RemoteException {
|
||||
List<Event> events = new ArrayList<>();
|
||||
for (int i = 0; i < 7; i++) {
|
||||
Event good = new Event();
|
||||
@@ -212,7 +225,8 @@ public class AppStateNotificationBridgeTest {
|
||||
}
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()))
|
||||
.thenReturn(usageEvents);
|
||||
|
||||
ArrayList<AppEntry> apps = new ArrayList<>();
|
||||
apps.add(getMockAppEntry(PKG1));
|
||||
@@ -229,7 +243,7 @@ public class AppStateNotificationBridgeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadAllExtraInfo_multiplePkgs() {
|
||||
public void testLoadAllExtraInfo_multiplePkgs() throws RemoteException {
|
||||
List<Event> events = new ArrayList<>();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
Event good = new Event();
|
||||
@@ -245,7 +259,8 @@ public class AppStateNotificationBridgeTest {
|
||||
events.add(good1);
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()))
|
||||
.thenReturn(usageEvents);
|
||||
|
||||
ArrayList<AppEntry> apps = new ArrayList<>();
|
||||
apps.add(getMockAppEntry(PKG1));
|
||||
@@ -265,8 +280,66 @@ public class AppStateNotificationBridgeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateExtraInfo_noEvents() {
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(mock(UsageEvents.class));
|
||||
public void testLoadAllExtraInfo_multipleUsers() throws RemoteException {
|
||||
// has work profile
|
||||
when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{1});
|
||||
mBridge = new AppStateNotificationBridge(mContext, mState,
|
||||
mock(AppStateBaseBridge.Callback.class), mUsageStats, mUserManager, mBackend);
|
||||
|
||||
List<Event> eventsProfileOwner = new ArrayList<>();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
good.mPackage = PKG1;
|
||||
good.mTimeStamp = i;
|
||||
eventsProfileOwner.add(good);
|
||||
}
|
||||
|
||||
List<Event> eventsProfile = new ArrayList<>();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
good.mPackage = PKG1;
|
||||
good.mTimeStamp = i;
|
||||
eventsProfile.add(good);
|
||||
}
|
||||
|
||||
UsageEvents usageEventsOwner = getUsageEvents(eventsProfileOwner);
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), eq(0), anyString()))
|
||||
.thenReturn(usageEventsOwner);
|
||||
|
||||
UsageEvents usageEventsProfile = getUsageEvents(eventsProfile);
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), eq(1), anyString()))
|
||||
.thenReturn(usageEventsProfile);
|
||||
|
||||
ArrayList<AppEntry> apps = new ArrayList<>();
|
||||
AppEntry owner = getMockAppEntry(PKG1);
|
||||
owner.info.uid = 1;
|
||||
apps.add(owner);
|
||||
|
||||
AppEntry profile = getMockAppEntry(PKG1);
|
||||
profile.info.uid = UserHandle.PER_USER_RANGE + 1;
|
||||
apps.add(profile);
|
||||
when(mSession.getAllApps()).thenReturn(apps);
|
||||
|
||||
mBridge.loadAllExtraInfo();
|
||||
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).sentCount).isEqualTo(8);
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).lastSent).isEqualTo(7);
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentWeekly).isEqualTo(0);
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentDaily).isEqualTo(1);
|
||||
|
||||
assertThat(((NotificationsSentState) apps.get(1).extraInfo).sentCount).isEqualTo(4);
|
||||
assertThat(((NotificationsSentState) apps.get(1).extraInfo).lastSent).isEqualTo(3);
|
||||
assertThat(((NotificationsSentState) apps.get(1).extraInfo).avgSentWeekly).isEqualTo(4);
|
||||
assertThat(((NotificationsSentState) apps.get(1).extraInfo).avgSentDaily).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateExtraInfo_noEvents() throws RemoteException {
|
||||
when(mUsageStats.queryEventsForPackageForUser(
|
||||
anyLong(), anyLong(), anyInt(), anyString(), anyString()))
|
||||
.thenReturn(mock(UsageEvents.class));
|
||||
AppEntry entry = getMockAppEntry(PKG1);
|
||||
|
||||
mBridge.updateExtraInfo(entry, "", 0);
|
||||
@@ -274,7 +347,7 @@ public class AppStateNotificationBridgeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateExtraInfo_multipleEventsAgg() {
|
||||
public void testUpdateExtraInfo_multipleEventsAgg() throws RemoteException {
|
||||
List<Event> events = new ArrayList<>();
|
||||
for (int i = 0; i < 13; i++) {
|
||||
Event good = new Event();
|
||||
@@ -285,7 +358,8 @@ public class AppStateNotificationBridgeTest {
|
||||
}
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
when(mUsageStats.queryEventsForPackageForUser(
|
||||
anyLong(), anyLong(), anyInt(), anyString(), anyString())).thenReturn(usageEvents);
|
||||
|
||||
AppEntry entry = getMockAppEntry(PKG1);
|
||||
mBridge.updateExtraInfo(entry, "", 0);
|
||||
|
||||
@@ -40,6 +40,7 @@ import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Looper;
|
||||
import android.os.UserManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
@@ -272,6 +273,10 @@ public class ManageApplicationsTest {
|
||||
@Test
|
||||
public void applicationsAdapter_onBindViewHolder_updateSwitch_notifications() {
|
||||
ManageApplications manageApplications = mock(ManageApplications.class);
|
||||
when(manageApplications.getActivity()).thenReturn(mock(Activity.class));
|
||||
UserManager um = mock(UserManager.class);
|
||||
when(um.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});
|
||||
ReflectionHelpers.setField(manageApplications, "mUserManager", um);
|
||||
manageApplications.mListType = LIST_TYPE_NOTIFICATION;
|
||||
ApplicationViewHolder holder = mock(ApplicationViewHolder.class);
|
||||
ReflectionHelpers.setField(holder, "itemView", mock(View.class));
|
||||
@@ -293,6 +298,9 @@ public class ManageApplicationsTest {
|
||||
manageApplications.mListType = LIST_TYPE_MAIN;
|
||||
ApplicationViewHolder holder = mock(ApplicationViewHolder.class);
|
||||
ReflectionHelpers.setField(holder, "itemView", mock(View.class));
|
||||
UserManager um = mock(UserManager.class);
|
||||
when(um.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});
|
||||
ReflectionHelpers.setField(manageApplications, "mUserManager", um);
|
||||
ManageApplications.ApplicationsAdapter adapter =
|
||||
new ManageApplications.ApplicationsAdapter(mState,
|
||||
manageApplications, mock(AppFilterItem.class),
|
||||
@@ -308,6 +316,10 @@ public class ManageApplicationsTest {
|
||||
@Test
|
||||
public void sortOrderSavedOnRebuild() {
|
||||
ManageApplications manageApplications = mock(ManageApplications.class);
|
||||
when(manageApplications.getActivity()).thenReturn(mock(Activity.class));
|
||||
UserManager um = mock(UserManager.class);
|
||||
when(um.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});
|
||||
ReflectionHelpers.setField(manageApplications, "mUserManager", um);
|
||||
manageApplications.mListType = LIST_TYPE_NOTIFICATION;
|
||||
manageApplications.mSortOrder = -1;
|
||||
ManageApplications.ApplicationsAdapter adapter =
|
||||
|
||||
@@ -1,191 +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.development;
|
||||
|
||||
import static com.android.settings.development.ConnectivityMonitorPreferenceController.ENG_BUILD;
|
||||
import static com.android.settings.development.ConnectivityMonitorPreferenceController.USERDEBUG_BUILD;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.SystemProperties;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class ConnectivityMonitorPreferenceControllerTest {
|
||||
|
||||
private static final String USER_BUILD = "user";
|
||||
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
@Mock
|
||||
private SwitchPreference mPreference;
|
||||
|
||||
private Context mContext;
|
||||
private ConnectivityMonitorPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mController = new ConnectivityMonitorPreferenceController(mContext);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
mController.displayPreference(mScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_trueShowFlagWithUserdebugBuild_shouldReturnTrue() {
|
||||
SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD);
|
||||
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_trueShowFlagWithEngBuild_shouldReturnTrue() {
|
||||
SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, ENG_BUILD);
|
||||
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_trueShowFlagWithUserBuild_shouldReturnFalse() {
|
||||
SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USER_BUILD);
|
||||
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "mcc999")
|
||||
public void isAvailable_falseShowFlagWithUserdebugBuild_shouldReturnFalse() {
|
||||
SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD);
|
||||
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "mcc999")
|
||||
public void isAvailable_falseShowFlagWithEngBuild_shouldReturnFalse() {
|
||||
SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, ENG_BUILD);
|
||||
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "mcc999")
|
||||
public void isAvailable_falseShowFlagWithUserBuild_shouldReturnFalse() {
|
||||
SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USER_BUILD);
|
||||
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_connectivityMonitorEnabled_shouldCheckedPreference() {
|
||||
SystemProperties.set(ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR,
|
||||
ConnectivityMonitorPreferenceController.ENABLED_STATUS);
|
||||
SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setChecked(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_connectivityMonitorUserEnabled_shouldCheckedPreference() {
|
||||
SystemProperties.set(ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR,
|
||||
ConnectivityMonitorPreferenceController.USER_ENABLED_STATUS);
|
||||
SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setChecked(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_connectivityMonitorDisabled_shouldUncheckedPreference() {
|
||||
SystemProperties.set(ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR,
|
||||
ConnectivityMonitorPreferenceController.DISABLED_STATUS);
|
||||
SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setChecked(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_connectivityMonitorUserDisabled_shouldUncheckedPreference() {
|
||||
SystemProperties.set(ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR,
|
||||
ConnectivityMonitorPreferenceController.USER_DISABLED_STATUS);
|
||||
SystemProperties.set(ConnectivityMonitorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setChecked(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_preferenceChecked_shouldEnableConnectivityMonitor() {
|
||||
SystemProperties.set(
|
||||
ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR,
|
||||
ConnectivityMonitorPreferenceController.USER_ENABLED_STATUS);
|
||||
|
||||
mController.handlePreferenceTreeClick(mPreference);
|
||||
|
||||
assertThat(ConnectivityMonitorPreferenceController.USER_ENABLED_STATUS).isEqualTo(
|
||||
SystemProperties.get(
|
||||
ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR,
|
||||
ConnectivityMonitorPreferenceController.DISABLED_STATUS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_preferenceUnchecked_shouldDisableConnectivityMonitor() {
|
||||
SystemProperties.set(
|
||||
ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR,
|
||||
ConnectivityMonitorPreferenceController.USER_DISABLED_STATUS);
|
||||
|
||||
mController.handlePreferenceTreeClick(mPreference);
|
||||
|
||||
assertThat(ConnectivityMonitorPreferenceController.USER_DISABLED_STATUS).isEqualTo(
|
||||
SystemProperties.get(
|
||||
ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR,
|
||||
ConnectivityMonitorPreferenceController.DISABLED_STATUS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() {
|
||||
mController.onDeveloperOptionsSwitchDisabled();
|
||||
|
||||
String mode = SystemProperties.get(
|
||||
ConnectivityMonitorPreferenceController.PROPERTY_CONNECTIVITY_MONITOR,
|
||||
null /* default */);
|
||||
|
||||
assertThat(mode).isEqualTo(ConnectivityMonitorPreferenceController.USER_DISABLED_STATUS);
|
||||
verify(mPreference).setEnabled(false);
|
||||
verify(mPreference).setChecked(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package com.android.settings.display;
|
||||
|
||||
import static android.provider.Settings.Secure.THEME_MODE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.support.v7.preference.ListPreference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class SystemUiThemePreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
@Mock
|
||||
private ListPreference mListPreference;
|
||||
private Context mContext;
|
||||
private SystemUiThemePreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
when(mPreferenceScreen.findPreference(anyString())).thenReturn(mListPreference);
|
||||
CharSequence[] entries = mContext.getResources().getStringArray(
|
||||
R.array.systemui_theme_entries);
|
||||
when(mListPreference.getEntries()).thenReturn(entries);
|
||||
mController = spy(new SystemUiThemePreferenceController(mContext, "systemui_theme"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_readsSetting() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), THEME_MODE, 2);
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
verify(mListPreference).setValue(eq("2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_writesSetting() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), THEME_MODE, 2);
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mController.onPreferenceChange(mListPreference, "0");
|
||||
int value = Settings.Secure.getInt(mContext.getContentResolver(), THEME_MODE, 2);
|
||||
assertThat(value).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_updatesSummary() {
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mController.onPreferenceChange(mListPreference, "0");
|
||||
verify(mController).getSummary();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,17 +21,13 @@ import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import android.arch.lifecycle.LifecycleOwner;
|
||||
import android.content.Context;
|
||||
import android.os.PowerManager;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.widget.TwoStateButtonPreference;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -41,6 +37,7 @@ import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowPowerManager;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(shadows = ShadowPowerManager.class)
|
||||
@@ -48,67 +45,58 @@ public class BatterySaverButtonPreferenceControllerTest {
|
||||
|
||||
private BatterySaverButtonPreferenceController mController;
|
||||
private Context mContext;
|
||||
private Lifecycle mLifecycle;
|
||||
private LifecycleOwner mLifecycleOwner;
|
||||
private Button mButtonOn;
|
||||
private Button mButtonOff;
|
||||
private PowerManager mPowerManager;
|
||||
@Mock
|
||||
private TwoStateButtonPreference mPreference;
|
||||
|
||||
@Mock
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mLifecycleOwner = () -> mLifecycle;
|
||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mButtonOn = new Button(mContext);
|
||||
mButtonOff = new Button(mContext);
|
||||
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
||||
mPreference = spy(new TwoStateButtonPreference(mContext, null /* AttributeSet */));
|
||||
ReflectionHelpers.setField(mPreference, "mButtonOn", mButtonOn);
|
||||
ReflectionHelpers.setField(mPreference, "mButtonOff", mButtonOff);
|
||||
doReturn(mPreference).when(mPreferenceScreen).findPreference(anyString());
|
||||
|
||||
mButtonOn = new Button(mContext);
|
||||
mButtonOn.setId(R.id.state_on_button);
|
||||
doReturn(mButtonOn).when(mPreference).getStateOnButton();
|
||||
mButtonOff = new Button(mContext);
|
||||
mButtonOff.setId(R.id.state_off_button);
|
||||
doReturn(mButtonOff).when(mPreference).getStateOffButton();
|
||||
|
||||
mController = new BatterySaverButtonPreferenceController(mContext, mLifecycle);
|
||||
mController = new BatterySaverButtonPreferenceController(mContext, "test_key");
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_lowPowerOn_displayButtonOff() {
|
||||
public void updateState_lowPowerOn_preferenceIsChecked() {
|
||||
mPowerManager.setPowerSaveMode(true);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mButtonOn.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(mButtonOff.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(mPreference.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_lowPowerOff_displayButtonOn() {
|
||||
public void testUpdateState_lowPowerOff_preferenceIsUnchecked() {
|
||||
mPowerManager.setPowerSaveMode(false);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mButtonOn.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(mButtonOff.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(mPreference.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClick_clickButtonOn_setPowerSaveMode() {
|
||||
mController.onClick(mButtonOn);
|
||||
public void setChecked_on_setPowerSaveMode() {
|
||||
mController.setChecked(true);
|
||||
|
||||
assertThat(mPowerManager.isPowerSaveMode()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClick_clickButtonOff_clearPowerSaveMode() {
|
||||
mController.onClick(mButtonOff);
|
||||
public void setChecked_off_unsetPowerSaveMode() {
|
||||
mController.setChecked(false);
|
||||
|
||||
assertThat(mPowerManager.isPowerSaveMode()).isFalse();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.android.settings.location;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.support.v4.graphics.drawable.IconCompat;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.SliceTester;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceItem;
|
||||
import androidx.slice.SliceMetadata;
|
||||
import androidx.slice.SliceProvider;
|
||||
import androidx.slice.core.SliceAction;
|
||||
import androidx.slice.widget.SliceLiveData;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class LocationSliceBuilderTest {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
|
||||
// Prevent crash in SliceMetadata.
|
||||
Resources resources = spy(mContext.getResources());
|
||||
doReturn(60).when(resources).getDimensionPixelSize(anyInt());
|
||||
doReturn(resources).when(mContext).getResources();
|
||||
|
||||
// Set-up specs for SliceMetadata.
|
||||
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLocationSlice_correctSliceContent() {
|
||||
final Slice LocationSlice = LocationSliceBuilder.getSlice(mContext);
|
||||
final SliceMetadata metadata = SliceMetadata.from(mContext, LocationSlice);
|
||||
|
||||
final List<SliceAction> toggles = metadata.getToggles();
|
||||
assertThat(toggles).isEmpty();
|
||||
|
||||
final SliceAction primaryAction = metadata.getPrimaryAction();
|
||||
final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext,
|
||||
R.drawable.ic_signal_location);
|
||||
assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString());
|
||||
|
||||
final List<SliceItem> sliceItems = LocationSlice.getItems();
|
||||
SliceTester.assertTitle(sliceItems, mContext.getString(R.string.location_settings_title));
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.job.JobScheduler;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
@@ -76,4 +77,51 @@ public class DeviceIndexFeatureProviderTest {
|
||||
mProvider.updateIndex(mActivity, false);
|
||||
verify(jobScheduler).schedule(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateIndex_enabled_provisioned_newBuild_shouldIndex() {
|
||||
Settings.Global.putInt(mActivity.getContentResolver(),
|
||||
Settings.Global.DEVICE_PROVISIONED, 1);
|
||||
DeviceIndexFeatureProvider.setIndexState(mActivity);
|
||||
Settings.Global.putString(mActivity.getContentResolver(),
|
||||
DeviceIndexFeatureProvider.INDEX_VERSION, "new version");
|
||||
Settings.Global.putString(mActivity.getContentResolver(),
|
||||
DeviceIndexFeatureProvider.LANGUAGE.toString(),
|
||||
DeviceIndexFeatureProvider.INDEX_LANGUAGE);
|
||||
JobScheduler jobScheduler = mock(JobScheduler.class);
|
||||
when(mProvider.isIndexingEnabled()).thenReturn(true);
|
||||
when(mActivity.getSystemService(JobScheduler.class)).thenReturn(jobScheduler);
|
||||
|
||||
mProvider.updateIndex(mActivity, false);
|
||||
verify(jobScheduler).schedule(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateIndex_enabled_provisioned_newIndex_shouldIndex() {
|
||||
Settings.Global.putInt(mActivity.getContentResolver(),
|
||||
Settings.Global.DEVICE_PROVISIONED, 1);
|
||||
DeviceIndexFeatureProvider.setIndexState(mActivity);
|
||||
Settings.Global.putString(mActivity.getContentResolver(),
|
||||
DeviceIndexFeatureProvider.INDEX_LANGUAGE, "new language");
|
||||
JobScheduler jobScheduler = mock(JobScheduler.class);
|
||||
when(mProvider.isIndexingEnabled()).thenReturn(true);
|
||||
when(mActivity.getSystemService(JobScheduler.class)).thenReturn(jobScheduler);
|
||||
|
||||
mProvider.updateIndex(mActivity, false);
|
||||
verify(jobScheduler).schedule(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateIndex_enabled_provisioned_sameBuild_sameLang_shouldNotIndex() {
|
||||
Settings.Global.putInt(mActivity.getContentResolver(),
|
||||
Settings.Global.DEVICE_PROVISIONED, 1);
|
||||
DeviceIndexFeatureProvider.setIndexState(mActivity);
|
||||
JobScheduler jobScheduler = mock(JobScheduler.class);
|
||||
when(mProvider.isIndexingEnabled()).thenReturn(true);
|
||||
when(mActivity.getSystemService(JobScheduler.class)).thenReturn(jobScheduler);
|
||||
|
||||
mProvider.updateIndex(mActivity, false);
|
||||
|
||||
verify(mProvider, never()).index(any(), any(), any(), any(), any());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +124,7 @@ public class DeviceIndexUpdateJobServiceTest {
|
||||
|
||||
DeviceIndexFeatureProvider indexFeatureProvider = FakeFeatureFactory.getFactory(mActivity)
|
||||
.getDeviceIndexFeatureProvider();
|
||||
verify(indexFeatureProvider).clearIndex(any());
|
||||
verify(indexFeatureProvider, times(1)).index(any(), any(), any(), any(), any());
|
||||
}
|
||||
|
||||
|
||||
@@ -22,19 +22,23 @@ import static android.content.ContentResolver.SCHEME_CONTENT;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.slice.SliceManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.os.StrictMode;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import com.android.settings.location.LocationSliceBuilder;
|
||||
import com.android.settings.wifi.WifiSliceBuilder;
|
||||
import com.android.settings.bluetooth.BluetoothSliceBuilder;
|
||||
import com.android.settings.notification.ZenModeSliceBuilder;
|
||||
@@ -54,6 +58,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
|
||||
@@ -81,7 +86,8 @@ public class SettingsSliceProviderTest {
|
||||
|
||||
private static final List<Uri> SPECIAL_CASE_PLATFORM_URIS = Arrays.asList(
|
||||
WifiSliceBuilder.WIFI_URI,
|
||||
BluetoothSliceBuilder.BLUETOOTH_URI
|
||||
BluetoothSliceBuilder.BLUETOOTH_URI,
|
||||
LocationSliceBuilder.LOCATION_URI
|
||||
);
|
||||
|
||||
private static final List<Uri> SPECIAL_CASE_OEM_URIS = Arrays.asList(
|
||||
@@ -189,6 +195,24 @@ public class SettingsSliceProviderTest {
|
||||
assertThat(newThreadPolicy.toString()).isEqualTo(oldThreadPolicy.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindSlice_requestsBlockedSlice_retunsNull() {
|
||||
final String blockedKey = "blocked_key";
|
||||
final Set<String> blockedSet = new ArraySet<>();
|
||||
blockedSet.add(blockedKey);
|
||||
doReturn(blockedSet).when(mProvider).getBlockedKeys();
|
||||
final Uri blockedUri = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath(blockedKey)
|
||||
.build();
|
||||
|
||||
final Slice slice = mProvider.onBindSlice(blockedUri);
|
||||
|
||||
assertThat(slice).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadSlice_cachedEntryRemovedOnUnpin() {
|
||||
SliceData data = getDummyData();
|
||||
@@ -401,6 +425,18 @@ public class SettingsSliceProviderTest {
|
||||
assertThat(wifiSlice.getUri()).isEqualTo(WifiSliceBuilder.WIFI_URI);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onSlicePinned_noIntentRegistered_specialCaseUri_doesNotCrash() {
|
||||
final Uri uri = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsSlicesContract.AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath(SettingsSlicesContract.KEY_LOCATION)
|
||||
.build();
|
||||
|
||||
mProvider.onSlicePinned(uri);
|
||||
}
|
||||
|
||||
private void insertSpecialCase(String key) {
|
||||
insertSpecialCase(key, true);
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@ public class SliceBuilderUtilsTest {
|
||||
|
||||
final Slice slice = SliceBuilderUtils.buildSlice(mContext, data);
|
||||
|
||||
SliceTester.testSettingsUnavailableSlice(mContext, slice, data);
|
||||
assertThat(slice).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -349,7 +349,7 @@ public class SliceBuilderUtilsTest {
|
||||
|
||||
final Slice slice = SliceBuilderUtils.buildSlice(mContext, data);
|
||||
|
||||
SliceTester.testSettingsUnavailableSlice(mContext, slice, data);
|
||||
assertThat(slice).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -394,7 +394,7 @@ public class SliceBuilderUtilsTest {
|
||||
.isEqualTo(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME);
|
||||
assertThat(capturedLoggingPair.second)
|
||||
.isEqualTo(data.getKey());
|
||||
SliceTester.testSettingsUnavailableSlice(mContext, slice, data);
|
||||
assertThat(slice).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -408,16 +408,6 @@ public class SliceBuilderUtilsTest {
|
||||
assertThat(intentData).isEqualTo(expectedUri);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSettingsIntent_createsIntentToSettings() {
|
||||
final Intent intent = new Intent(Settings.ACTION_SETTINGS);
|
||||
final PendingIntent expectedIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
|
||||
|
||||
final PendingIntent settingsIntent = SliceBuilderUtils.getSettingsIntent(mContext);
|
||||
|
||||
assertThat(expectedIntent).isEqualTo(settingsIntent);
|
||||
}
|
||||
|
||||
private SliceData getDummyData() {
|
||||
return getDummyData(TOGGLE_CONTROLLER, SUMMARY, SliceData.SliceType.SWITCH, SCREEN_TITLE);
|
||||
}
|
||||
|
||||
@@ -150,14 +150,17 @@ public class SliceTester {
|
||||
final int color = colorItem.getInt();
|
||||
assertThat(color).isEqualTo(Utils.getColorAccent(context));
|
||||
|
||||
final IconCompat expectedToggleIcon = IconCompat.createWithResource(context,
|
||||
final SliceAction primaryAction = metadata.getPrimaryAction();
|
||||
|
||||
final IconCompat expectedIcon = IconCompat.createWithResource(context,
|
||||
sliceData.getIconResource());
|
||||
assertThat(expectedIcon.toString()).isEqualTo(primaryAction.getIcon().toString());
|
||||
|
||||
final long sliceTTL = metadata.getExpiry();
|
||||
assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY);
|
||||
|
||||
// Check primary intent
|
||||
final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction();
|
||||
final PendingIntent primaryPendingIntent = primaryAction.getAction();
|
||||
assertThat(primaryPendingIntent).isEqualTo(
|
||||
SliceBuilderUtils.getContentPendingIntent(context, sliceData));
|
||||
|
||||
@@ -191,20 +194,8 @@ public class SliceTester {
|
||||
assertThat(toggles).isEmpty();
|
||||
|
||||
final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction();
|
||||
final int availabilityStatus = SliceBuilderUtils.getPreferenceController(context,
|
||||
sliceData).getAvailabilityStatus();
|
||||
switch (availabilityStatus) {
|
||||
case UNSUPPORTED_ON_DEVICE:
|
||||
case CONDITIONALLY_UNAVAILABLE:
|
||||
assertThat(primaryPendingIntent).isEqualTo(
|
||||
SliceBuilderUtils.getSettingsIntent(context));
|
||||
break;
|
||||
case DISABLED_FOR_USER:
|
||||
case DISABLED_DEPENDENT_SETTING:
|
||||
assertThat(primaryPendingIntent).isEqualTo(
|
||||
SliceBuilderUtils.getContentPendingIntent(context, sliceData));
|
||||
break;
|
||||
}
|
||||
assertThat(primaryPendingIntent).isEqualTo(SliceBuilderUtils.getContentPendingIntent(
|
||||
context, sliceData));
|
||||
|
||||
final List<SliceItem> sliceItems = slice.getItems();
|
||||
assertTitle(sliceItems, sliceData.getTitle());
|
||||
|
||||
@@ -17,34 +17,27 @@
|
||||
package com.android.settings.widget;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class TwoStateButtonPreferenceControllerTest {
|
||||
public class TwoStateButtonPreferenceTest {
|
||||
|
||||
private static final String KEY = "pref_key";
|
||||
|
||||
@Mock
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
@Mock
|
||||
private TwoStateButtonPreference mPreference;
|
||||
private TwoStateButtonPreferenceController mController;
|
||||
private Context mContext;
|
||||
private Button mButtonOn;
|
||||
private Button mButtonOff;
|
||||
@@ -53,35 +46,34 @@ public class TwoStateButtonPreferenceControllerTest {
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
doReturn(mPreference).when(mPreferenceScreen).findPreference(anyString());
|
||||
mPreference = spy(new TwoStateButtonPreference(mContext, null /* AttributeSet */));
|
||||
mButtonOn = new Button(mContext);
|
||||
doReturn(mButtonOn).when(mPreference).getStateOnButton();
|
||||
mButtonOn.setId(R.id.state_on_button);
|
||||
mButtonOff = new Button(mContext);
|
||||
doReturn(mButtonOff).when(mPreference).getStateOffButton();
|
||||
|
||||
mController = new TestButtonsPreferenceController(mContext, KEY);
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mButtonOff.setId(R.id.state_off_button);
|
||||
ReflectionHelpers.setField(mPreference, "mButtonOn", mButtonOn);
|
||||
ReflectionHelpers.setField(mPreference, "mButtonOff", mButtonOff);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetButtonVisibility_stateOn_onlyShowButtonOn() {
|
||||
mController.setButtonVisibility(true /* stateOn */);
|
||||
|
||||
assertThat(mButtonOn.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(mButtonOff.getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetButtonVisibility_stateOff_onlyShowButtonOff() {
|
||||
mController.setButtonVisibility(false /* stateOn */);
|
||||
mPreference.setChecked(true /* stateOn */);
|
||||
|
||||
assertThat(mButtonOn.getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(mButtonOff.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetButtonVisibility_stateOff_onlyShowButtonOff() {
|
||||
mPreference.setChecked(false /* stateOn */);
|
||||
|
||||
assertThat(mButtonOn.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(mButtonOff.getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetButtonEnabled_enabled_buttonEnabled() {
|
||||
mController.setButtonEnabled(true /* enabled */);
|
||||
mPreference.setButtonEnabled(true /* enabled */);
|
||||
|
||||
assertThat(mButtonOn.isEnabled()).isTrue();
|
||||
assertThat(mButtonOff.isEnabled()).isTrue();
|
||||
@@ -89,30 +81,18 @@ public class TwoStateButtonPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void testSetButtonEnabled_disabled_buttonDisabled() {
|
||||
mController.setButtonEnabled(false /* enabled */);
|
||||
mPreference.setButtonEnabled(false /* enabled */);
|
||||
|
||||
assertThat(mButtonOn.isEnabled()).isFalse();
|
||||
assertThat(mButtonOff.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller to test methods in {@link TwoStateButtonPreferenceController}
|
||||
*/
|
||||
public static class TestButtonsPreferenceController
|
||||
extends TwoStateButtonPreferenceController {
|
||||
@Test
|
||||
public void onClick_shouldPropagateChangeToListener() {
|
||||
mPreference.onClick(mButtonOn);
|
||||
verify(mPreference).callChangeListener(true);
|
||||
|
||||
TestButtonsPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onButtonClicked(boolean stateOn) {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
mPreference.onClick(mButtonOff);
|
||||
verify(mPreference).callChangeListener(false);
|
||||
}
|
||||
}
|
||||
@@ -259,26 +259,13 @@ public class WifiConfigControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hiddenView_isDisabledWhenAppropriate() {
|
||||
View hiddenSpinner = mView.findViewById(R.id.hidden_settings);
|
||||
assertThat(hiddenSpinner.isEnabled()).isFalse();
|
||||
public void hiddenField_visibilityUpdatesCorrectly() {
|
||||
View hiddenField = mView.findViewById(R.id.hidden_settings_field);
|
||||
assertThat(hiddenField.getVisibility()).isEqualTo(View.GONE);
|
||||
|
||||
mController = new TestWifiConfigController(mConfigUiBase, mView, null /* accessPoint */,
|
||||
WifiConfigUiBase.MODE_CONNECT);
|
||||
assertThat(hiddenSpinner.isEnabled()).isTrue();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void hiddenSpinner_visibilityUpdatesCorrectly() {
|
||||
View hiddenSpinner = mView.findViewById(R.id.hidden_settings);
|
||||
assertThat(hiddenSpinner.isEnabled()).isFalse();
|
||||
assertThat(hiddenSpinner.getVisibility()).isEqualTo(View.GONE);
|
||||
|
||||
mController = new TestWifiConfigController(mConfigUiBase, mView, null /* accessPoint */,
|
||||
WifiConfigUiBase.MODE_CONNECT);
|
||||
assertThat(hiddenSpinner.isEnabled()).isTrue();
|
||||
assertThat(hiddenSpinner.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(hiddenField.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
public class TestWifiConfigController extends WifiConfigController {
|
||||
|
||||
@@ -26,7 +26,6 @@ import static org.mockito.Mockito.spy;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.wifi.WifiSliceBuilder;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.SliceTester;
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ public class WifiCallingSliceHelperTest {
|
||||
final Slice slice = mWfcSliceHelper.createWifiCallingSlice(mWfcURI);
|
||||
|
||||
testWifiCallingSettingsUnavailableSlice(slice, null,
|
||||
SliceBuilderUtils.getSettingsIntent(mContext));
|
||||
WifiCallingSliceHelper.getSettingsIntent(mContext));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -125,7 +125,7 @@ public class WifiCallingSliceHelperTest {
|
||||
|
||||
assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
|
||||
testWifiCallingSettingsUnavailableSlice(slice, null,
|
||||
SliceBuilderUtils.getSettingsIntent(mContext));
|
||||
WifiCallingSliceHelper.getSettingsIntent(mContext));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user