Snap for 5392835 from f5d2552b7a to qt-release
Change-Id: I2b7e21b7e991f1117771c19b449482d7868b9c46
This commit is contained in:
@@ -965,7 +965,7 @@
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="homepage_about_background">#9FA8DA</color>"
|
||||
errorLine1=" <color name="homepage_about_background">#6F86DA</color>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
@@ -1309,6 +1309,230 @@
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="bt_color_icon_1">#48a50e0e</color> <!-- 72% Material Red 900 -->"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="144"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="bt_color_icon_2">#480d652d</color> <!-- 72% Material Green 900 -->"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="145"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="bt_color_icon_3">#48e37400</color> <!-- 72% Material Yellow 900 -->"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="146"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="bt_color_icon_4">#48b06000</color> <!-- 72% Material Orange 900 -->"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="147"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="bt_color_icon_5">#489c166b</color> <!-- 72% Material Pink 900 -->"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="148"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="bt_color_icon_6">#48681da8</color> <!-- 72% Material Purple 900 -->"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="149"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="bt_color_icon_7">#48007b83</color> <!-- 72% Material Cyan 900 -->"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="150"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="bt_color_bg_1">#fad2cf</color> <!-- Material Red 100 -->"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="152"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="bt_color_bg_2">#ceead6</color> <!-- Material Green 100 -->"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="153"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="bt_color_bg_3">#feefc3</color> <!-- Material Yellow 100 -->"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="154"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="bt_color_bg_4">#fedfc8</color> <!-- Material Orange 100 -->"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="155"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="bt_color_bg_5">#fdcfe8</color> <!-- Material Pink 100 -->"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="156"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="bt_color_bg_6">#e9d2fd</color> <!-- Material Purple 100 -->"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="157"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="bt_color_bg_7">#cbf0f8</color> <!-- Material Cyan 100 -->"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="158"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
@@ -2537,7 +2761,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/strings.xml"
|
||||
line="6026"
|
||||
line="6020"
|
||||
column="36"/>
|
||||
</issue>
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2018 The Android Open Source Project
|
||||
~
|
||||
@@ -15,9 +16,29 @@
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path android:fillColor="#000" android:pathData="M9,11.75A1.25,1.25 0 0,0 7.75,13A1.25,1.25 0 0,0 9,14.25A1.25,1.25 0 0,0 10.25,13A1.25,1.25 0 0,0 9,11.75M15,11.75A1.25,1.25 0 0,0 13.75,13A1.25,1.25 0 0,0 15,14.25A1.25,1.25 0 0,0 16.25,13A1.25,1.25 0 0,0 15,11.75M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20C7.59,20 4,16.41 4,12C4,11.71 4,11.42 4.05,11.14C6.41,10.09 8.28,8.16 9.26,5.77C11.07,8.33 14.05,10 17.42,10C18.2,10 18.95,9.91 19.67,9.74C19.88,10.45 20,11.21 20,12C20,16.41 16.41,20 12,20Z" />
|
||||
android:width="240dp"
|
||||
android:height="240dp"
|
||||
android:viewportWidth="300"
|
||||
android:viewportHeight="300">
|
||||
|
||||
<path
|
||||
android:fillColor="#DADCE0"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M150,0C67.16,0,0,67.16,0,150s67.16,150,150,150 s150-67.16,150-150S232.84,0,150,0 M150,4c39,0,75.66,15.19,103.24,42.76C280.81,74.34,296,111,296,150s-15.19,75.66-42.76,103.24 C225.66,280.81,189,296,150,296s-75.66-15.19-103.24-42.76C19.19,225.66,4,189,4,150S19.19,74.34,46.76,46.76 C74.34,19.19,111,4,150,4" />
|
||||
<path
|
||||
android:fillColor="?android:attr/colorAccent"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M220,120c0,5.52-4.48,10-10,10s-10-4.48-10-10 s4.48-10,10-10S220,114.48,220,120" />
|
||||
<path
|
||||
android:fillColor="?android:attr/colorAccent"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M90,130c-5.52,0-10-4.48-10-10s4.48-10,10-10 s10,4.48,10,10S95.52,130,90,130" />
|
||||
<path
|
||||
android:fillColor="?android:attr/colorAccent"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M164.2,215.88c-3.83,3.25-8.79,5.22-14.2,5.22 c-12.13,0-22-9.87-22-22c0-0.03,0-0.06,0-0.09l-8-0.03c0,0.04,0,0.08,0,0.13c0,6.24,1.9,12.03,5.16,16.83 c5.4,7.95,14.51,13.17,24.84,13.17c1.04,0,2.06-0.05,3.08-0.15c6.18-0.63,11.81-3.14,16.3-6.95L164.2,215.88z" />
|
||||
<path
|
||||
android:fillColor="?android:attr/colorAccent"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M 153 140 L 153 166 L 137 166 L 137 174 L 161 174 L 161 140 Z" />
|
||||
</vector>
|
||||
30
res/drawable/ic_face_enroll_introduction_detail.xml
Normal file
30
res/drawable/ic_face_enroll_introduction_detail.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2019 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:tint="?android:attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:pathData="M0 0h24v24H0V0z" />
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M11 15h2v2h-2zm0-8h2v6h-2zm0.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z" />
|
||||
</vector>
|
||||
@@ -2,7 +2,8 @@
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
android:viewportHeight="24"
|
||||
android:tint="?android:attr/colorAccent">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M7,4v3H4V4H7M9,2H2v7h7V2L9,2z"/>
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
android:viewportHeight="24"
|
||||
android:tint="?android:attr/colorAccent">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M9,2l-7,0l0,2l7,0l0,-2z"/>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<LinearLayout
|
||||
style="@style/SudContentFrame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
@@ -45,50 +45,87 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.google.android.setupdesign.view.FillContentLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
|
||||
<com.google.android.setupdesign.view.IllustrationVideoView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/face_enroll_introduction_animation"
|
||||
style="@style/SudContentIllustration"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:sudVideo="@raw/face_enroll_introduction_animation" />
|
||||
|
||||
</com.google.android.setupdesign.view.FillContentLayout>
|
||||
<Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center">
|
||||
<Button
|
||||
android:id="@+id/accessibility_button"
|
||||
style="@style/SudGlifButton.Secondary"
|
||||
android:layout_gravity="center"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.setupdesign.view.IllustrationVideoView
|
||||
android:id="@+id/illustration_normal"
|
||||
style="@style/SudContentIllustration"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="240dp"
|
||||
app:sudVideo="@raw/face_enroll_introduction_animation" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/illustration_accessibility"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/security_settings_face_enroll_introduction_accessibility" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:id="@+id/accessibility_layout"
|
||||
android:orientation="vertical"
|
||||
android:visibility="invisible">
|
||||
android:visibility="invisible"
|
||||
android:background="@drawable/face_enroll_introduction" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="2"/>
|
||||
|
||||
<!-- Contains the buttons and extra information text at the bottom -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_gravity="center_horizontal|bottom">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<Button
|
||||
android:id="@+id/accessibility_button"
|
||||
style="@style/SudGlifButton.Secondary"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/security_settings_face_enroll_introduction_accessibility" />
|
||||
|
||||
<com.android.settings.biometrics.face.FaceEnrollAccessibilityToggle
|
||||
android:id="@+id/toggle_diversity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible"
|
||||
FaceEnrollAccessibilitySwitch:messageText="@string/security_settings_face_enroll_introduction_accessibility_diversity"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/footer_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ic_face_enroll_introduction_detail">
|
||||
</ImageView>
|
||||
<Space
|
||||
android:layout_width="8dp"
|
||||
android:layout_height="wrap_content" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/security_settings_face_enroll_introduction_footer_message"/>
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -25,14 +25,12 @@
|
||||
<TextView
|
||||
android:id="@+id/network_request_title_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingTop="18dp"
|
||||
android:layout_weight="1"
|
||||
android:textSize="18sp"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
style="@style/info_label"/>
|
||||
|
||||
<ProgressBar
|
||||
|
||||
@@ -22,5 +22,4 @@
|
||||
android:minWidth="@dimen/min_tap_target_size"
|
||||
android:minHeight="@dimen/min_tap_target_size"
|
||||
android:layout_gravity="center"
|
||||
android:background="@null"
|
||||
android:visibility="gone"/>
|
||||
android:background="?android:attr/selectableItemBackground"/>
|
||||
|
||||
@@ -50,29 +50,31 @@
|
||||
android:text="@string/wifi_ssid"
|
||||
android:textDirection="locale" />
|
||||
|
||||
<RelativeLayout
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
android:layout_height="wrap_content">
|
||||
<EditText android:id="@+id/ssid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/ssid_scanner_button"
|
||||
style="@style/wifi_item_edit_content"
|
||||
android:hint="@string/wifi_ssid_hint"
|
||||
android:singleLine="true"
|
||||
android:inputType="textNoSuggestions" />
|
||||
android:inputType="textNoSuggestions"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/ssid_scanner_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="@dimen/min_tap_target_size"
|
||||
android:minHeight="@dimen/min_tap_target_size"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:background="@null"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:src="@drawable/ic_scan_24dp"
|
||||
android:contentDescription="@string/wifi_dpp_scan_qr_code"/>
|
||||
</RelativeLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<LinearLayout android:id="@+id/ssid_too_long_warning"
|
||||
android:layout_width="match_parent"
|
||||
@@ -286,16 +288,18 @@
|
||||
style="@style/wifi_item_label"
|
||||
android:text="@string/wifi_password" />
|
||||
|
||||
<RelativeLayout
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
android:layout_height="wrap_content">
|
||||
<EditText android:id="@+id/password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/password_scanner_button"
|
||||
style="@style/wifi_item_edit_content"
|
||||
android:singleLine="true"
|
||||
android:password="true" />
|
||||
android:password="true"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/password_scanner_button"
|
||||
@@ -303,12 +307,11 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="@dimen/min_tap_target_size"
|
||||
android:minHeight="@dimen/min_tap_target_size"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:background="@null"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:src="@drawable/ic_scan_24dp"
|
||||
android:contentDescription="@string/wifi_dpp_scan_qr_code"/>
|
||||
</RelativeLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout android:id="@+id/show_password_layout"
|
||||
|
||||
@@ -22,28 +22,24 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ScrollView
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="0dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/footer">
|
||||
|
||||
<LinearLayout
|
||||
<include layout="@layout/wifi_dpp_fragment_header"/>
|
||||
|
||||
<LinearLayout android:id="@+id/wifi_network_list_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<include layout="@layout/wifi_dpp_fragment_header"/>
|
||||
|
||||
<LinearLayout android:id="@+id/wifi_network_list_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@+id/header"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/footer"
|
||||
layout="@layout/wifi_dpp_fragment_footer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -1378,4 +1378,25 @@
|
||||
<item>@string/wifi_calling_mode_cellular_preferred_summary</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Bluetooth icon foreground colors -->
|
||||
<integer-array name="bt_icon_fg_colors">
|
||||
<item>@color/bt_color_icon_1</item>
|
||||
<item>@color/bt_color_icon_2</item>
|
||||
<item>@color/bt_color_icon_3</item>
|
||||
<item>@color/bt_color_icon_4</item>
|
||||
<item>@color/bt_color_icon_5</item>
|
||||
<item>@color/bt_color_icon_6</item>
|
||||
<item>@color/bt_color_icon_7</item>
|
||||
</integer-array>
|
||||
|
||||
<!-- Bluetooth icon background colors -->
|
||||
<integer-array name="bt_icon_bg_colors">
|
||||
<item>@color/bt_color_bg_1</item>
|
||||
<item>@color/bt_color_bg_2</item>
|
||||
<item>@color/bt_color_bg_3</item>
|
||||
<item>@color/bt_color_bg_4</item>
|
||||
<item>@color/bt_color_bg_5</item>
|
||||
<item>@color/bt_color_bg_6</item>
|
||||
<item>@color/bt_color_bg_7</item>
|
||||
</integer-array>
|
||||
</resources>
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
<color name="homepage_support_background">#26459C</color>
|
||||
<color name="homepage_generic_icon_background">#1A73E8</color>
|
||||
<color name="homepage_location_background">#2EC7DC</color>
|
||||
<color name="homepage_about_background">#9FA8DA</color>
|
||||
<color name="homepage_about_background">#6F86DA</color>
|
||||
<color name="homepage_privacy_background">#5E97F6</color>
|
||||
|
||||
<color name="homepage_card_stroke_color">#1f000000</color>
|
||||
@@ -140,4 +140,20 @@
|
||||
<color name="qr_focused_corner_line_color">#ff1a73e8</color>
|
||||
<color name="qr_background_color">#b3ffffff</color> <!-- 70% white transparency -->
|
||||
<!-- End of QR code scanner colors -->
|
||||
|
||||
<color name="bt_color_icon_1">#48a50e0e</color> <!-- 72% Material Red 900 -->
|
||||
<color name="bt_color_icon_2">#480d652d</color> <!-- 72% Material Green 900 -->
|
||||
<color name="bt_color_icon_3">#48e37400</color> <!-- 72% Material Yellow 900 -->
|
||||
<color name="bt_color_icon_4">#48b06000</color> <!-- 72% Material Orange 900 -->
|
||||
<color name="bt_color_icon_5">#489c166b</color> <!-- 72% Material Pink 900 -->
|
||||
<color name="bt_color_icon_6">#48681da8</color> <!-- 72% Material Purple 900 -->
|
||||
<color name="bt_color_icon_7">#48007b83</color> <!-- 72% Material Cyan 900 -->
|
||||
|
||||
<color name="bt_color_bg_1">#fad2cf</color> <!-- Material Red 100 -->
|
||||
<color name="bt_color_bg_2">#ceead6</color> <!-- Material Green 100 -->
|
||||
<color name="bt_color_bg_3">#feefc3</color> <!-- Material Yellow 100 -->
|
||||
<color name="bt_color_bg_4">#fedfc8</color> <!-- Material Orange 100 -->
|
||||
<color name="bt_color_bg_5">#fdcfe8</color> <!-- Material Pink 100 -->
|
||||
<color name="bt_color_bg_6">#e9d2fd</color> <!-- Material Purple 100 -->
|
||||
<color name="bt_color_bg_7">#cbf0f8</color> <!-- Material Cyan 100 -->
|
||||
</resources>
|
||||
@@ -898,8 +898,10 @@
|
||||
<string name="security_settings_face_enroll_introduction_message">Use your face to unlock your phone, authorize purchases, or sign in to apps.</string>
|
||||
<!-- Introduction detail message shown in face enrollment dialog, when face unlock is disabled by device admin [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_face_enroll_introduction_message_unlock_disabled">Use your face to unlock your phone or approve purchases.\n\nNote: You can\u2019t use your face to unlock this device. For more information, contact your organization\u2019s admin.</string>
|
||||
<!-- Introduction detail message shwon in face enrollment screen in setup wizard. [CHAR LIMIT=NONE] -->
|
||||
<!-- Introduction detail message shown in face enrollment screen in setup wizard. [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_face_enroll_introduction_message_setup">Use your face to unlock your phone, authorize purchases, or sign in to apps</string>
|
||||
<!-- Introduction detail message shown in face enrollment that provides extra detais. [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_face_enroll_introduction_footer_message"></string>
|
||||
<!-- Title shown in face enrollment dialog [CHAR LIMIT=40] -->
|
||||
<string name="security_settings_face_enroll_repeat_title">Center your face in the circle</string>
|
||||
<!-- Button text to skip enrollment of face [CHAR LIMIT=40] -->
|
||||
@@ -941,6 +943,11 @@
|
||||
<!-- Text shown in face settings explaining what your face can be used for. [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_face_settings_footer">Your face can be used to unlock your device and access apps.
|
||||
<annotation id="url">Learn more</annotation></string>
|
||||
<!-- Dialog title shown when the user removes an enrollment [CHAR LIMIT=35] -->
|
||||
<string name="security_settings_face_settings_remove_dialog_title">Delete face data?</string>
|
||||
<!-- Dialog contents shown when the user removes an enrollment [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_face_settings_remove_dialog_details">Data recorded by face unlock will be permanently and securely deleted. After removal, you will need your PIN, pattern, or password to unlock your phone, sign in to apps, and confirm payments.</string>
|
||||
|
||||
|
||||
<!-- Fingerprint enrollment and settings --><skip />
|
||||
<!-- Title shown for menu item that launches fingerprint settings or enrollment [CHAR LIMIT=22] -->
|
||||
@@ -2235,6 +2242,8 @@
|
||||
<string name="wifi_disconnect">@string/bluetooth_device_context_disconnect</string>
|
||||
<!-- Failured notification for connect -->
|
||||
<string name="wifi_failed_connect_message">Failed to connect to network</string>
|
||||
<!-- Not in range notification for connect [CHAR LIMIT=40] -->
|
||||
<string name="wifi_not_in_range_message">Network not in range</string>
|
||||
<!-- Button label to delete a Wi-Fi network -->
|
||||
<string name="wifi_forget">Forget</string>
|
||||
<!-- Button label to modify a Wi-Fi network -->
|
||||
@@ -7050,7 +7059,7 @@
|
||||
handle actions such as open web page, making phone calls, default SMS apps [CHAR LIMIT=40]-->
|
||||
<string name="app_default_dashboard_title">Default apps</string>
|
||||
<!-- Summary text for system preference tile, showing important setting items under system setting [CHAR LIMIT=NONE]-->
|
||||
<string name="system_dashboard_summary">Languages, time, backup, updates</string>
|
||||
<string name="system_dashboard_summary">Languages, gestures, time, backup</string>
|
||||
|
||||
<!-- Search strings -->
|
||||
<!-- Text to describe the search results fragment title [CHAR LIMIT=16] -->
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
@@ -68,4 +69,12 @@ public class FaceEnrollAccessibilityToggle extends LinearLayout {
|
||||
public void setChecked(boolean checked) {
|
||||
mSwitch.setChecked(checked);
|
||||
}
|
||||
|
||||
public void setListener(CompoundButton.OnCheckedChangeListener listener) {
|
||||
mSwitch.setOnCheckedChangeListener(listener);
|
||||
}
|
||||
|
||||
public Switch getSwitch() {
|
||||
return mSwitch;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
@@ -38,6 +38,7 @@ import com.google.android.setupcompat.template.FooterBarMixin;
|
||||
import com.google.android.setupcompat.template.FooterButton;
|
||||
import com.google.android.setupcompat.util.WizardManagerHelper;
|
||||
import com.google.android.setupdesign.span.LinkSpan;
|
||||
import com.google.android.setupdesign.view.IllustrationVideoView;
|
||||
|
||||
public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
|
||||
|
||||
@@ -46,19 +47,44 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
|
||||
private FaceManager mFaceManager;
|
||||
private FaceEnrollAccessibilityToggle mSwitchDiversity;
|
||||
|
||||
private IllustrationVideoView mIllustrationNormal;
|
||||
private View mIllustrationAccessibility;
|
||||
|
||||
private CompoundButton.OnCheckedChangeListener mSwitchDiversityListener =
|
||||
new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
if (isChecked) {
|
||||
mIllustrationNormal.stop();
|
||||
mIllustrationNormal.setVisibility(View.INVISIBLE);
|
||||
mIllustrationAccessibility.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mIllustrationNormal.setVisibility(View.VISIBLE);
|
||||
mIllustrationNormal.start();
|
||||
mIllustrationAccessibility.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mFaceManager = Utils.getFaceManagerOrNull(this);
|
||||
final LinearLayout accessibilityLayout = findViewById(R.id.accessibility_layout);
|
||||
final Button accessibilityButton = findViewById(R.id.accessibility_button);
|
||||
final View footerView = findViewById(R.id.footer_layout);
|
||||
accessibilityButton.setOnClickListener(view -> {
|
||||
mSwitchDiversity.setChecked(true);
|
||||
accessibilityButton.setVisibility(View.INVISIBLE);
|
||||
accessibilityLayout.setVisibility(View.VISIBLE);
|
||||
accessibilityButton.setVisibility(View.GONE);
|
||||
mSwitchDiversity.setVisibility(View.VISIBLE);
|
||||
footerView.setVisibility(View.GONE);
|
||||
});
|
||||
|
||||
mSwitchDiversity = findViewById(R.id.toggle_diversity);
|
||||
mSwitchDiversity.setListener(mSwitchDiversityListener);
|
||||
|
||||
mIllustrationNormal = findViewById(R.id.illustration_normal);
|
||||
mIllustrationAccessibility = findViewById(R.id.illustration_accessibility);
|
||||
|
||||
mFooterBarMixin = getLayout().getMixin(FooterBarMixin.class);
|
||||
if (WizardManagerHelper.isAnySetupWizard(getIntent())) {
|
||||
@@ -91,6 +117,13 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mSwitchDiversityListener.onCheckedChanged(mSwitchDiversity.getSwitch(),
|
||||
mSwitchDiversity.isChecked());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isDisabledByAdmin() {
|
||||
return RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
|
||||
@@ -114,7 +147,7 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
|
||||
|
||||
@Override
|
||||
protected int getDescriptionResDisabledByAdmin() {
|
||||
return R.string.security_settings_fingerprint_enroll_introduction_message_unlock_disabled;
|
||||
return R.string.security_settings_face_enroll_introduction_message_unlock_disabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.provider.SearchIndexableResource;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
@@ -56,6 +57,7 @@ public class FaceSettings extends DashboardFragment {
|
||||
private int mUserId;
|
||||
private byte[] mToken;
|
||||
private FaceSettingsAttentionPreferenceController mAttentionController;
|
||||
private FaceSettingsRemoveButtonPreferenceController mRemoveController;
|
||||
|
||||
private final FaceSettingsRemoveButtonPreferenceController.Listener mRemovalListener = () -> {
|
||||
if (getActivity() != null) {
|
||||
@@ -166,8 +168,9 @@ public class FaceSettings extends DashboardFragment {
|
||||
if (controller instanceof FaceSettingsAttentionPreferenceController) {
|
||||
mAttentionController = (FaceSettingsAttentionPreferenceController) controller;
|
||||
} else if (controller instanceof FaceSettingsRemoveButtonPreferenceController) {
|
||||
((FaceSettingsRemoveButtonPreferenceController) controller)
|
||||
.setListener(mRemovalListener);
|
||||
mRemoveController = (FaceSettingsRemoveButtonPreferenceController) controller;
|
||||
mRemoveController.setListener(mRemovalListener);
|
||||
mRemoveController.setActivity((SettingsActivity) getActivity());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,9 +16,14 @@
|
||||
|
||||
package com.android.settings.biometrics.face;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.hardware.face.Face;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
@@ -28,7 +33,9 @@ import android.widget.Toast;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settingslib.widget.LayoutPreference;
|
||||
|
||||
import java.util.List;
|
||||
@@ -43,6 +50,33 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference
|
||||
private static final String TAG = "FaceSettings/Remove";
|
||||
private static final String KEY = "security_settings_face_delete_faces_container";
|
||||
|
||||
public static class ConfirmRemoveDialog extends InstrumentedDialogFragment {
|
||||
|
||||
private DialogInterface.OnClickListener mOnClickListener;
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.DIALOG_FACE_REMOVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
|
||||
builder.setTitle(R.string.security_settings_face_settings_remove_dialog_title)
|
||||
.setMessage(R.string.security_settings_face_settings_remove_dialog_details)
|
||||
.setPositiveButton(R.string.okay, mOnClickListener)
|
||||
.setNegativeButton(R.string.cancel, mOnClickListener);
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.setCanceledOnTouchOutside(false);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public void setOnClickListener(DialogInterface.OnClickListener listener) {
|
||||
mOnClickListener = listener;
|
||||
}
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
void onRemoved();
|
||||
}
|
||||
@@ -50,6 +84,7 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference
|
||||
private Button mButton;
|
||||
private List<Face> mFaces;
|
||||
private Listener mListener;
|
||||
private SettingsActivity mActivity;
|
||||
|
||||
private final Context mContext;
|
||||
private final int mUserId;
|
||||
@@ -77,6 +112,27 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference
|
||||
}
|
||||
};
|
||||
|
||||
private final DialogInterface.OnClickListener mOnClickListener
|
||||
= new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (which == DialogInterface.BUTTON_POSITIVE) {
|
||||
if (mFaces.isEmpty()) {
|
||||
Log.e(TAG, "No faces");
|
||||
return;
|
||||
}
|
||||
if (mFaces.size() > 1) {
|
||||
Log.e(TAG, "Multiple enrollments: " + mFaces.size());
|
||||
}
|
||||
|
||||
// Remove the first/only face
|
||||
mFaceManager.remove(mFaces.get(0), mUserId, mRemovalCallback);
|
||||
} else {
|
||||
mButton.setEnabled(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public FaceSettingsRemoveButtonPreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mContext = context;
|
||||
@@ -115,20 +171,17 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference
|
||||
public void onClick(View v) {
|
||||
if (v == mButton) {
|
||||
mButton.setEnabled(false);
|
||||
if (mFaces.isEmpty()) {
|
||||
Log.e(TAG, "No faces");
|
||||
return;
|
||||
}
|
||||
if (mFaces.size() > 1) {
|
||||
Log.e(TAG, "Multiple enrollments: " + mFaces.size());
|
||||
}
|
||||
|
||||
// Remove the first/only face
|
||||
mFaceManager.remove(mFaces.get(0), mUserId, mRemovalCallback);
|
||||
ConfirmRemoveDialog dialog = new ConfirmRemoveDialog();
|
||||
dialog.setOnClickListener(mOnClickListener);
|
||||
dialog.show(mActivity.getSupportFragmentManager(), ConfirmRemoveDialog.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public void setListener(Listener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
public void setActivity(SettingsActivity activity) {
|
||||
mActivity = activity;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
@@ -66,10 +65,8 @@ public class BluetoothDetailsHeaderController extends BluetoothDetailsController
|
||||
}
|
||||
|
||||
protected void setHeaderProperties() {
|
||||
final Pair<Drawable, String> pair = BluetoothUtils
|
||||
.getBtClassDrawableWithDescription(mContext, mCachedDevice,
|
||||
mContext.getResources().getFraction(R.fraction.bt_battery_scale_fraction, 1,
|
||||
1));
|
||||
final Pair<Drawable, String> pair = Utils.getBtRainbowDrawableWithDescription(mContext,
|
||||
mCachedDevice);
|
||||
String summaryText = mCachedDevice.getConnectionSummary();
|
||||
// If both the hearing aids are connected, two device status should be shown.
|
||||
// If Second Summary is unavailable, to set it to null.
|
||||
|
||||
@@ -38,7 +38,6 @@ import androidx.preference.PreferenceViewHolder;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.widget.GearPreference;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
|
||||
@@ -130,8 +129,8 @@ public final class BluetoothDevicePreference extends GearPreference implements
|
||||
// Null check is done at the framework
|
||||
setSummary(mCachedDevice.getConnectionSummary());
|
||||
|
||||
final Pair<Drawable, String> pair = BluetoothUtils
|
||||
.getBtClassDrawableWithDescription(getContext(), mCachedDevice);
|
||||
final Pair<Drawable, String> pair = Utils
|
||||
.getBtRainbowDrawableWithDescription(getContext(), mCachedDevice);
|
||||
if (pair.first != null) {
|
||||
setIcon(pair.first);
|
||||
contentDescription = pair.second;
|
||||
@@ -246,5 +245,4 @@ public final class BluetoothDevicePreference extends GearPreference implements
|
||||
R.string.bluetooth_pairing_error_message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,8 +21,12 @@ import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
@@ -30,8 +34,10 @@ import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.widget.AdaptiveIcon;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils.ErrorListener;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager.BluetoothManagerCallback;
|
||||
|
||||
@@ -179,4 +185,25 @@ public final class Utils {
|
||||
return META_INT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get colorful bluetooth icon with description
|
||||
*/
|
||||
public static Pair<Drawable, String> getBtRainbowDrawableWithDescription(Context context,
|
||||
CachedBluetoothDevice cachedDevice) {
|
||||
final Pair<Drawable, String> pair = BluetoothUtils.getBtClassDrawableWithDescription(
|
||||
context, cachedDevice);
|
||||
final Resources resources = context.getResources();
|
||||
final int[] iconFgColors = resources.getIntArray(R.array.bt_icon_fg_colors);
|
||||
final int[] iconBgColors = resources.getIntArray(R.array.bt_icon_bg_colors);
|
||||
|
||||
// get color index based on mac address
|
||||
final int index = Math.abs(cachedDevice.getAddress().hashCode()) % iconBgColors.length;
|
||||
pair.first.setColorFilter(iconFgColors[index], PorterDuff.Mode.SRC_ATOP);
|
||||
final Drawable adaptiveIcon = new AdaptiveIcon(context, pair.first);
|
||||
((AdaptiveIcon) adaptiveIcon).setBackgroundColor(iconBgColors[index]);
|
||||
|
||||
return new Pair<>(adaptiveIcon, pair.second);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.dashboard.profileselector.ProfileSelectDialog;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.widget.AdaptiveHomepageIcon;
|
||||
import com.android.settings.widget.AdaptiveIcon;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.drawer.DashboardCategory;
|
||||
import com.android.settingslib.drawer.Tile;
|
||||
@@ -197,8 +197,8 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
|
||||
Drawable iconDrawable = tileIcon.loadDrawable(preference.getContext());
|
||||
if (forceRoundedIcon
|
||||
&& !TextUtils.equals(mContext.getPackageName(), tile.getPackageName())) {
|
||||
iconDrawable = new AdaptiveHomepageIcon(mContext, iconDrawable);
|
||||
((AdaptiveHomepageIcon) iconDrawable).setBackgroundColor(mContext, tile);
|
||||
iconDrawable = new AdaptiveIcon(mContext, iconDrawable);
|
||||
((AdaptiveIcon) iconDrawable).setBackgroundColor(mContext, tile);
|
||||
}
|
||||
preference.setIcon(iconDrawable);
|
||||
} else if (tile.getMetaData() != null
|
||||
|
||||
@@ -19,7 +19,7 @@ public class BatterySaverStickyPreferenceController extends BasePreferenceContro
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
int setting = Settings.System.getInt(mContext.getContentResolver(),
|
||||
int setting = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
LOW_POWER_STICKY_AUTO_DISABLE_ENABLED, 1);
|
||||
|
||||
((SwitchPreference) preference).setChecked(setting == 0);
|
||||
@@ -28,7 +28,7 @@ public class BatterySaverStickyPreferenceController extends BasePreferenceContro
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
boolean keepActive = (Boolean) newValue;
|
||||
Settings.System.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
LOW_POWER_STICKY_AUTO_DISABLE_ENABLED,
|
||||
keepActive ? 0 : 1);
|
||||
return true;
|
||||
|
||||
@@ -59,7 +59,7 @@ public class BatteryDatabaseManager {
|
||||
mDatabaseHelper = AnomalyDatabaseHelper.getInstance(context);
|
||||
}
|
||||
|
||||
public static BatteryDatabaseManager getInstance(Context context) {
|
||||
public static synchronized BatteryDatabaseManager getInstance(Context context) {
|
||||
if (sSingleton == null) {
|
||||
sSingleton = new BatteryDatabaseManager(context);
|
||||
}
|
||||
@@ -84,15 +84,15 @@ public class BatteryDatabaseManager {
|
||||
public synchronized boolean insertAnomaly(int uid, String packageName, int type,
|
||||
int anomalyState,
|
||||
long timestampMs) {
|
||||
try (SQLiteDatabase db = mDatabaseHelper.getWritableDatabase()) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(UID, uid);
|
||||
values.put(PACKAGE_NAME, packageName);
|
||||
values.put(ANOMALY_TYPE, type);
|
||||
values.put(ANOMALY_STATE, anomalyState);
|
||||
values.put(TIME_STAMP_MS, timestampMs);
|
||||
return db.insertWithOnConflict(TABLE_ANOMALY, null, values, CONFLICT_IGNORE) != -1;
|
||||
}
|
||||
final SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(UID, uid);
|
||||
values.put(PACKAGE_NAME, packageName);
|
||||
values.put(ANOMALY_TYPE, type);
|
||||
values.put(ANOMALY_STATE, anomalyState);
|
||||
values.put(TIME_STAMP_MS, timestampMs);
|
||||
|
||||
return db.insertWithOnConflict(TABLE_ANOMALY, null, values, CONFLICT_IGNORE) != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,43 +100,41 @@ public class BatteryDatabaseManager {
|
||||
*/
|
||||
public synchronized List<AppInfo> queryAllAnomalies(long timestampMsAfter, int state) {
|
||||
final List<AppInfo> appInfos = new ArrayList<>();
|
||||
try (SQLiteDatabase db = mDatabaseHelper.getReadableDatabase()) {
|
||||
final String[] projection = {PACKAGE_NAME, ANOMALY_TYPE, UID};
|
||||
final String orderBy = AnomalyDatabaseHelper.AnomalyColumns.TIME_STAMP_MS + " DESC";
|
||||
final Map<Integer, AppInfo.Builder> mAppInfoBuilders = new ArrayMap<>();
|
||||
final String selection = TIME_STAMP_MS + " > ? AND " + ANOMALY_STATE + " = ? ";
|
||||
final String[] selectionArgs = new String[]{String.valueOf(timestampMsAfter),
|
||||
String.valueOf(state)};
|
||||
final SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();
|
||||
final String[] projection = {PACKAGE_NAME, ANOMALY_TYPE, UID};
|
||||
final String orderBy = AnomalyDatabaseHelper.AnomalyColumns.TIME_STAMP_MS + " DESC";
|
||||
final Map<Integer, AppInfo.Builder> mAppInfoBuilders = new ArrayMap<>();
|
||||
final String selection = TIME_STAMP_MS + " > ? AND " + ANOMALY_STATE + " = ? ";
|
||||
final String[] selectionArgs = new String[]{String.valueOf(timestampMsAfter),
|
||||
String.valueOf(state)};
|
||||
|
||||
try (Cursor cursor = db.query(TABLE_ANOMALY, projection, selection, selectionArgs,
|
||||
null /* groupBy */, null /* having */, orderBy)) {
|
||||
while (cursor.moveToNext()) {
|
||||
final int uid = cursor.getInt(cursor.getColumnIndex(UID));
|
||||
if (!mAppInfoBuilders.containsKey(uid)) {
|
||||
final AppInfo.Builder builder = new AppInfo.Builder()
|
||||
.setUid(uid)
|
||||
.setPackageName(
|
||||
cursor.getString(cursor.getColumnIndex(PACKAGE_NAME)));
|
||||
mAppInfoBuilders.put(uid, builder);
|
||||
}
|
||||
mAppInfoBuilders.get(uid).addAnomalyType(
|
||||
cursor.getInt(cursor.getColumnIndex(ANOMALY_TYPE)));
|
||||
try (Cursor cursor = db.query(TABLE_ANOMALY, projection, selection, selectionArgs,
|
||||
null /* groupBy */, null /* having */, orderBy)) {
|
||||
while (cursor.moveToNext()) {
|
||||
final int uid = cursor.getInt(cursor.getColumnIndex(UID));
|
||||
if (!mAppInfoBuilders.containsKey(uid)) {
|
||||
final AppInfo.Builder builder = new AppInfo.Builder()
|
||||
.setUid(uid)
|
||||
.setPackageName(
|
||||
cursor.getString(cursor.getColumnIndex(PACKAGE_NAME)));
|
||||
mAppInfoBuilders.put(uid, builder);
|
||||
}
|
||||
mAppInfoBuilders.get(uid).addAnomalyType(
|
||||
cursor.getInt(cursor.getColumnIndex(ANOMALY_TYPE)));
|
||||
}
|
||||
}
|
||||
|
||||
for (Integer uid : mAppInfoBuilders.keySet()) {
|
||||
appInfos.add(mAppInfoBuilders.get(uid).build());
|
||||
}
|
||||
for (Integer uid : mAppInfoBuilders.keySet()) {
|
||||
appInfos.add(mAppInfoBuilders.get(uid).build());
|
||||
}
|
||||
|
||||
return appInfos;
|
||||
}
|
||||
|
||||
public synchronized void deleteAllAnomaliesBeforeTimeStamp(long timestampMs) {
|
||||
try (SQLiteDatabase db = mDatabaseHelper.getWritableDatabase()) {
|
||||
db.delete(TABLE_ANOMALY, TIME_STAMP_MS + " < ?",
|
||||
new String[]{String.valueOf(timestampMs)});
|
||||
}
|
||||
final SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
|
||||
db.delete(TABLE_ANOMALY, TIME_STAMP_MS + " < ?",
|
||||
new String[]{String.valueOf(timestampMs)});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,12 +150,12 @@ public class BatteryDatabaseManager {
|
||||
for (int i = 0; i < size; i++) {
|
||||
whereArgs[i] = appInfos.get(i).packageName;
|
||||
}
|
||||
try (SQLiteDatabase db = mDatabaseHelper.getWritableDatabase()) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(ANOMALY_STATE, state);
|
||||
db.update(TABLE_ANOMALY, values, PACKAGE_NAME + " IN (" + TextUtils.join(",",
|
||||
Collections.nCopies(appInfos.size(), "?")) + ")", whereArgs);
|
||||
}
|
||||
|
||||
final SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(ANOMALY_STATE, state);
|
||||
db.update(TABLE_ANOMALY, values, PACKAGE_NAME + " IN (" + TextUtils.join(",",
|
||||
Collections.nCopies(appInfos.size(), "?")) + ")", whereArgs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,21 +168,20 @@ public class BatteryDatabaseManager {
|
||||
public synchronized SparseLongArray queryActionTime(
|
||||
@AnomalyDatabaseHelper.ActionType int type) {
|
||||
final SparseLongArray timeStamps = new SparseLongArray();
|
||||
try (SQLiteDatabase db = mDatabaseHelper.getReadableDatabase()) {
|
||||
final String[] projection = {ActionColumns.UID, ActionColumns.TIME_STAMP_MS};
|
||||
final String selection = ActionColumns.ACTION_TYPE + " = ? ";
|
||||
final String[] selectionArgs = new String[]{String.valueOf(type)};
|
||||
final SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();
|
||||
final String[] projection = {ActionColumns.UID, ActionColumns.TIME_STAMP_MS};
|
||||
final String selection = ActionColumns.ACTION_TYPE + " = ? ";
|
||||
final String[] selectionArgs = new String[]{String.valueOf(type)};
|
||||
|
||||
try (Cursor cursor = db.query(TABLE_ACTION, projection, selection, selectionArgs,
|
||||
null /* groupBy */, null /* having */, null /* orderBy */)) {
|
||||
final int uidIndex = cursor.getColumnIndex(ActionColumns.UID);
|
||||
final int timestampIndex = cursor.getColumnIndex(ActionColumns.TIME_STAMP_MS);
|
||||
try (Cursor cursor = db.query(TABLE_ACTION, projection, selection, selectionArgs,
|
||||
null /* groupBy */, null /* having */, null /* orderBy */)) {
|
||||
final int uidIndex = cursor.getColumnIndex(ActionColumns.UID);
|
||||
final int timestampIndex = cursor.getColumnIndex(ActionColumns.TIME_STAMP_MS);
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
final int uid = cursor.getInt(uidIndex);
|
||||
final long timeStamp = cursor.getLong(timestampIndex);
|
||||
timeStamps.append(uid, timeStamp);
|
||||
}
|
||||
while (cursor.moveToNext()) {
|
||||
final int uid = cursor.getInt(uidIndex);
|
||||
final long timeStamp = cursor.getLong(timestampIndex);
|
||||
timeStamps.append(uid, timeStamp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,14 +193,14 @@ public class BatteryDatabaseManager {
|
||||
*/
|
||||
public synchronized boolean insertAction(@AnomalyDatabaseHelper.ActionType int type,
|
||||
int uid, String packageName, long timestampMs) {
|
||||
try (SQLiteDatabase db = mDatabaseHelper.getWritableDatabase()) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(ActionColumns.UID, uid);
|
||||
values.put(ActionColumns.PACKAGE_NAME, packageName);
|
||||
values.put(ActionColumns.ACTION_TYPE, type);
|
||||
values.put(ActionColumns.TIME_STAMP_MS, timestampMs);
|
||||
return db.insertWithOnConflict(TABLE_ACTION, null, values, CONFLICT_REPLACE) != -1;
|
||||
}
|
||||
final SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(ActionColumns.UID, uid);
|
||||
values.put(ActionColumns.PACKAGE_NAME, packageName);
|
||||
values.put(ActionColumns.ACTION_TYPE, type);
|
||||
values.put(ActionColumns.TIME_STAMP_MS, timestampMs);
|
||||
|
||||
return db.insertWithOnConflict(TABLE_ACTION, null, values, CONFLICT_REPLACE) != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,14 +208,13 @@ public class BatteryDatabaseManager {
|
||||
*/
|
||||
public synchronized boolean deleteAction(@AnomalyDatabaseHelper.ActionType int type,
|
||||
int uid, String packageName) {
|
||||
try (SQLiteDatabase db = mDatabaseHelper.getWritableDatabase()) {
|
||||
final String where =
|
||||
ActionColumns.ACTION_TYPE + " = ? AND " + ActionColumns.UID + " = ? AND "
|
||||
+ ActionColumns.PACKAGE_NAME + " = ? ";
|
||||
final String[] whereArgs = new String[]{String.valueOf(type), String.valueOf(uid),
|
||||
String.valueOf(packageName)};
|
||||
SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
|
||||
final String where =
|
||||
ActionColumns.ACTION_TYPE + " = ? AND " + ActionColumns.UID + " = ? AND "
|
||||
+ ActionColumns.PACKAGE_NAME + " = ? ";
|
||||
final String[] whereArgs = new String[]{String.valueOf(type), String.valueOf(uid),
|
||||
String.valueOf(packageName)};
|
||||
|
||||
return db.delete(TABLE_ACTION, where, whereArgs) != 0;
|
||||
}
|
||||
return db.delete(TABLE_ACTION, where, whereArgs) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ import com.android.settings.slices.CustomSliceRegistry;
|
||||
import com.android.settings.slices.CustomSliceable;
|
||||
import com.android.settings.slices.SliceBroadcastReceiver;
|
||||
import com.android.settings.slices.SliceBuilderUtils;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
|
||||
@@ -211,8 +210,9 @@ public class BluetoothDevicesSlice implements CustomSliceable {
|
||||
|
||||
@VisibleForTesting
|
||||
IconCompat getBluetoothDeviceIcon(CachedBluetoothDevice device) {
|
||||
final Pair<Drawable, String> pair = BluetoothUtils
|
||||
.getBtClassDrawableWithDescription(mContext, device);
|
||||
final Pair<Drawable, String> pair =
|
||||
com.android.settings.bluetooth.Utils.getBtRainbowDrawableWithDescription(mContext,
|
||||
device);
|
||||
final Drawable drawable = pair.first;
|
||||
|
||||
// Use default bluetooth icon if can't get icon.
|
||||
|
||||
@@ -104,7 +104,7 @@ public class RecentLocationAccessPreferenceController extends AbstractPreference
|
||||
.setOnClickListener((v) -> {
|
||||
final Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSION);
|
||||
intent.putExtra(Intent.EXTRA_PERMISSION_NAME,
|
||||
Manifest.permission_group.LOCATION);
|
||||
Manifest.permission.ACCESS_FINE_LOCATION);
|
||||
intent.putExtra(Intent.EXTRA_PACKAGE_NAME, access.packageName);
|
||||
intent.putExtra(Intent.EXTRA_USER, access.userHandle);
|
||||
mContext.startActivity(intent);
|
||||
|
||||
@@ -20,6 +20,8 @@ import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.accounts.AccountFeatureProvider;
|
||||
import com.android.settings.applications.ApplicationFeatureProvider;
|
||||
@@ -50,6 +52,7 @@ public abstract class FeatureFactory {
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
protected static FeatureFactory sFactory;
|
||||
protected static Context sAppContext;
|
||||
|
||||
/**
|
||||
* Returns a factory for creating feature controllers. Creates the factory if it does not
|
||||
@@ -60,6 +63,9 @@ public abstract class FeatureFactory {
|
||||
if (sFactory != null) {
|
||||
return sFactory;
|
||||
}
|
||||
if (sAppContext == null) {
|
||||
sAppContext = context.getApplicationContext();
|
||||
}
|
||||
|
||||
if (DEBUG) Log.d(LOG_TAG, "getFactory");
|
||||
final String clsName = context.getString(R.string.config_featureFactory);
|
||||
@@ -76,6 +82,16 @@ public abstract class FeatureFactory {
|
||||
return sFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an application {@link Context} used to create this {@link FeatureFactory}. If the
|
||||
* factory has not been properly created yet (aka {@link #getFactory} has not been called), this
|
||||
* will return null.
|
||||
*/
|
||||
@Nullable
|
||||
public static Context getAppContext() {
|
||||
return sAppContext;
|
||||
}
|
||||
|
||||
public abstract AssistGestureFeatureProvider getAssistGestureFeatureProvider();
|
||||
|
||||
public abstract SuggestionFeatureProvider getSuggestionFeatureProvider(Context context);
|
||||
|
||||
@@ -48,16 +48,11 @@ public class PanelFragment extends Fragment {
|
||||
private RecyclerView mPanelSlices;
|
||||
|
||||
private PanelContent mPanel;
|
||||
private final MetricsFeatureProvider mMetricsProvider;
|
||||
private MetricsFeatureProvider mMetricsProvider;
|
||||
|
||||
@VisibleForTesting
|
||||
PanelSlicesAdapter mAdapter;
|
||||
|
||||
public PanelFragment() {
|
||||
final Context context = getActivity();
|
||||
mMetricsProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@@ -83,6 +78,7 @@ public class PanelFragment extends Fragment {
|
||||
.getPanelFeatureProvider()
|
||||
.getPanel(activity, panelType, mediaPackageName);
|
||||
|
||||
mMetricsProvider = FeatureFactory.getFactory(activity).getMetricsFeatureProvider();
|
||||
// Log panel opened.
|
||||
mMetricsProvider.action(
|
||||
0 /* attribution */,
|
||||
|
||||
@@ -35,14 +35,15 @@ import com.android.settings.R;
|
||||
import com.android.settings.homepage.AdaptiveIconShapeDrawable;
|
||||
import com.android.settingslib.drawer.Tile;
|
||||
|
||||
public class AdaptiveHomepageIcon extends LayerDrawable {
|
||||
public class AdaptiveIcon extends LayerDrawable {
|
||||
|
||||
private static final String TAG = "AdaptiveHomepageIcon";
|
||||
|
||||
@VisibleForTesting(otherwise = NONE)
|
||||
int mBackgroundColor = -1;
|
||||
private AdaptiveConstantState mAdaptiveConstantState;
|
||||
|
||||
public AdaptiveHomepageIcon(Context context, Drawable foreground) {
|
||||
public AdaptiveIcon(Context context, Drawable foreground) {
|
||||
super(new Drawable[]{
|
||||
new AdaptiveIconShapeDrawable(context.getResources()),
|
||||
foreground
|
||||
@@ -50,6 +51,7 @@ public class AdaptiveHomepageIcon extends LayerDrawable {
|
||||
final int insetPx = context.getResources()
|
||||
.getDimensionPixelSize(R.dimen.dashboard_tile_foreground_image_inset);
|
||||
setLayerInset(1 /* index */, insetPx, insetPx, insetPx, insetPx);
|
||||
mAdaptiveConstantState = new AdaptiveConstantState(context, foreground);
|
||||
}
|
||||
|
||||
public void setBackgroundColor(Context context, Tile tile) {
|
||||
@@ -85,5 +87,36 @@ public class AdaptiveHomepageIcon extends LayerDrawable {
|
||||
mBackgroundColor = color;
|
||||
getDrawable(0).setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
|
||||
Log.d(TAG, "Setting background color " + mBackgroundColor);
|
||||
mAdaptiveConstantState.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstantState getConstantState() {
|
||||
return mAdaptiveConstantState;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class AdaptiveConstantState extends ConstantState {
|
||||
Context context;
|
||||
Drawable drawable;
|
||||
int color;
|
||||
|
||||
public AdaptiveConstantState(Context context, Drawable drawable) {
|
||||
this.context = context;
|
||||
this.drawable = drawable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable newDrawable() {
|
||||
final AdaptiveIcon icon = new AdaptiveIcon(context, drawable);
|
||||
icon.setBackgroundColor(color);
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChangingConfigurations() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
83
src/com/android/settings/wifi/AddWifiNetworkPreference.java
Normal file
83
src/com/android/settings/wifi/AddWifiNetworkPreference.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package com.android.settings.wifi;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageButton;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.wifi.dpp.WifiDppUtils;
|
||||
|
||||
/**
|
||||
* The Preference for users to add Wi-Fi networks in WifiSettings
|
||||
*/
|
||||
public class AddWifiNetworkPreference extends Preference {
|
||||
|
||||
private static final String TAG = "AddWifiNetworkPreference";
|
||||
|
||||
private boolean mInitialized;
|
||||
|
||||
public AddWifiNetworkPreference(Context context) {
|
||||
super(context);
|
||||
|
||||
setLayoutResource(com.android.settingslib.R.layout.preference_access_point);
|
||||
setWidgetLayoutResource(R.layout.wifi_button_preference_widget);
|
||||
setIcon(R.drawable.ic_menu_add);
|
||||
setTitle(R.string.wifi_add_network);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder holder) {
|
||||
super.onBindViewHolder(holder);
|
||||
|
||||
if (!mInitialized) {
|
||||
mInitialized = true;
|
||||
|
||||
final ImageButton imageButton = (ImageButton) holder.findViewById(R.id.button_icon);
|
||||
imageButton.setImageDrawable(getDrawable(R.drawable.ic_scan_24dp));
|
||||
imageButton.setContentDescription(
|
||||
getContext().getString(R.string.wifi_dpp_scan_qr_code));
|
||||
imageButton.setOnClickListener(view -> {
|
||||
getContext().startActivity(
|
||||
WifiDppUtils.getEnrolleeQrCodeScannerIntent(/* ssid */ null));
|
||||
});
|
||||
|
||||
final View divider = (View) holder.findViewById(
|
||||
com.android.settingslib.R.id.two_target_divider);
|
||||
divider.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private Drawable getDrawable(@DrawableRes int iconResId) {
|
||||
Drawable buttonIcon = null;
|
||||
|
||||
try {
|
||||
buttonIcon = getContext().getDrawable(iconResId);
|
||||
} catch (Resources.NotFoundException exception) {
|
||||
Log.e(TAG, "Resource does not exist: " + iconResId);
|
||||
}
|
||||
return buttonIcon;
|
||||
}
|
||||
}
|
||||
@@ -1,135 +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.wifi;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageButton;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
/**
|
||||
* This preference provides one button layout with Settings style.
|
||||
* It looks like below
|
||||
*
|
||||
* --------------------------------------------------------------
|
||||
* | icon | title | button |
|
||||
* --------------------------------------------------------------
|
||||
*
|
||||
* User can set icon / click listener for button.
|
||||
* By default, the button is invisible.
|
||||
*/
|
||||
public class ButtonPreference extends Preference {
|
||||
|
||||
private static final String TAG = "ButtonPreference";
|
||||
|
||||
private ImageButton mImageButton;
|
||||
private Drawable mButtonIcon;
|
||||
private View.OnClickListener mClickListener;
|
||||
private String mContentDescription;
|
||||
|
||||
// Used for dummy pref.
|
||||
public ButtonPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setWidgetLayoutResource(R.layout.wifi_button_preference_widget);
|
||||
mImageButton = null;
|
||||
mButtonIcon = null;
|
||||
mClickListener = null;
|
||||
mContentDescription = null;
|
||||
}
|
||||
|
||||
public ButtonPreference(Context context) {
|
||||
this(context, /* attrs */ null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final PreferenceViewHolder view) {
|
||||
super.onBindViewHolder(view);
|
||||
initButton(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrder(int order) {
|
||||
super.setOrder(order);
|
||||
setButtonVisibility();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected void initButton(final PreferenceViewHolder view) {
|
||||
if (mImageButton == null) {
|
||||
mImageButton = (ImageButton) view.findViewById(R.id.button_icon);
|
||||
}
|
||||
if (mImageButton != null) {
|
||||
mImageButton.setImageDrawable(mButtonIcon);
|
||||
mImageButton.setOnClickListener(mClickListener);
|
||||
mImageButton.setContentDescription(mContentDescription);
|
||||
}
|
||||
setButtonVisibility();
|
||||
}
|
||||
|
||||
private void setButtonVisibility() {
|
||||
if(mImageButton != null) {
|
||||
mImageButton.setVisibility(mButtonIcon == null ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the drawable to be displayed in button.
|
||||
*/
|
||||
public void setButtonIcon(@DrawableRes int iconResId) {
|
||||
if (iconResId == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mButtonIcon = getContext().getDrawable(iconResId);
|
||||
notifyChanged();
|
||||
} catch (Resources.NotFoundException exception) {
|
||||
Log.e(TAG, "Resource does not exist: " + iconResId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be invoked when button is clicked.
|
||||
*/
|
||||
public void setButtonOnClickListener(View.OnClickListener listener) {
|
||||
if (listener != mClickListener) {
|
||||
mClickListener = listener;
|
||||
notifyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A content description briefly describes the button and is primarily used for accessibility
|
||||
* support to determine how a button should be presented to the user.
|
||||
*/
|
||||
public void setButtonContentDescription(String contentDescription) {
|
||||
if (contentDescription != mContentDescription) {
|
||||
mContentDescription = contentDescription;
|
||||
notifyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,11 +82,15 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp
|
||||
|
||||
@VisibleForTesting
|
||||
final static String EXTRA_APP_NAME = "com.android.settings.wifi.extra.APP_NAME";
|
||||
final static String EXTRA_IS_SPECIFIED_SSID =
|
||||
"com.android.settings.wifi.extra.REQUEST_IS_FOR_SINGLE_NETWORK";
|
||||
|
||||
private List<AccessPoint> mAccessPointList;
|
||||
private FilterWifiTracker mFilterWifiTracker;
|
||||
private AccessPointAdapter mDialogAdapter;
|
||||
private NetworkRequestUserSelectionCallback mUserSelectionCallback;
|
||||
private boolean mIsSpecifiedSsid;
|
||||
private boolean mWaitingConnectCallback;
|
||||
|
||||
public static NetworkRequestDialogFragment newInstance() {
|
||||
NetworkRequestDialogFragment dialogFragment = new NetworkRequestDialogFragment();
|
||||
@@ -104,6 +108,11 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp
|
||||
final TextView title = customTitle.findViewById(R.id.network_request_title_text);
|
||||
title.setText(getTitle());
|
||||
|
||||
final Intent intent = getActivity().getIntent();
|
||||
if (intent != null) {
|
||||
mIsSpecifiedSsid = intent.getBooleanExtra(EXTRA_IS_SPECIFIED_SSID, false);
|
||||
}
|
||||
|
||||
final ProgressBar progressBar = customTitle.findViewById(
|
||||
R.id.network_request_title_progress);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
@@ -115,10 +124,13 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context)
|
||||
.setCustomTitle(customTitle)
|
||||
.setAdapter(mDialogAdapter, this)
|
||||
.setPositiveButton(R.string.cancel, (dialog, which) -> getActivity().finish())
|
||||
.setNegativeButton(R.string.cancel, (dialog, which) -> getActivity().finish())
|
||||
// Do nothings, will replace the onClickListener to avoid auto closing dialog.
|
||||
.setNeutralButton(R.string.network_connection_request_dialog_showall,
|
||||
null /* OnClickListener */);
|
||||
if (mIsSpecifiedSsid) {
|
||||
builder.setPositiveButton(R.string.wifi_connect, null /* OnClickListener */);
|
||||
}
|
||||
|
||||
// Clicking list item is to connect wifi ap.
|
||||
final AlertDialog dialog = builder.create();
|
||||
@@ -136,8 +148,19 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp
|
||||
notifyAdapterRefresh();
|
||||
neutralBtn.setVisibility(View.GONE);
|
||||
});
|
||||
});
|
||||
|
||||
// Replace Positive onClickListener to avoid closing dialog
|
||||
if (mIsSpecifiedSsid) {
|
||||
final Button positiveBtn = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
|
||||
positiveBtn.setOnClickListener(v -> {
|
||||
// When clicking connect button, should connect to the first and the only one
|
||||
// list item.
|
||||
this.onClick(dialog, 0 /* position */);
|
||||
});
|
||||
// Disable button in first, and enable it after there are some accesspoints in list.
|
||||
positiveBtn.setEnabled(false);
|
||||
}
|
||||
});
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@@ -184,6 +207,9 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp
|
||||
|
||||
if (wifiConfig != null) {
|
||||
mUserSelectionCallback.select(wifiConfig);
|
||||
|
||||
mWaitingConnectCallback = true;
|
||||
updateConnectButton(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -223,7 +249,7 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp
|
||||
}
|
||||
}
|
||||
|
||||
private void showNeutralButton() {
|
||||
private void showAllButton() {
|
||||
final AlertDialog alertDialog = (AlertDialog) getDialog();
|
||||
if (alertDialog == null) {
|
||||
return;
|
||||
@@ -235,6 +261,35 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp
|
||||
}
|
||||
}
|
||||
|
||||
private void updateConnectButton(boolean enabled) {
|
||||
// The button is only showed in single SSID mode.
|
||||
if (!mIsSpecifiedSsid) {
|
||||
return;
|
||||
}
|
||||
|
||||
final AlertDialog alertDialog = (AlertDialog) getDialog();
|
||||
if (alertDialog == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Button positiveBtn = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
|
||||
if (positiveBtn != null) {
|
||||
positiveBtn.setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
private void hideProgressIcon() {
|
||||
final AlertDialog alertDialog = (AlertDialog) getDialog();
|
||||
if (alertDialog == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final View progress = alertDialog.findViewById(R.id.network_request_title_progress);
|
||||
if (progress != null) {
|
||||
progress.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
@@ -403,7 +458,9 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp
|
||||
|
||||
@Override
|
||||
public void onUserSelectionConnectFailure(WifiConfiguration wificonfiguration) {
|
||||
stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE.ABORT);
|
||||
// Do nothing when selection is failed, let user could try again easily.
|
||||
mWaitingConnectCallback = false;
|
||||
updateConnectButton(true);
|
||||
}
|
||||
|
||||
private final class FilterWifiTracker {
|
||||
@@ -427,10 +484,6 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp
|
||||
mAccessPointKeys.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
if (mShowLimitedItem && (mAccessPointKeys.size() > MAX_NUMBER_LIST_ITEM)) {
|
||||
showNeutralButton();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -457,6 +510,21 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp
|
||||
}
|
||||
}
|
||||
|
||||
// Update related UI buttons
|
||||
if (mShowLimitedItem && (count >= MAX_NUMBER_LIST_ITEM)) {
|
||||
showAllButton();
|
||||
}
|
||||
if (count > 0) {
|
||||
hideProgressIcon();
|
||||
}
|
||||
// Enable connect button if there is Accesspoint item, except for the situation that
|
||||
// user click but connected status doesn't come back yet.
|
||||
if (count < 0) {
|
||||
updateConnectButton(false);
|
||||
} else if (!mWaitingConnectCallback) {
|
||||
updateConnectButton(true);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -179,7 +179,8 @@ public class WifiSettings extends RestrictedSettingsFragment
|
||||
|
||||
private PreferenceCategory mConnectedAccessPointPreferenceCategory;
|
||||
private PreferenceCategory mAccessPointsPreferenceCategory;
|
||||
private ButtonPreference mAddPreference;
|
||||
@VisibleForTesting
|
||||
AddWifiNetworkPreference mAddWifiNetworkPreference;
|
||||
@VisibleForTesting
|
||||
Preference mConfigureWifiSettingsPreference;
|
||||
@VisibleForTesting
|
||||
@@ -237,20 +238,8 @@ public class WifiSettings extends RestrictedSettingsFragment
|
||||
(PreferenceCategory) findPreference(PREF_KEY_ACCESS_POINTS);
|
||||
mConfigureWifiSettingsPreference = findPreference(PREF_KEY_CONFIGURE_WIFI_SETTINGS);
|
||||
mSavedNetworksPreference = findPreference(PREF_KEY_SAVED_NETWORKS);
|
||||
|
||||
Context prefContext = getPrefContext();
|
||||
mAddPreference = new ButtonPreference(prefContext);
|
||||
mAddPreference.setIcon(R.drawable.ic_menu_add);
|
||||
mAddPreference.setTitle(R.string.wifi_add_network);
|
||||
mAddPreference.setButtonIcon(R.drawable.ic_scan_24dp);
|
||||
mAddPreference.setButtonOnClickListener((View v) -> {
|
||||
// Launch QR code scanner to join a network.
|
||||
getContext().startActivity(
|
||||
WifiDppUtils.getEnrolleeQrCodeScannerIntent(/* ssid */ null));
|
||||
});
|
||||
mAddPreference.setButtonContentDescription(getString(R.string.wifi_dpp_scan_qr_code));
|
||||
mAddWifiNetworkPreference = new AddWifiNetworkPreference(getPrefContext());
|
||||
mStatusMessagePreference = (LinkablePreference) findPreference(PREF_KEY_STATUS_MESSAGE);
|
||||
|
||||
mUserBadgeCache = new AccessPointPreference.UserBadgeCache(getPackageManager());
|
||||
}
|
||||
|
||||
@@ -590,7 +579,7 @@ public class WifiSettings extends RestrictedSettingsFragment
|
||||
showDialog(mSelectedAccessPoint, WifiConfigUiBase.MODE_CONNECT);
|
||||
break;
|
||||
}
|
||||
} else if (preference == mAddPreference) {
|
||||
} else if (preference == mAddWifiNetworkPreference) {
|
||||
onAddNetworkPressed();
|
||||
} else {
|
||||
return super.onPreferenceTreeClick(preference);
|
||||
@@ -809,8 +798,8 @@ public class WifiSettings extends RestrictedSettingsFragment
|
||||
}
|
||||
}
|
||||
removeCachedPrefs(mAccessPointsPreferenceCategory);
|
||||
mAddPreference.setOrder(index);
|
||||
mAccessPointsPreferenceCategory.addPreference(mAddPreference);
|
||||
mAddWifiNetworkPreference.setOrder(index);
|
||||
mAccessPointsPreferenceCategory.addPreference(mAddWifiNetworkPreference);
|
||||
setAdditionalSettingsSummaries();
|
||||
|
||||
if (!hasAvailableAccessPoints) {
|
||||
|
||||
@@ -34,11 +34,14 @@ import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.wifi.AddNetworkFragment;
|
||||
import com.android.settings.wifi.savedaccesspoints.SavedNetworkComparator;
|
||||
import com.android.settingslib.wifi.AccessPoint;
|
||||
import com.android.settingslib.wifi.AccessPointPreference;
|
||||
import com.android.settingslib.wifi.WifiSavedConfigUtils;
|
||||
import com.android.settingslib.wifi.WifiTracker;
|
||||
import com.android.settingslib.wifi.WifiTrackerFactory;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class WifiNetworkListFragment extends SettingsPreferenceFragment implements
|
||||
@@ -256,17 +259,6 @@ public class WifiNetworkListFragment extends SettingsPreferenceFragment implemen
|
||||
return false;
|
||||
}
|
||||
|
||||
// Can only use saved network for DPP configuration. For ephemeral connections networkId
|
||||
// is invalid.
|
||||
if (!accessPoint.isSaved()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ignore access points that are out of range.
|
||||
if (!accessPoint.isReachable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -290,44 +282,47 @@ public class WifiNetworkListFragment extends SettingsPreferenceFragment implemen
|
||||
return;
|
||||
}
|
||||
|
||||
// AccessPoints are sorted by the WifiTracker
|
||||
final List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints();
|
||||
|
||||
mAccessPointsPreferenceCategory.setVisible(true);
|
||||
|
||||
cacheRemoveAllPrefs(mAccessPointsPreferenceCategory);
|
||||
// TODO(b/128942314): Lists reachable AccessPoints on top of the list
|
||||
final List<AccessPoint> savedAccessPoints =
|
||||
WifiSavedConfigUtils.getAllConfigs(getContext(), mWifiManager);
|
||||
Collections.sort(savedAccessPoints, SavedNetworkComparator.INSTANCE);
|
||||
|
||||
int index = 0;
|
||||
for (; index < accessPoints.size(); index++) {
|
||||
AccessPoint accessPoint = accessPoints.get(index);
|
||||
// Check if this access point is valid for DPP.
|
||||
if (isValidForDppConfiguration(accessPoint)) {
|
||||
final String key = accessPoint.getKey();
|
||||
mAccessPointsPreferenceCategory.removeAll();
|
||||
for (AccessPoint savedAccessPoint : savedAccessPoints) {
|
||||
if (isValidForDppConfiguration(savedAccessPoint)) {
|
||||
// Replaces with an AccessPoint from scanned result for signal information
|
||||
savedAccessPoint = getScannedAccessPointIfAvailable(savedAccessPoint);
|
||||
final AccessPointPreference preference =
|
||||
createAccessPointPreference(savedAccessPoint);
|
||||
|
||||
final AccessPointPreference pref = (AccessPointPreference) getCachedPreference(key);
|
||||
if (pref != null) {
|
||||
pref.setOrder(index);
|
||||
continue;
|
||||
}
|
||||
final AccessPointPreference preference = createAccessPointPreference(accessPoint);
|
||||
preference.setKey(key);
|
||||
preference.setOrder(index);
|
||||
preference.setOrder(index++);
|
||||
preference.setEnabled(savedAccessPoint.isReachable());
|
||||
savedAccessPoint.setListener(this);
|
||||
|
||||
mAccessPointsPreferenceCategory.addPreference(preference);
|
||||
accessPoint.setListener(this);
|
||||
preference.refresh();
|
||||
mAccessPointsPreferenceCategory.addPreference(preference);
|
||||
}
|
||||
}
|
||||
removeCachedPrefs(mAccessPointsPreferenceCategory);
|
||||
mAddPreference.setOrder(index);
|
||||
mAccessPointsPreferenceCategory.addPreference(mAddPreference);
|
||||
|
||||
if (mIsTest) {
|
||||
mFakeNetworkPreference.setOrder(index + 1);
|
||||
mAccessPointsPreferenceCategory.addPreference(mFakeNetworkPreference);
|
||||
}
|
||||
}
|
||||
|
||||
private AccessPoint getScannedAccessPointIfAvailable(AccessPoint savedAccessPoint) {
|
||||
final List<AccessPoint> scannedAccessPoints = mWifiTracker.getAccessPoints();
|
||||
final WifiConfiguration savedWifiConfiguration = savedAccessPoint.getConfig();
|
||||
for (AccessPoint scannedAccessPoint : scannedAccessPoints) {
|
||||
if (scannedAccessPoint.matches(savedWifiConfiguration)) {
|
||||
return scannedAccessPoint;
|
||||
}
|
||||
}
|
||||
return savedAccessPoint;
|
||||
}
|
||||
|
||||
private AccessPointPreference createAccessPointPreference(AccessPoint accessPoint) {
|
||||
return new AccessPointPreference(accessPoint, getPrefContext(), mUserBadgeCache,
|
||||
R.drawable.ic_wifi_signal_0, /* forSavedNetworks */ false);
|
||||
|
||||
@@ -42,7 +42,7 @@ public class BatterySaverStickyPreferenceControllerTest {
|
||||
}
|
||||
|
||||
private int getAutoDisableSetting() {
|
||||
return Settings.System.getInt(mContext.getContentResolver(),
|
||||
return Settings.Global.getInt(mContext.getContentResolver(),
|
||||
LOW_POWER_STICKY_AUTO_DISABLE_ENABLED,
|
||||
1);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AdaptiveHomepageIconTest {
|
||||
public class AdaptiveIconTest {
|
||||
|
||||
private Context mContext;
|
||||
private ActivityInfo mActivityInfo;
|
||||
@@ -64,8 +64,8 @@ public class AdaptiveHomepageIconTest {
|
||||
|
||||
@Test
|
||||
public void createIcon_shouldSetBackgroundAndInset() {
|
||||
final AdaptiveHomepageIcon icon =
|
||||
new AdaptiveHomepageIcon(mContext, new ColorDrawable(Color.BLACK));
|
||||
final AdaptiveIcon icon =
|
||||
new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
|
||||
|
||||
assertThat(icon.getNumberOfLayers()).isEqualTo(2);
|
||||
assertThat(icon.getDrawable(0)).isInstanceOf(AdaptiveIconShapeDrawable.class);
|
||||
@@ -73,8 +73,8 @@ public class AdaptiveHomepageIconTest {
|
||||
|
||||
@Test
|
||||
public void setBackgroundColor_shouldUpdateColorFilter() {
|
||||
final AdaptiveHomepageIcon icon =
|
||||
spy(new AdaptiveHomepageIcon(mContext, new ColorDrawable(Color.BLACK)));
|
||||
final AdaptiveIcon icon =
|
||||
spy(new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)));
|
||||
final ShapeDrawable background = mock(ShapeDrawable.class);
|
||||
when(icon.getDrawable(0)).thenReturn(background);
|
||||
|
||||
@@ -89,8 +89,8 @@ public class AdaptiveHomepageIconTest {
|
||||
mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, 0xff0000);
|
||||
doReturn(Icon.createWithResource(mContext, R.drawable.ic_settings_accent))
|
||||
.when(tile).getIcon(mContext);
|
||||
final AdaptiveHomepageIcon icon =
|
||||
new AdaptiveHomepageIcon(mContext, new ColorDrawable(Color.BLACK));
|
||||
final AdaptiveIcon icon =
|
||||
new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
|
||||
|
||||
icon.setBackgroundColor(mContext, tile);
|
||||
assertThat(icon.mBackgroundColor).isEqualTo(0xff0000);
|
||||
@@ -101,8 +101,8 @@ public class AdaptiveHomepageIconTest {
|
||||
final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
|
||||
doReturn(Icon.createWithResource(mContext, R.drawable.ic_settings_accent))
|
||||
.when(tile).getIcon(mContext);
|
||||
final AdaptiveHomepageIcon icon =
|
||||
new AdaptiveHomepageIcon(mContext, new ColorDrawable(Color.BLACK));
|
||||
final AdaptiveIcon icon =
|
||||
new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
|
||||
|
||||
icon.setBackgroundColor(mContext, tile);
|
||||
|
||||
@@ -118,11 +118,24 @@ public class AdaptiveHomepageIconTest {
|
||||
doReturn(Icon.createWithResource(mContext, R.drawable.ic_settings_accent))
|
||||
.when(tile).getIcon(mContext);
|
||||
|
||||
final AdaptiveHomepageIcon icon =
|
||||
new AdaptiveHomepageIcon(mContext, new ColorDrawable(Color.BLACK));
|
||||
final AdaptiveIcon icon =
|
||||
new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
|
||||
icon.setBackgroundColor(mContext, tile);
|
||||
|
||||
assertThat(icon.mBackgroundColor)
|
||||
.isEqualTo(mContext.getColor(R.color.material_blue_500));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConstantState_returnCorrectState() {
|
||||
final AdaptiveIcon icon =
|
||||
new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
|
||||
icon.setBackgroundColor(Color.YELLOW);
|
||||
|
||||
final AdaptiveIcon.AdaptiveConstantState state =
|
||||
(AdaptiveIcon.AdaptiveConstantState) icon.getConstantState();
|
||||
|
||||
assertThat(state.color).isEqualTo(Color.YELLOW);
|
||||
assertThat(state.context).isEqualTo(mContext);
|
||||
}
|
||||
}
|
||||
@@ -1,82 +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.wifi;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.ImageButton;
|
||||
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class ButtonPreferenceTest {
|
||||
|
||||
private Context mContext;
|
||||
private View mRootView;
|
||||
private ButtonPreference mPref;
|
||||
private PreferenceViewHolder mHolder;
|
||||
private boolean mClicked;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mPref = new ButtonPreference(mContext);
|
||||
mRootView = View.inflate(mContext, R.layout.wifi_button_preference_widget, /* parent */
|
||||
null);
|
||||
mHolder = PreferenceViewHolder.createInstanceForTests(mRootView);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initButton_noIcon_shouldInvisible() {
|
||||
mPref.initButton(mHolder);
|
||||
assertThat(mRootView.findViewById(R.id.button_icon).getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initButton_withIcon_shouldVisible() {
|
||||
mPref.setButtonIcon(R.drawable.ic_qrcode_24dp);
|
||||
mPref.initButton(mHolder);
|
||||
assertThat(mRootView.findViewById(R.id.button_icon).getVisibility()).isEqualTo(
|
||||
View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initButton_whenClick_shouldCallback() {
|
||||
mClicked = false;
|
||||
mPref.setButtonIcon(R.drawable.ic_qrcode_24dp);
|
||||
mPref.setButtonOnClickListener((View v) -> {
|
||||
mClicked = true;
|
||||
});
|
||||
mPref.initButton(mHolder);
|
||||
ImageButton button = (ImageButton) mRootView.findViewById(R.id.button_icon);
|
||||
button.performClick();
|
||||
assertThat(mClicked).isTrue();
|
||||
}
|
||||
}
|
||||
@@ -106,12 +106,12 @@ public class NetworkRequestDialogFragmentTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickPositiveButton_shouldCloseTheDialog() {
|
||||
public void clickNegativeButton_shouldCloseTheDialog() {
|
||||
networkRequestDialogFragment.show(mActivity.getSupportFragmentManager(), null);
|
||||
AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(alertDialog.isShowing()).isTrue();
|
||||
|
||||
Button positiveButton = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
Button positiveButton = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
|
||||
assertThat(positiveButton).isNotNull();
|
||||
|
||||
positiveButton.performClick();
|
||||
@@ -185,26 +185,6 @@ public class NetworkRequestDialogFragmentTest {
|
||||
verify(spyActivity).finish();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateAccessPointList_onUserSelectionConnectFailure_shouldCallAbortDialog() {
|
||||
FakeNetworkRequestDialogFragment fakeFragment = new FakeNetworkRequestDialogFragment();
|
||||
FakeNetworkRequestDialogFragment spyFakeFragment = spy(fakeFragment);
|
||||
List<AccessPoint> accessPointList = createAccessPointList();
|
||||
when(spyFakeFragment.getAccessPointList()).thenReturn(accessPointList);
|
||||
spyFakeFragment.show(mActivity.getSupportFragmentManager(), null);
|
||||
|
||||
AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(alertDialog.isShowing()).isTrue();
|
||||
|
||||
// Test if config would update list.
|
||||
WifiConfiguration config = new WifiConfiguration();
|
||||
config.SSID = "Test AP 3";
|
||||
fakeFragment.onUserSelectionConnectFailure(config);
|
||||
|
||||
assertThat(fakeFragment.bCalledStopAndPop).isTrue();
|
||||
assertThat(fakeFragment.errorType).isEqualTo(ERROR_DIALOG_TYPE.ABORT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onUserSelectionCallbackRegistration_onClick_shouldCallSelect() {
|
||||
// Assert.
|
||||
@@ -267,19 +247,27 @@ public class NetworkRequestDialogFragmentTest {
|
||||
Bundle bundle = new Bundle();
|
||||
|
||||
bundle.putString(KEY_SSID, "Test AP 1");
|
||||
bundle.putInt(KEY_SECURITY, 1);
|
||||
bundle.putInt(KEY_SECURITY, 1 /* WEP */);
|
||||
accessPointList.add(new AccessPoint(mContext, bundle));
|
||||
|
||||
bundle.putString(KEY_SSID, "Test AP 2");
|
||||
bundle.putInt(KEY_SECURITY, 1);
|
||||
bundle.putInt(KEY_SECURITY, 1 /* WEP */);
|
||||
accessPointList.add(new AccessPoint(mContext, bundle));
|
||||
|
||||
bundle.putString(KEY_SSID, "Test AP 3");
|
||||
bundle.putInt(KEY_SECURITY, 2);
|
||||
bundle.putInt(KEY_SECURITY, 1 /* WEP */);
|
||||
accessPointList.add(new AccessPoint(mContext, bundle));
|
||||
|
||||
bundle.putString(KEY_SSID, "Test AP 4");
|
||||
bundle.putInt(KEY_SECURITY, 0);
|
||||
bundle.putInt(KEY_SECURITY, 0 /* NONE */);
|
||||
accessPointList.add(new AccessPoint(mContext, bundle));
|
||||
|
||||
bundle.putString(KEY_SSID, "Test AP 5");
|
||||
bundle.putInt(KEY_SECURITY, 1 /* WEP */);
|
||||
accessPointList.add(new AccessPoint(mContext, bundle));
|
||||
|
||||
bundle.putString(KEY_SSID, "Test AP 6");
|
||||
bundle.putInt(KEY_SECURITY, 1 /* WEP */);
|
||||
accessPointList.add(new AccessPoint(mContext, bundle));
|
||||
|
||||
return accessPointList;
|
||||
@@ -300,9 +288,13 @@ public class NetworkRequestDialogFragmentTest {
|
||||
networkRequestDialogFragment.show(mActivity.getSupportFragmentManager(), /* tag */ null);
|
||||
final AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
|
||||
|
||||
List<AccessPoint> accessPointList = createAccessPointList();
|
||||
when(mWifiTracker.getAccessPoints()).thenReturn(accessPointList);
|
||||
|
||||
final String SSID_AP = "Test AP ";
|
||||
final List<ScanResult> scanResults = new ArrayList<>();
|
||||
for (int i = 0; i < 6 ; i ++) {
|
||||
for (int i = 0; i < 7 ; i ++) {
|
||||
ScanResult scanResult = new ScanResult();
|
||||
scanResult.SSID = SSID_AP + i;
|
||||
scanResult.capabilities = "WEP";
|
||||
|
||||
@@ -69,6 +69,7 @@ public class WifiSettingsTest {
|
||||
mWifiSettings = spy(new WifiSettings());
|
||||
doReturn(mContext).when(mWifiSettings).getContext();
|
||||
doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class);
|
||||
mWifiSettings.mAddWifiNetworkPreference = new AddWifiNetworkPreference(mContext);
|
||||
mWifiSettings.mSavedNetworksPreference = new Preference(mContext);
|
||||
mWifiSettings.mConfigureWifiSettingsPreference = new Preference(mContext);
|
||||
mWifiSettings.mWifiTracker = mWifiTracker;
|
||||
@@ -151,4 +152,11 @@ public class WifiSettingsTest {
|
||||
assertThat(mWifiSettings.mConfigureWifiSettingsPreference.getSummary()).isEqualTo(
|
||||
mContext.getString(R.string.wifi_configure_settings_preference_summary_wakeup_off));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkAddWifiNetworkPrefernce_preferenceVisible() {
|
||||
assertThat(mWifiSettings.mAddWifiNetworkPreference.isVisible()).isTrue();
|
||||
assertThat(mWifiSettings.mAddWifiNetworkPreference.getTitle()).isEqualTo(
|
||||
mContext.getString(R.string.wifi_add_network));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user