Snap for 4801384 from 2e0709b3b8 to pi-release

Change-Id: I5954c59bd42debb8cab1a6fa46c71bf5485cbc34
This commit is contained in:
android-build-team Robot
2018-05-24 07:27:58 +00:00
70 changed files with 1023 additions and 762 deletions

View File

@@ -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>

View File

@@ -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>

View 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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View 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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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"

View File

@@ -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>

View File

@@ -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>

View File

@@ -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] -->

View File

@@ -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>

View File

@@ -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" />

View File

@@ -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"

View File

@@ -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"/>

View File

@@ -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 -> {

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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 =

View File

@@ -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);
}
}

View File

@@ -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));

View File

@@ -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];
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}

View 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 */);
}
}

View File

@@ -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;
}
}

View File

@@ -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();

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;

View File

@@ -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());
}
}

View File

@@ -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.
}
}

View File

@@ -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;

View File

@@ -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
);
}

View File

@@ -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)

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 =

View File

@@ -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);
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.settings.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();
}
}

View File

@@ -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();
}

View File

@@ -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));
}
}

View File

@@ -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());
}
}

View File

@@ -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());
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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());

View File

@@ -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);
}
}

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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