Snap for 12847866 from 3b54bb45e6 to 25Q2-release

Change-Id: I62a786719c1de4e12e395c3768346f97f2fa598a
This commit is contained in:
Android Build Coastguard Worker
2024-12-24 16:17:57 -08:00
43 changed files with 1053 additions and 618 deletions

View File

@@ -27,4 +27,11 @@ flag {
namespace: "globalintl"
description: "Feature flag for regional preferences APIs"
bug: "370379000"
}
flag {
name: "settings_expressive_design_enabled"
namespace: "globalintl"
description: "Feature flag for expressive design"
bug: "385659296"
}

View File

@@ -89,12 +89,6 @@
<string name="security_settings_face_enroll_introduction_message_class3" product="tablet">Use your face to unlock your tablet or for authentication in apps, like when you sign in to apps or approve a purchase</string>
<!-- Subtitle shown on the face enrollment introduction screen with in-app authentication. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_message_class3" product="device">Use your face to unlock your device or for authentication in apps, like when you sign in to apps or approve a purchase</string>
<!-- Subtitle shown on the face enrollment introduction screen with in-app authentication. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_message_class3_2" product="default"></string>
<!-- Subtitle shown on the face enrollment introduction screen with in-app authentication. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_message_class3_2" product="tablet"></string>
<!-- Subtitle shown on the face enrollment introduction screen with in-app authentication. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_message_class3_2" product="device"></string>
<!-- Introduction detail message shown in face enrollment dialog when asking for parental consent [CHAR LIMIT=NONE]-->
<string name="security_settings_face_enroll_introduction_consent_message_0" product="default">Allow your child to use their face to unlock their phone</string>
<!-- Introduction detail message shown in face enrollment dialog when asking for parental consent [CHAR LIMIT=NONE]-->
@@ -113,18 +107,6 @@
<string name="security_settings_face_enroll_introduction_consent_message" product="tablet">Using your child\u2019s face to unlock their tablet may be less secure than a strong pattern or PIN.</string>
<!-- Introduction detail message shown in face enrollment dialog when asking for parental consent [CHAR LIMIT=NONE]-->
<string name="security_settings_face_enroll_introduction_consent_message" product="device">Using your child\u2019s face to unlock their device may be less secure than a strong pattern or PIN.</string>
<!-- Message shown in Secure and helpful section in face enrollment introduction page. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_secure_and_helpful_message_1" product="default"></string>
<!-- Message shown in Secure and helpful section in face enrollment introduction page. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_secure_and_helpful_message_1" product="tablet"></string>
<!-- Message shown in Secure and helpful section in face enrollment introduction page. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_secure_and_helpful_message_1" product="device"></string>
<!-- Message shown in Secure and helpful section in face enrollment introduction page. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_secure_and_helpful_message_2" product="default"></string>
<!-- Message shown in Secure and helpful section in face enrollment introduction page. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_secure_and_helpful_message_2" product="tablet"></string>
<!-- Message shown in Secure and helpful section in face enrollment introduction page. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_secure_and_helpful_message_2" product="device"></string>
<!-- Message on the face enrollment introduction page that provides information about what could cause the phone to unlock. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_info_looking" product="default"></string>
<!-- Message on the face enrollment introduction page that provides information about what could cause the phone to unlock. [CHAR LIMIT=NONE] -->
@@ -179,12 +161,6 @@
<string name="security_settings_face_enroll_introduction_control_message" product="tablet"></string>
<!-- Message on the face enrollment introduction page that explains privacy controls for face unlock [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_control_message" product="device"></string>
<!-- Message on the face enrollment introduction page that explains privacy controls for face unlock [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_control_message_2" product="default"></string>
<!-- Message on the face enrollment introduction page that explains privacy controls for face unlock [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_control_message_2" product="tablet"></string>
<!-- Message on the face enrollment introduction page that explains privacy controls for face unlock [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_control_message_2" product="device"></string>
<!-- Message on the face enrollment introduction page that explains privacy controls for face unlock when asking for parental consent. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_control_consent_message" product="default"></string>
<!-- Message on the face enrollment introduction page that explains privacy controls for face unlock when asking for parental consent. [CHAR LIMIT=NONE] -->
@@ -217,8 +193,6 @@
<string name="security_settings_face_settings_footer_class3_attention_not_supported" product="device">Use your face to unlock your device or verify it\u2019s you, like when you sign in to apps or approve a purchase.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the device can unlock it when you don\u2019t intend to.\n\nYour device can be unlocked by someone else if it\u2019s held up to your face, even if your eyes are closed.\n\nYour device can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
<!-- Introduction detail message shown in fingerprint enrollment dialog [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_enroll_introduction_v3_message">Use your fingerprint to unlock your <xliff:g id="deviceName" example="Pixel">%s</xliff:g> or verify it\u2019s you, like when you sign in to apps or approve a purchase</string>
<!-- Introduction detail message shown in fingerprint enrollment dialog [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_enroll_introduction_v3_message_2">Use your fingerprints to unlock your <xliff:g id="deviceName" example="Pixel">%s</xliff:g> or verify it\u2019s you in apps</string>
<!-- Introduction detail message shown in fingerprint enrollment dialog when asking for parental consent [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_enroll_introduction_consent_message" product="default">Allow your child to use their fingerprint to unlock their phone or verify it\u2019s them. This happens when they sign in to apps, approve a purchase, and more.</string>
<!-- Introduction detail message shown in fingerprint enrollment dialog when asking for parental consent [CHAR LIMIT=NONE]-->
@@ -267,18 +241,6 @@
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_5" product="tablet">Your child\u2019s tablet can be unlocked when they don\u2019t intend to, like if someone holds it up to their finger.</string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard when asking for parental consent. [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_5" product="device">Your child\u2019s device can be unlocked when they don\u2019t intend to, like if someone holds it up to their finger.</string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_7" product="default"></string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_7" product="tablet"></string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_7" product="device"></string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_8" product="default"></string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_8" product="tablet"></string>
<!-- Introduction description message shown in fingerprint enrollment introduction screen in setup wizard. [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_8" product="device"></string>
<!-- Message text only shown in fingerprint security settings home screen. (tablet) [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_v2_home_screen_text" product="tablet">Use your fingerprint to unlock your tablet or verify it\u2019s you, like when you sign in to apps</string>
<!-- Message text only shown in fingerprint security settings home screen. (device) [CHAR LIMIT=NONE]-->

View File

@@ -1,26 +0,0 @@
<!--
~ Copyright (C) 2024 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M274,600Q305,600 329.5,582Q354,564 364,535L379,489Q395,441 371,400.5Q347,360 302,360L161,360L180,517Q185,552 211.5,576Q238,600 274,600ZM686,600Q722,600 748.5,576Q775,552 780,517L799,360L659,360Q614,360 590,401Q566,442 582,490L596,535Q606,564 630.5,582Q655,600 686,600ZM274,680Q208,680 158.5,636.5Q109,593 101,527L80,360L40,360L40,280L302,280Q346,280 382.5,301.5Q419,323 440,360L521,360Q542,323 578.5,301.5Q615,280 659,280L920,280L920,360L880,360L859,527Q851,593 801.5,636.5Q752,680 686,680Q629,680 583.5,647.5Q538,615 520,561L505,516Q503,509 501,501.5Q499,494 497,480L463,480Q461,492 459,499.5Q457,507 455,514L440,560Q422,614 376.5,647Q331,680 274,680Z"/>
</vector>

View File

@@ -1,26 +0,0 @@
<!--
~ Copyright (C) 2024 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M480,800Q346,800 253,707Q160,614 160,480Q160,346 253,253Q346,160 480,160Q614,160 707,253Q800,346 800,480Q800,614 707,707Q614,800 480,800ZM480,720Q580,720 650,650Q720,580 720,480Q720,463 717.5,446.5Q715,430 710,414Q695,417 680,418.5Q665,420 650,420Q587,420 530,396Q473,372 428,326Q400,383 351,425Q302,467 240,486Q243,584 312.5,652Q382,720 480,720ZM256,394Q300,371 323,340.5Q346,310 368,268Q330,288 301,320.5Q272,353 256,394ZM380,560Q363,560 351.5,548.5Q340,537 340,520Q340,503 351.5,491.5Q363,480 380,480Q397,480 408.5,491.5Q420,503 420,520Q420,537 408.5,548.5Q397,560 380,560ZM650,340Q656,340 662,340Q668,340 674,339Q641,294 590.5,267Q540,240 480,240Q474,240 468,240Q462,240 457,241Q496,286 539.5,313Q583,340 650,340ZM580,560Q563,560 551.5,548.5Q540,537 540,520Q540,503 551.5,491.5Q563,480 580,480Q597,480 608.5,491.5Q620,503 620,520Q620,537 608.5,548.5Q597,560 580,560ZM40,240L40,120Q40,87 63.5,63.5Q87,40 120,40L240,40L240,120L120,120Q120,120 120,120Q120,120 120,120L120,240L40,240ZM240,920L120,920Q87,920 63.5,896.5Q40,873 40,840L40,720L120,720L120,840Q120,840 120,840Q120,840 120,840L240,840L240,920ZM720,920L720,840L840,840Q840,840 840,840Q840,840 840,840L840,720L920,720L920,840Q920,873 896.5,896.5Q873,920 840,920L720,920ZM840,240L840,120Q840,120 840,120Q840,120 840,120L720,120L720,40L840,40Q873,40 896.5,63.5Q920,87 920,120L920,240L840,240ZM457,241Q457,241 457,241Q457,241 457,241Q457,241 457,241Q457,241 457,241Q457,241 457,241Q457,241 457,241Q457,241 457,241Q457,241 457,241ZM368,268Q368,268 368,268Q368,268 368,268Q368,268 368,268Q368,268 368,268Z"/>
</vector>

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M440,680L520,680L520,440L440,440L440,680ZM480,360Q497,360 508.5,348.5Q520,337 520,320Q520,303 508.5,291.5Q497,280 480,280Q463,280 451.5,291.5Q440,303 440,320Q440,337 451.5,348.5Q463,360 480,360ZM480,880Q341,845 250.5,720.5Q160,596 160,444L160,200L480,80L800,200L800,444Q800,596 709.5,720.5Q619,845 480,880ZM480,796Q584,763 652,664Q720,565 720,444L720,255L480,165L240,255L240,444Q240,565 308,664Q376,763 480,796ZM480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480Z"/>
</vector>

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M426,608L662,376L606,320L426,496L354,426L298,482L426,608ZM480,880Q473,880 466.5,878.5Q460,877 454,874Q306,798 233,685.5Q160,573 160,412L160,248Q160,222 174.5,201Q189,180 213,172L453,86Q460,84 466.5,82Q473,80 480,80Q489,80 507,86L747,172Q771,180 785.5,200.5Q800,221 800,247L800,412Q800,573 725.5,686Q651,799 505,874Q499,877 493,878.5Q487,880 480,880ZM480,797Q601,731 660.5,638.5Q720,546 720,412L720,247Q720,247 720,247Q720,247 720,247L480,161Q480,161 480,161Q480,161 480,161L240,247Q240,247 240,247Q240,247 240,247L240,412Q240,546 299.5,639Q359,732 480,797ZM480,479Q480,479 480,479Q480,479 480,479L480,479Q480,479 480,479Q480,479 480,479L480,479Q480,479 480,479Q480,479 480,479L480,479Q480,479 480,479Q480,479 480,479L480,479Q480,479 480,479Q480,479 480,479Z"/>
</vector>

View File

@@ -1,334 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2024 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.
-->
<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="?attr/face_layout_theme"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:sudDescriptionText="@string/security_settings_face_enroll_introduction_message">
<LinearLayout
style="@style/SudContentFrame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical">
<com.google.android.setupdesign.view.RichTextView
android:id="@+id/error_text"
style="@style/SudDescription.Glif"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
style="@style/SudContentIllustration"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@null"
android:src="@drawable/face_enroll_intro_illustration"
android:layout_marginBottom="@dimen/face_enroll_intro_illustration_margin_bottom"/>
</FrameLayout>
<!-- Contains the extra information text at the bottom -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Secure and helpful -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/BiometricEnrollIntroTitle"
android:text="@string/security_settings_fingerprint_enroll_introduction_footer_title_3"/>
<Space
android:layout_width="wrap_content"
android:layout_height="16dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/icon_security_privacy_safe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:background="@drawable/ic_security_privacy_safe"/>
<Space
android:layout_width="16dp"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/footer_message_7"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/security_settings_face_enroll_introduction_secure_and_helpful_message_1"
style="@style/BiometricEnrollIntroMessage" />
</LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="16dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/icon_privacy_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:background="@drawable/ic_privacy_tip"/>
<Space
android:layout_width="16dp"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/footer_message_8"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/security_settings_face_enroll_introduction_secure_and_helpful_message_2"
style="@style/BiometricEnrollIntroMessage" />
</LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="16dp"/>
<!-- Keep in mind -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/BiometricEnrollIntroTitle"
android:text="@string/security_settings_face_enroll_introduction_info_title" />
<Space
android:layout_width="wrap_content"
android:layout_height="16dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/icon_glasses"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_eyeglasses"/>
<Space
android:layout_width="16dp"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/info_message_glasses"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/BiometricEnrollIntroMessage" />
</LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="16dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/icon_looking"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_face_enroll_introduction_visibility"/>
<Space
android:layout_width="16dp"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/info_message_looking"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/BiometricEnrollIntroMessage" />
</LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="16dp"/>
<LinearLayout
android:id="@+id/info_row_less_secure"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone">
<ImageView
android:id="@+id/icon_less_secure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_info_outline_24dp"/>
<Space
android:layout_width="16dp"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/info_message_less_secure"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/BiometricEnrollIntroMessage"
android:text="@string/security_settings_face_enroll_introduction_info_less_secure" />
</LinearLayout>
<LinearLayout
android:id="@+id/info_row_require_eyes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone">
<ImageView
android:id="@+id/icon_require_eyes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_settings_24dp"/>
<Space
android:layout_width="16dp"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/info_message_require_eyes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/BiometricEnrollIntroMessage" />
</LinearLayout>
<!-- How it works -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/BiometricEnrollIntroTitle"
android:text="@string/security_settings_face_enroll_introduction_how_title" />
<Space
android:layout_width="wrap_content"
android:layout_height="16dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/icon_familiar_face_and_zone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:background="@drawable/ic_familiar_face_and_zone"/>
<Space
android:layout_width="16dp"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/how_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/BiometricEnrollIntroMessage" />
</LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="16dp"/>
<!-- You're in control -->
<TextView
android:id="@+id/title_in_control"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/BiometricEnrollIntroTitle" />
<Space
android:layout_width="wrap_content"
android:layout_height="16dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/icon_trash_can"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:background="@drawable/ic_trash_can"/>
<Space
android:layout_width="16dp"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/message_in_control"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/BiometricEnrollIntroMessage"
android:paddingBottom="0dp" />
</LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="16dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/icon_link"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:background="@drawable/ic_info_outline_24dp"/>
<Space
android:layout_width="wrap_content"
android:layout_height="4dp"/>
<TextView
android:id="@+id/message_learn_more"
android:linksClickable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/BiometricEnrollIntroMessage"
android:paddingBottom="0dp"
android:text="@string/security_settings_face_enroll_introduction_learn_more_message" />
</LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="16dp"/>
</LinearLayout>
</LinearLayout>
</com.google.android.setupdesign.GlifLayout>

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2024 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="?android:attr/dialogPreferredPadding"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textDirection="locale"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:text="@string/bluetooth_hearing_device_input_routing_dialog_summary" />
<RadioGroup
android:id="@+id/input_routing_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:checkedButton="@id/input_from_hearing_device">
<RadioButton
android:id="@+id/input_from_hearing_device"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:text="@string/bluetooth_hearing_device_input_routing_hearing_device_option"/>
<RadioButton
android:id="@+id/input_from_builtin_mic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:text="@string/bluetooth_hearing_device_input_routing_builtin_option"/>
</RadioGroup>
</LinearLayout>

View File

@@ -180,6 +180,16 @@
<string name="bluetooth_ambient_volume_unmute">Unmute surroundings</string>
<!-- Message when changing ambient state failed. [CHAR LIMIT=NONE] -->
<string name="bluetooth_ambient_volume_error">Couldn\u2019t update surroundings</string>
<!-- Connected devices settings. Title for hearing device input routing control preference. -->
<string name="bluetooth_hearing_device_input_routing_title">Default microphone for calls</string>
<!-- Connected devices settings. Title for hearing device input routing control dialog. -->
<string name="bluetooth_hearing_device_input_routing_dialog_title">Default microphone</string>
<!-- Connected devices settings. Summary for hearing device input routing control dialog. -->
<string name="bluetooth_hearing_device_input_routing_dialog_summary">Choose a microphone for calls.</string>
<!-- Connected devices settings. One of the input routing option. It will change input routing to hearing aid microphone. -->
<string name="bluetooth_hearing_device_input_routing_hearing_device_option">Hearing aid microphone</string>
<!-- Connected devices settings. One of the input routing option. It will change input routing to this phone's builtin microphone -->
<string name="bluetooth_hearing_device_input_routing_builtin_option">This phone\'s microphone</string>
<!-- Connected devices settings. Title of the preference to show the entrance of the audio output page. It can change different types of audio are played on phone or other bluetooth devices. [CHAR LIMIT=35] -->
<string name="bluetooth_audio_routing_title">Audio output</string>
<!-- Title for bluetooth audio routing page footer. [CHAR LIMIT=30] -->
@@ -807,8 +817,6 @@
<string name="security_settings_face_enroll_introduction_accessibility_diversity"></string>
<!-- Message shown for a toggle which when enabled, allows the user to enroll using a simpler flow for accessibility [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_accessibility_vision"></string>
<!-- Message on the face enrollment introduction page that explains privacy controls for face unlock [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_learn_more_message"></string>
<!-- Button text to cancel enrollment from the introduction [CHAR LIMIT=22] -->
<string name="security_settings_face_enroll_introduction_cancel">Cancel</string>
<!-- Button text to cancel enrollment [CHAR LIMIT=30] -->
@@ -936,8 +944,6 @@
<string name="security_settings_fingerprint_enroll_introduction_footer_title_consent_1">You and your child are in control</string>
<!-- Introduction title shown in the bottom of fingerprint enrollment dialog [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_enroll_introduction_footer_title_2">Keep in mind</string>
<!-- Introduction title shown in the bottom of fingerprint enrollment dialog [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_enroll_introduction_footer_title_3">Secure and helpful</string>
<!-- Introduction detail message shown in fingerprint enrollment dialog, when fingerprint unlock is disabled by device admin [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_enroll_introduction_message_unlock_disabled">Use your fingerprint to unlock your phone or approve purchases.\n\nNote: You can\u2019t use your fingerprint to unlock this device. For more information, contact your organization\u2019s admin.</string>
<!-- Button text to cancel enrollment from the introduction [CHAR LIMIT=22] -->
@@ -968,8 +974,6 @@
<string name="security_settings_fingerprint_v2_enroll_introduction_footer_message_consent_6">For best results, use a screen protector that\u2019s Made for Google certified. With other screen protectors, your child\u2019s fingerprint may not work.</string>
<!-- Introduction detail message shown in fingerprint enrollment introduction to learn more about fingerprint [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_v2_enroll_introduction_message_learn_more"></string>
<!-- Introduction detail message shown in fingerprint enrollment introduction to learn more about fingerprint [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_v2_enroll_introduction_message_learn_more_2"></string>
<!-- Watch unlock enrollment and settings --><skip />
<!-- Title shown for menu item that launches watch unlock settings. [CHAR LIMIT=40] -->
@@ -5450,9 +5454,9 @@
<!-- Summary for the accessibility preference for enabling/disabling large icons for mouse/trackpad pointers. [CHAR LIMIT=60] -->
<string name="accessibility_toggle_large_pointer_icon_summary">Make the mouse pointer more noticeable</string>
<!-- Title for the accessibility preference for forcing all apps to use dark theme. [CHAR LIMIT=35] -->
<string name="accessibility_force_invert_title">Make all apps dark</string>
<string name="accessibility_force_invert_title">Make more apps dark</string>
<!-- Summary for the accessibility preference for forcing all apps to use dark theme. [CHAR LIMIT=100] -->
<string name="accessibility_force_invert_summary">Applies to apps without their own dark theme. Some apps may have display issues, like inverted colors.</string>
<string name="accessibility_force_invert_summary">Automatically convert light theme apps to dark theme</string>
<!-- Title for the accessibility preference for disabling animations. [CHAR LIMIT=35] -->
<string name="accessibility_disable_animations">Remove animations</string>
<!-- Summary for the accessibility preference for disabling animations. [CHAR LIMIT=60] -->
@@ -12304,11 +12308,6 @@
<!-- Summary for an item in the page listing multiple mobile service subscriptions, indicating
that service is inactive and is tied to an eSIM profile [CHAR LIMIT=40] -->
<string name="mobile_network_inactive_esim">Inactive / eSIM</string>
<!-- Title of a dialog that lets a user modify the display name used for a mobile network
subscription in various places in the Settings app. The default name is typically just the
carrier name, but especially in multi-SIM configurations users may want to use a different
name. [CHAR LIMIT=40] -->
<string name="mobile_network_sim_name">SIM name &amp; color</string>
<!-- Label for an item listing the name of the SIM that the user has specified. [CHAR LIMIT=40] -->
<string name="mobile_network_sim_name_label">Name</string>
<!-- Label for an item listing the color of the SIM that the user has specified. [CHAR LIMIT=40] -->

View File

@@ -51,14 +51,6 @@
settings:controller="com.android.settings.display.DarkUIPreferenceController"
settings:searchable="false"/>
<SwitchPreferenceCompat
android:icon="@drawable/ic_dark_ui"
android:key="toggle_force_invert"
android:persistent="false"
android:summary="@string/accessibility_force_invert_summary"
android:title="@string/accessibility_force_invert_title"
settings:controller="com.android.settings.accessibility.ToggleForceInvertPreferenceController"/>
<SwitchPreferenceCompat
android:icon="@drawable/ic_accessibility_animation"
android:key="animator_duration_scale"

View File

@@ -35,25 +35,35 @@
android:title="@string/twilight_mode_location_off_dialog_message"
settings:controller="com.android.settings.display.TwilightLocationPreferenceController"/>
<DropDownPreference
android:key="dark_ui_auto_mode"
android:title="@string/dark_ui_auto_mode_title"
android:summary="%s"
android:entries="@array/dark_ui_scheduler_preference_titles"
android:entryValues="@array/dark_ui_scheduler_preference_titles"
settings:allowDividerAbove="true"
settings:controller="com.android.settings.display.darkmode.DarkModeScheduleSelectorController"
settings:keywords="@string/keywords_dark_ui_mode"/>
<PreferenceCategory
android:key="display_category"
android:title="@string/accessibility_screen_option">
<Preference
android:key="dark_theme_start_time"
android:title="@string/night_display_start_time_title"
settings:searchable="false"/>
<SwitchPreferenceCompat
android:key="toggle_force_invert"
android:summary="@string/accessibility_force_invert_summary"
android:title="@string/accessibility_force_invert_title"
settings:controller="com.android.settings.accessibility.ToggleForceInvertPreferenceController"/>
<Preference
android:key="dark_theme_end_time"
android:title="@string/night_display_end_time_title"
settings:searchable="false"/>
<DropDownPreference
android:key="dark_ui_auto_mode"
android:title="@string/dark_ui_auto_mode_title"
android:summary="%s"
android:entries="@array/dark_ui_scheduler_preference_titles"
android:entryValues="@array/dark_ui_scheduler_preference_titles"
settings:controller="com.android.settings.display.darkmode.DarkModeScheduleSelectorController"
settings:keywords="@string/keywords_dark_ui_mode"/>
<Preference
android:key="dark_theme_start_time"
android:title="@string/night_display_start_time_title"
settings:searchable="false"/>
<Preference
android:key="dark_theme_end_time"
android:title="@string/night_display_end_time_title"
settings:searchable="false"/>
</PreferenceCategory>
<com.android.settingslib.widget.FooterPreference
android:key="dark_theme_custom_bedtime_footer"

View File

@@ -44,6 +44,12 @@
android:name="classname"
android:value="com.android.settings.applications.appinfo.AppLocaleDetails" />
</Preference>
<Preference
android:key="terms_of_address_in_more_language_settings"
android:title="@string/terms_of_address_title"
android:summary="@string/terms_of_address_summary"
android:fragment="com.android.settings.localepicker.TermsOfAddressFragment"
settings:controller="com.android.settings.localepicker.NewTermsOfAddressController"/>
</PreferenceCategory>
<PreferenceCategory

View File

@@ -22,7 +22,6 @@ import android.hardware.display.ColorDisplayManager;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.view.accessibility.Flags;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -30,7 +29,6 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.TwoStatePreference;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
@@ -51,8 +49,6 @@ public class ColorAndMotionFragment extends DashboardFragment {
// Preferences
private static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN = "daltonizer_preference";
private static final String TOGGLE_LARGE_POINTER_ICON = "toggle_large_pointer_icon";
@VisibleForTesting
static final String TOGGLE_FORCE_INVERT = "toggle_force_invert";
private Preference mDisplayDaltonizerPreferenceScreen;
private TwoStatePreference mToggleDisableAnimationsPreference;
@@ -77,9 +73,6 @@ public class ColorAndMotionFragment extends DashboardFragment {
mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_QS_TARGETS);
if (Flags.forceInvertColor()) {
mShortcutFeatureKeys.add(ToggleForceInvertPreferenceController.SETTINGS_KEY);
}
mSettingsContentObserver = new AccessibilitySettingsContentObserver(new Handler());
mSettingsContentObserver.registerKeysToObserverCallback(mShortcutFeatureKeys,

View File

@@ -101,7 +101,7 @@ public abstract class HearingDeviceAudioRoutingBasePreferenceController extends
final List<AudioProductStrategy> supportedStrategies =
mAudioRoutingHelper.getSupportedStrategies(audioAttributes);
final AudioDeviceAttributes hearingDeviceAttributes =
mAudioRoutingHelper.getMatchedHearingDeviceAttributes(hearingDevice);
mAudioRoutingHelper.getMatchedHearingDeviceAttributesForOutput(hearingDevice);
if (hearingDeviceAttributes == null) {
if (DEBUG) {
Log.d(TAG,

View File

@@ -123,7 +123,7 @@ public class HighContrastTextMigrationReceiver extends BroadcastReceiver {
R.string.accessibility_notification_high_contrast_text_title))
.setContentText(context.getString(
R.string.accessibility_notification_high_contrast_text_content))
.setAutoCancel(true);
.setFlag(Notification.FLAG_NO_CLEAR, true);
Intent settingsIntent = new Intent(Settings.ACTION_TEXT_READING_SETTINGS);
settingsIntent.setPackage(context.getPackageName());
@@ -142,9 +142,11 @@ public class HighContrastTextMigrationReceiver extends BroadcastReceiver {
settingsPendingIntent
).build();
notificationBuilder.addAction(settingsAction);
notificationBuilder
.setContentIntent(settingsPendingIntent)
.addAction(settingsAction)
.setAutoCancel(true);
}
NotificationManager notificationManager =
context.getSystemService(NotificationManager.class);
NotificationChannel notificationChannel = new NotificationChannel(

View File

@@ -16,11 +16,16 @@
package com.android.settings.accessibility;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import android.content.Context;
import android.content.res.Configuration;
import android.provider.Settings;
import android.view.accessibility.Flags;
import androidx.annotation.VisibleForTesting;
import androidx.annotation.NonNull;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
@@ -28,27 +33,28 @@ import com.android.settings.core.TogglePreferenceController;
/** A toggle preference controller for force invert (force dark). */
public class ToggleForceInvertPreferenceController extends TogglePreferenceController {
public static final String SETTINGS_KEY =
Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED;
@VisibleForTesting
static final int ON = 1;
@VisibleForTesting
static final int OFF = 0;
public ToggleForceInvertPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
public boolean isChecked() {
return Settings.Secure.getInt(mContext.getContentResolver(), SETTINGS_KEY, OFF) != OFF;
return Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, OFF) != OFF;
}
@Override
public boolean setChecked(boolean isChecked) {
return Settings.Secure.putInt(mContext.getContentResolver(),
SETTINGS_KEY, isChecked ? ON : OFF);
Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, isChecked ? ON : OFF);
}
@Override
public void updateState(@NonNull Preference preference) {
super.updateState(preference);
final boolean isDarkModeActivated = (mContext.getResources().getConfiguration().uiMode
& Configuration.UI_MODE_NIGHT_YES) != 0;
preference.setEnabled(isDarkModeActivated);
}
@Override

View File

@@ -37,7 +37,6 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.SetupWizardUtils;
import com.android.settings.Utils;
import com.android.settings.flags.Flags;
import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.password.ConfirmDeviceCredentialActivity;
@@ -552,11 +551,8 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
@NonNull
protected PorterDuffColorFilter getIconColorFilter() {
if (mIconColorFilter == null) {
final int colorType = Flags.biometricsOnboardingEducation()
? DynamicColorPalette.ColorType.PRIMARY_TEXT
: DynamicColorPalette.ColorType.ACCENT;
mIconColorFilter = new PorterDuffColorFilter(
DynamicColorPalette.getColor(this, colorType),
DynamicColorPalette.getColor(this, DynamicColorPalette.ColorType.ACCENT),
PorterDuff.Mode.SRC_IN);
}
return mIconColorFilter;

View File

@@ -53,7 +53,6 @@ import com.android.settings.biometrics.BiometricEnrollActivity;
import com.android.settings.biometrics.BiometricEnrollIntroduction;
import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.biometrics.MultiBiometricEnrollHelper;
import com.android.settings.flags.Flags;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.password.SetupSkipDialog;
import com.android.settings.utils.SensorPrivacyManagerHelper;
@@ -145,19 +144,6 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
final ImageView iconLooking = findViewById(R.id.icon_looking);
iconGlasses.getBackground().setColorFilter(getIconColorFilter());
iconLooking.getBackground().setColorFilter(getIconColorFilter());
if (Flags.biometricsOnboardingEducation()) {
final ImageView iconSecurityPrivacySafe = findViewById(R.id.icon_security_privacy_safe);
final ImageView iconPrivacyTip = findViewById(R.id.icon_privacy_tip);
final ImageView iconFamiliarFaceAndZone =
findViewById(R.id.icon_familiar_face_and_zone);
final ImageView iconTrashCan = findViewById(R.id.icon_trash_can);
final ImageView iconLink = findViewById(R.id.icon_link);
iconSecurityPrivacySafe.getBackground().setColorFilter(getIconColorFilter());
iconPrivacyTip.getBackground().setColorFilter(getIconColorFilter());
iconFamiliarFaceAndZone.getBackground().setColorFilter(getIconColorFilter());
iconTrashCan.getBackground().setColorFilter(getIconColorFilter());
iconLink.getBackground().setColorFilter(getIconColorFilter());
}
// Set text for views with multiple variations.
final TextView infoMessageGlasses = findViewById(R.id.info_message_glasses);
@@ -170,19 +156,9 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
infoMessageLooking.setText(getInfoMessageLooking());
inControlTitle.setText(getInControlTitle());
howMessage.setText(getHowMessage());
if (Flags.biometricsOnboardingEducation()) {
inControlMessage.setText(
R.string.security_settings_face_enroll_introduction_control_message_2);
final TextView learnMore = findViewById(R.id.message_learn_more);
learnMore.setText(Html.fromHtml(getString(
R.string.security_settings_face_enroll_introduction_learn_more_message),
Html.FROM_HTML_MODE_LEGACY));
learnMore.setMovementMethod(LinkMovementMethod.getInstance());
} else {
inControlMessage.setText(Html.fromHtml(getString(getInControlMessage()),
Html.FROM_HTML_MODE_LEGACY));
inControlMessage.setMovementMethod(LinkMovementMethod.getInstance());
}
inControlMessage.setText(Html.fromHtml(getString(getInControlMessage()),
Html.FROM_HTML_MODE_LEGACY));
inControlMessage.setMovementMethod(LinkMovementMethod.getInstance());
lessSecure.setText(getLessSecureMessage());
final ScrollView scrollView =
@@ -435,11 +411,7 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
@Override
protected int getLayoutResource() {
if (Flags.biometricsOnboardingEducation()) {
return R.layout.face_enroll_introduction_2;
} else {
return R.layout.face_enroll_introduction;
}
return R.layout.face_enroll_introduction;
}
@Override
@@ -622,13 +594,8 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
setDescriptionText(getString(
R.string.private_space_face_enroll_introduction_message));
} else if (mIsFaceStrong) {
final int messageRes;
if (Flags.biometricsOnboardingEducation()) {
messageRes = R.string.security_settings_face_enroll_introduction_message_class3_2;
} else {
messageRes = R.string.security_settings_face_enroll_introduction_message_class3;
}
setDescriptionText(getString(messageRes));
setDescriptionText(getString(
R.string.security_settings_face_enroll_introduction_message_class3));
}
super.updateDescriptionText();
}

View File

@@ -37,8 +37,8 @@ import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.bluetooth.AmbientVolumeUi;
import com.android.settingslib.widget.SliderPreference;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
@@ -68,12 +68,12 @@ public class AmbientVolumePreference extends PreferenceGroup implements AmbientV
private boolean mExpanded = false;
private boolean mMutable = false;
private boolean mMuted = false;
private final BiMap<Integer, SeekBarPreference> mSideToSliderMap = HashBiMap.create();
private final BiMap<Integer, SliderPreference> mSideToSliderMap = HashBiMap.create();
private int mVolumeLevel = AMBIENT_VOLUME_LEVEL_DEFAULT;
private final OnPreferenceChangeListener mPreferenceChangeListener =
(slider, v) -> {
if (slider instanceof SeekBarPreference && v instanceof final Integer value) {
if (slider instanceof SliderPreference && v instanceof final Integer value) {
final Integer side = mSideToSliderMap.inverse().get(slider);
if (mListener != null && side != null) {
mListener.onSliderValueChange(side, value);
@@ -173,8 +173,8 @@ public class AmbientVolumePreference extends PreferenceGroup implements AmbientV
}
mMuted = muted;
if (mMutable && mMuted) {
for (SeekBarPreference slider : mSideToSliderMap.values()) {
slider.setProgress(slider.getMin());
for (SliderPreference slider : mSideToSliderMap.values()) {
slider.setValue(slider.getMin());
}
}
updateVolumeIcon();
@@ -198,7 +198,7 @@ public class AmbientVolumePreference extends PreferenceGroup implements AmbientV
if (!mSideToSliderMap.isEmpty()) {
for (int side : VALID_SIDES) {
final SeekBarPreference slider = mSideToSliderMap.get(side);
final SliderPreference slider = mSideToSliderMap.get(side);
if (slider != null && findPreference(slider.getKey()) == null) {
addPreference(slider);
}
@@ -209,7 +209,7 @@ public class AmbientVolumePreference extends PreferenceGroup implements AmbientV
@Override
public void setSliderEnabled(int side, boolean enabled) {
SeekBarPreference slider = mSideToSliderMap.get(side);
SliderPreference slider = mSideToSliderMap.get(side);
if (slider != null && slider.isEnabled() != enabled) {
slider.setEnabled(enabled);
updateLayout();
@@ -218,16 +218,16 @@ public class AmbientVolumePreference extends PreferenceGroup implements AmbientV
@Override
public void setSliderValue(int side, int value) {
SeekBarPreference slider = mSideToSliderMap.get(side);
if (slider != null && slider.getProgress() != value) {
slider.setProgress(value);
SliderPreference slider = mSideToSliderMap.get(side);
if (slider != null && slider.getValue() != value) {
slider.setValue(value);
updateVolumeLevel();
}
}
@Override
public void setSliderRange(int side, int min, int max) {
SeekBarPreference slider = mSideToSliderMap.get(side);
SliderPreference slider = mSideToSliderMap.get(side);
if (slider != null) {
slider.setMin(min);
slider.setMax(max);
@@ -243,7 +243,7 @@ public class AmbientVolumePreference extends PreferenceGroup implements AmbientV
slider.setVisible(mExpanded);
}
if (!slider.isEnabled()) {
slider.setProgress(slider.getMin());
slider.setValue(slider.getMin());
}
});
updateVolumeLevel();
@@ -265,14 +265,14 @@ public class AmbientVolumePreference extends PreferenceGroup implements AmbientV
}
private int getVolumeLevel(int side) {
SeekBarPreference slider = mSideToSliderMap.get(side);
SliderPreference slider = mSideToSliderMap.get(side);
if (slider == null || !slider.isEnabled()) {
return 0;
}
final double min = slider.getMin();
final double max = slider.getMax();
final double levelGap = (max - min) / 4.0;
final int value = slider.getProgress();
final int value = slider.getValue();
return (int) Math.ceil((value - min) / levelGap);
}
@@ -311,7 +311,7 @@ public class AmbientVolumePreference extends PreferenceGroup implements AmbientV
if (mSideToSliderMap.containsKey(side)) {
return;
}
SeekBarPreference slider = new SeekBarPreference(getContext());
SliderPreference slider = new SliderPreference(getContext());
slider.setKey(KEY_AMBIENT_VOLUME_SLIDER + "_" + side);
slider.setOrder(order);
slider.setOnPreferenceChangeListener(mPreferenceChangeListener);
@@ -326,7 +326,7 @@ public class AmbientVolumePreference extends PreferenceGroup implements AmbientV
}
@VisibleForTesting
Map<Integer, SeekBarPreference> getSliders() {
Map<Integer, SliderPreference> getSliders() {
return mSideToSliderMap;
}
}

View File

@@ -42,6 +42,7 @@ public class BluetoothDetailsHearingDeviceController extends BluetoothDetailsCon
public static final int ORDER_HEARING_DEVICE_SETTINGS = 1;
public static final int ORDER_HEARING_AIDS_PRESETS = 2;
public static final int ORDER_HEARING_DEVICE_INPUT_ROUTING = 3;
public static final int ORDER_AMBIENT_VOLUME = 4;
static final String KEY_HEARING_DEVICE_GROUP = "hearing_device_group";
@@ -62,10 +63,12 @@ public class BluetoothDetailsHearingDeviceController extends BluetoothDetailsCon
@VisibleForTesting
void setSubControllers(
BluetoothDetailsHearingDeviceSettingsController hearingDeviceSettingsController,
BluetoothDetailsHearingAidsPresetsController presetsController) {
BluetoothDetailsHearingAidsPresetsController presetsController,
BluetoothDetailsHearingDeviceInputRoutingController inputRoutingController) {
mControllers.clear();
mControllers.add(hearingDeviceSettingsController);
mControllers.add(presetsController);
mControllers.add(inputRoutingController);
}
@Override
@@ -112,6 +115,11 @@ public class BluetoothDetailsHearingDeviceController extends BluetoothDetailsCon
mControllers.add(new BluetoothDetailsAmbientVolumePreferenceController(mContext,
mManager, mFragment, mCachedDevice, mLifecycle));
}
if (com.android.settingslib.flags.Flags.hearingDevicesInputRoutingControl()) {
mControllers.add(
new BluetoothDetailsHearingDeviceInputRoutingController(mContext, mFragment,
mCachedDevice, mLifecycle));
}
}
@NonNull

View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) 2024 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.bluetooth;
import static com.android.settings.bluetooth.BluetoothDetailsHearingDeviceController.KEY_HEARING_DEVICE_GROUP;
import static com.android.settings.bluetooth.BluetoothDetailsHearingDeviceController.ORDER_HEARING_DEVICE_INPUT_ROUTING;
import android.content.Context;
import android.media.AudioManager;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.bluetooth.HearingDeviceInputRoutingPreference.InputRoutingValue;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.HapClientProfile;
import com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants;
import com.android.settingslib.bluetooth.HearingAidAudioRoutingHelper;
import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.Arrays;
/**
* The controller of the hearing device input routing
*
* <p> It manages the input routing preference and update the routing according to the value.
*/
public class BluetoothDetailsHearingDeviceInputRoutingController extends
BluetoothDetailsController implements
HearingDeviceInputRoutingPreference.InputRoutingCallback {
private static final String TAG = "BluetoothDetailsHearingDeviceInputRoutingController";
static final String KEY_HEARING_DEVICE_INPUT_ROUTING = "hearing_device_input_routing";
private final HearingAidAudioRoutingHelper mAudioRoutingHelper;
private final AudioManager mAudioManager;
public BluetoothDetailsHearingDeviceInputRoutingController(
@NonNull Context context,
@NonNull PreferenceFragmentCompat fragment,
@NonNull CachedBluetoothDevice device,
@NonNull Lifecycle lifecycle) {
super(context, fragment, device, lifecycle);
mAudioRoutingHelper = new HearingAidAudioRoutingHelper(context);
mAudioManager = mContext.getSystemService(AudioManager.class);
}
@Override
public boolean isAvailable() {
boolean isSupportedProfile = mCachedDevice.getProfiles().stream().anyMatch(
profile -> profile instanceof HapClientProfile);
boolean isSupportedInputDevice = Arrays.stream(
mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).anyMatch(
info -> mCachedDevice.getAddress().equals(info.getAddress()));
if (isSupportedProfile && !isSupportedInputDevice) {
Log.d(TAG, "Not supported input type hearing device.");
}
return isSupportedProfile && isSupportedInputDevice;
}
@Override
protected void init(PreferenceScreen screen) {
PreferenceCategory hearingCategory = screen.findPreference(KEY_HEARING_DEVICE_GROUP);
if (hearingCategory != null) {
hearingCategory.addPreference(
createInputRoutingPreference(hearingCategory.getContext()));
}
}
@Override
protected void refresh() {}
@Nullable
@Override
public String getPreferenceKey() {
return KEY_HEARING_DEVICE_INPUT_ROUTING;
}
private HearingDeviceInputRoutingPreference createInputRoutingPreference(Context context) {
HearingDeviceInputRoutingPreference pref = new HearingDeviceInputRoutingPreference(context);
pref.setKey(KEY_HEARING_DEVICE_INPUT_ROUTING);
pref.setOrder(ORDER_HEARING_DEVICE_INPUT_ROUTING);
pref.setTitle(context.getString(R.string.bluetooth_hearing_device_input_routing_title));
pref.setChecked(getUserPreferredInputRoutingValue());
pref.setInputRoutingCallback(this);
return pref;
}
@InputRoutingValue
private int getUserPreferredInputRoutingValue() {
return mCachedDevice.getDevice().isMicrophonePreferredForCalls()
? InputRoutingValue.HEARING_DEVICE : InputRoutingValue.BUILTIN_MIC;
}
@Override
public void onInputRoutingUpdated(int selectedInputRoutingUiValue) {
boolean useBuiltinMic =
(selectedInputRoutingUiValue == InputRoutingValue.BUILTIN_MIC);
boolean status = mAudioRoutingHelper.setPreferredInputDeviceForCalls(mCachedDevice,
useBuiltinMic ? HearingAidAudioRoutingConstants.RoutingValue.BUILTIN_DEVICE
: HearingAidAudioRoutingConstants.RoutingValue.AUTO);
if (!status) {
Log.d(TAG, "Fail to configure setPreferredInputDeviceForCalls");
}
mCachedDevice.getDevice().setMicrophonePreferredForCalls(!useBuiltinMic);
}
}

View File

@@ -373,6 +373,7 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
}
mFormatter.updateLayout(FragmentTypeModel.DeviceDetailsMainFragment.INSTANCE);
}
setDivider(null);
}
@Override

View File

@@ -0,0 +1,172 @@
/*
* Copyright (C) 2024 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.bluetooth;
import android.content.Context;
import android.content.DialogInterface;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RadioGroup;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.settings.R;
import com.android.settingslib.CustomDialogPreferenceCompat;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
* Preference for controlling the input routing for hearing device.
*
* <p> This preference displays a dialog that allows users to choose which input device that want to
* use when using this hearing device.
*/
public class HearingDeviceInputRoutingPreference extends CustomDialogPreferenceCompat {
/**
* Annotations for possible input routing UI for this hearing device input routing preference.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({
InputRoutingValue.HEARING_DEVICE,
InputRoutingValue.BUILTIN_MIC
})
public @interface InputRoutingValue {
int HEARING_DEVICE = 0;
int BUILTIN_MIC = 1;
}
private static final int INVALID_ID = -1;
private final Context mContext;
private final int mFromHearingDeviceButtonId = R.id.input_from_hearing_device;
private final int mFromBuiltinMicButtonId = R.id.input_from_builtin_mic;
@Nullable
private RadioGroup mInputRoutingGroup;
@Nullable
private InputRoutingCallback mCallback;
// Default value is hearing device as input
@InputRoutingValue
private int mSelectedInputRoutingValue = InputRoutingValue.HEARING_DEVICE;
public HearingDeviceInputRoutingPreference(@NonNull Context context) {
this(context, null);
}
public HearingDeviceInputRoutingPreference(@NonNull Context context,
@Nullable AttributeSet attrs) {
super(context, attrs);
mContext = context;
setDialogTitle(R.string.bluetooth_hearing_device_input_routing_dialog_title);
setDialogLayoutResource(R.layout.hearing_device_input_routing_dialog);
setNegativeButtonText(R.string.cancel);
setPositiveButtonText(R.string.done_button);
}
/**
* Sets the callback to receive input routing updates.
*/
public void setInputRoutingCallback(@NonNull InputRoutingCallback callback) {
mCallback = callback;
}
/**
* Sets the {@link InputRoutingValue} value to determine which radio button should be checked,
* and also update summary accordingly.
*
* @param inputRoutingValue The input routing value.
*/
public void setChecked(@InputRoutingValue int inputRoutingValue) {
mSelectedInputRoutingValue = inputRoutingValue;
setSummary(getSummary());
}
@Override
protected void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
int prevBtnId = getRadioButtonId(mSelectedInputRoutingValue);
int curBtnId = Objects.requireNonNull(mInputRoutingGroup).getCheckedRadioButtonId();
if (prevBtnId == curBtnId) {
return;
}
setChecked(getSelectedInputRoutingValue());
if (mCallback != null) {
mCallback.onInputRoutingUpdated(mSelectedInputRoutingValue);
}
}
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
mInputRoutingGroup = view.requireViewById(R.id.input_routing_group);
mInputRoutingGroup.check(getRadioButtonId(mSelectedInputRoutingValue));
}
@Nullable
@Override
public CharSequence getSummary() {
return switch (mSelectedInputRoutingValue) {
case InputRoutingValue.HEARING_DEVICE -> mContext.getResources().getString(
R.string.bluetooth_hearing_device_input_routing_hearing_device_option);
case InputRoutingValue.BUILTIN_MIC -> mContext.getResources().getString(
R.string.bluetooth_hearing_device_input_routing_builtin_option);
default -> null;
};
}
private int getRadioButtonId(@InputRoutingValue int inputRoutingValue) {
return switch (inputRoutingValue) {
case InputRoutingValue.HEARING_DEVICE -> mFromHearingDeviceButtonId;
case InputRoutingValue.BUILTIN_MIC -> mFromBuiltinMicButtonId;
default -> INVALID_ID;
};
}
@InputRoutingValue
private int getSelectedInputRoutingValue() {
int checkedId = Objects.requireNonNull(mInputRoutingGroup).getCheckedRadioButtonId();
if (checkedId == mFromBuiltinMicButtonId) {
return InputRoutingValue.BUILTIN_MIC;
} else {
// Should always return default value hearing device as input if something error
// happens.
return InputRoutingValue.HEARING_DEVICE;
}
}
/**
* Callback to be invoked when input routing changes.
*/
public interface InputRoutingCallback {
/**
* Called when the positive button is clicked and input routing is changed.
*
* @param selectedInputRoutingValue The selected input routing value.
*/
void onInputRoutingUpdated(@InputRoutingValue int selectedInputRoutingValue);
}
}

View File

@@ -92,7 +92,17 @@ public class GraphicsDriverEnableAngleAsSystemDriverController
// This can be enabled by calling:
// `adb shell setprop debug.graphics.angle.developeroption.enable true`
private boolean isAngleDeveloperOptionEnabled() {
return mSystemProperties.getBoolean(PROPERTY_DEBUG_ANGLE_DEVELOPER_OPTION, false);
boolean intendedUsingAngleDeveloperOption =
mSystemProperties.getBoolean(PROPERTY_DEBUG_ANGLE_DEVELOPER_OPTION, false);
if (intendedUsingAngleDeveloperOption) {
Log.v(TAG,
"ANGLE developer option is enabled in system properties, "
+ "but temporarily overridden.");
}
// Temporarily disabling for broader rollout.
// The feature requires further maturation before general availability.
return false;
}
@VisibleForTesting

View File

@@ -77,6 +77,10 @@ class AdaptiveSleepPreference :
override fun storage(context: Context): KeyValueStore = Storage(context)
override fun getReadPermissions(context: Context) = SettingsSecureStore.getReadPermissions()
override fun getWritePermissions(context: Context) = SettingsSecureStore.getWritePermissions()
override fun getReadPermit(context: Context, callingPid: Int, callingUid: Int) =
ReadWritePermit.ALLOW

View File

@@ -50,6 +50,10 @@ class PeakRefreshRateSwitchPreference :
override fun storage(context: Context): KeyValueStore =
PeakRefreshRateStore(context, SettingsSystemStore.get(context))
override fun getReadPermissions(context: Context) = SettingsSystemStore.getReadPermissions()
override fun getWritePermissions(context: Context) = SettingsSystemStore.getWritePermissions()
override fun getReadPermit(context: Context, callingPid: Int, callingUid: Int) =
ReadWritePermit.ALLOW

View File

@@ -16,6 +16,7 @@
package com.android.settings.display.darkmode
import android.Manifest
import android.app.UiModeManager
import android.content.BroadcastReceiver
import android.content.Context
@@ -29,6 +30,7 @@ import com.android.settings.flags.Flags
import com.android.settingslib.PrimarySwitchPreference
import com.android.settingslib.datastore.KeyValueStore
import com.android.settingslib.datastore.NoOpKeyedObservable
import com.android.settingslib.datastore.Permissions
import com.android.settingslib.metadata.BooleanValue
import com.android.settingslib.metadata.PersistentPreference
import com.android.settingslib.metadata.PreferenceLifecycleContext
@@ -71,6 +73,11 @@ class DarkModeScreen :
override val keywords: Int
get() = R.string.keywords_dark_ui_mode
override fun getReadPermissions(context: Context) = Permissions.EMPTY
override fun getWritePermissions(context: Context) =
Permissions.allOf(Manifest.permission.MODIFY_DAY_NIGHT_MODE)
override fun getReadPermit(context: Context, callingPid: Int, callingUid: Int) =
ReadWritePermit.ALLOW

View File

@@ -0,0 +1,76 @@
/*
* Copyright (C) 2024 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.localepicker;
import android.content.Context;
import android.os.LocaleList;
import androidx.annotation.NonNull;
import com.android.internal.app.LocaleStore;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.flags.Flags;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
public class NewTermsOfAddressController extends BasePreferenceController {
public NewTermsOfAddressController(@NonNull Context context, @NonNull String preferenceKey) {
super(context, preferenceKey);
}
@Override
public int getAvailabilityStatus() {
if (Flags.regionalPreferencesApiEnabled()) {
if (Flags.termsOfAddressEnabled()) {
return checkAvailabilityStatus();
}
}
return CONDITIONALLY_UNAVAILABLE;
}
private int checkAvailabilityStatus() {
// If language is not available for system language, or if ToA does not apply to
// system language, we will hide it.
final Locale defaultLocale = Locale.getDefault();
LocaleStore.LocaleInfo localeInfo = LocaleStore.getLocaleInfo(defaultLocale);
final List<String> supportedLanguageList = Arrays.asList(
mContext.getResources().getStringArray(
R.array.terms_of_address_supported_languages));
final List<String> notSupportedLocaleList = Arrays.asList(
mContext.getResources().getStringArray(
R.array.terms_of_address_unsupported_locales));
final Locale locale = localeInfo.getLocale().stripExtensions();
final String language = locale.getLanguage();
final String localeTag = locale.toLanguageTag();
// Supported locales:
// 1. All French is supported except fr-CA.
// 2. QA language en-XA (LTR pseudo locale), ar_XB (RTL pseudo locale).
if ((supportedLanguageList.contains(language)
&& !notSupportedLocaleList.contains(localeTag))
|| LocaleList.isPseudoLocale(locale)) {
return AVAILABLE;
}
return CONDITIONALLY_UNAVAILABLE;
}
}

View File

@@ -20,7 +20,6 @@ import static com.android.settings.flags.Flags.termsOfAddressEnabled;
import android.content.Context;
import android.os.LocaleList;
import android.text.TextUtils;
import android.util.Log;
import androidx.preference.PreferenceCategory;
@@ -28,6 +27,7 @@ import androidx.preference.PreferenceScreen;
import com.android.internal.app.LocaleStore;
import com.android.settings.R;
import com.android.settings.flags.Flags;
import com.android.settings.widget.PreferenceCategoryController;
import java.util.Arrays;
@@ -64,6 +64,9 @@ public class TermsOfAddressCategoryController extends PreferenceCategoryControll
@Override
public int getAvailabilityStatus() {
if (Flags.regionalPreferencesApiEnabled()) {
return CONDITIONALLY_UNAVAILABLE;
}
if (!termsOfAddressEnabled()) {
return CONDITIONALLY_UNAVAILABLE;

View File

@@ -468,7 +468,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
final MenuItem item = menu.add(Menu.NONE, R.id.edit_sim_name, Menu.NONE,
R.string.mobile_network_sim_name);
R.string.mobile_network_sim_label_color_title);
item.setIcon(com.android.internal.R.drawable.ic_mode_edit);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}

View File

@@ -25,6 +25,7 @@ import com.android.settingslib.spaprivileged.framework.common.broadcastReceiverF
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
class WifiRepository(
private val context: Context,
@@ -32,11 +33,13 @@ class WifiRepository(
context.broadcastReceiverFlow(IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION)),
) {
fun wifiStateFlow() = wifiStateChangedActionFlow
.map { intent ->
intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN)
}
.onEach { Log.d(TAG, "wifiStateFlow: $it") }
fun wifiStateFlow(): Flow<Int> =
wifiStateChangedActionFlow
.map { intent ->
intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN)
}
.onStart { emit(WifiManager.WIFI_STATE_UNKNOWN) }
.onEach { Log.d(TAG, "wifiStateFlow: $it") }
private companion object {
private const val TAG = "WifiRepository"

View File

@@ -16,14 +16,10 @@
package com.android.settings.accessibility;
import static android.view.accessibility.Flags.FLAG_FORCE_INVERT_COLOR;
import static com.google.common.truth.Truth.assertThat;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
@@ -73,20 +69,6 @@ public class ColorAndMotionFragmentTest {
}
@Test
@RequiresFlagsEnabled(FLAG_FORCE_INVERT_COLOR)
public void forceInvertEnabled_getNonIndexableKeys_existInXmlLayout() {
final List<String> niks = ColorAndMotionFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext,
R.xml.accessibility_color_and_motion);
assertThat(niks).doesNotContain(ColorAndMotionFragment.TOGGLE_FORCE_INVERT);
assertThat(keys).containsAtLeastElementsIn(niks);
}
@Test
@RequiresFlagsDisabled(FLAG_FORCE_INVERT_COLOR)
public void getNonIndexableKeys_existInXmlLayout() {
final List<String> niks = ColorAndMotionFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
@@ -94,7 +76,6 @@ public class ColorAndMotionFragmentTest {
XmlTestUtils.getKeysFromPreferenceXml(mContext,
R.xml.accessibility_color_and_motion);
assertThat(niks).contains(ColorAndMotionFragment.TOGGLE_FORCE_INVERT);
assertThat(keys).containsAtLeastElementsIn(niks);
}
}

View File

@@ -108,7 +108,7 @@ public class HearingDeviceAudioRoutingBasePreferenceControllerTest {
when(mBluetoothDevice.getAnonymizedAddress()).thenReturn(TEST_DEVICE_ADDRESS);
when(mCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
doReturn(hearingDeviceAttribute).when(
mAudioRoutingHelper).getMatchedHearingDeviceAttributes(any());
mAudioRoutingHelper).getMatchedHearingDeviceAttributesForOutput(any());
when(mAudioProductStrategyMedia.getAudioAttributesForLegacyStreamType(
AudioManager.STREAM_MUSIC)).thenReturn((new AudioAttributes.Builder()).build());
when(mAudioRoutingHelper.getAudioProductStrategies()).thenReturn(
@@ -143,7 +143,8 @@ public class HearingDeviceAudioRoutingBasePreferenceControllerTest {
@Test
public void onPreferenceChange_noMatchedDeviceAttributes_notCallSetStrategies() {
when(mAudioRoutingHelper.getMatchedHearingDeviceAttributes(any())).thenReturn(null);
when(mAudioRoutingHelper.getMatchedHearingDeviceAttributesForOutput(any())).thenReturn(
null);
verify(mAudioRoutingHelper, never()).setPreferredDeviceRoutingStrategies(any(), isNull(),
anyInt());

View File

@@ -23,13 +23,18 @@ import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.content.res.Configuration;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
import androidx.preference.Preference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
@@ -52,10 +57,7 @@ public class ToggleForceInvertPreferenceControllerTest {
@Before
public void setUp() {
mController = new ToggleForceInvertPreferenceController(
mContext,
ColorAndMotionFragment.TOGGLE_FORCE_INVERT
);
mController = new ToggleForceInvertPreferenceController(mContext, "toggle_force_invert");
}
@Test
@@ -72,6 +74,30 @@ public class ToggleForceInvertPreferenceControllerTest {
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void updateState_darkModeOn_preferenceEnabled() {
Configuration config = mContext.getResources().getConfiguration();
config.uiMode = Configuration.UI_MODE_NIGHT_YES;
mContext.getResources().updateConfiguration(config, null);
Preference preference = mock(Preference.class);
mController.updateState(preference);
verify(preference).setEnabled(true);
}
@Test
public void updateState_darkModeOff_preferenceDisabled() {
Configuration config = mContext.getResources().getConfiguration();
config.uiMode = Configuration.UI_MODE_NIGHT_NO;
mContext.getResources().updateConfiguration(config, null);
Preference preference = mock(Preference.class);
mController.updateState(preference);
verify(preference).setEnabled(false);
}
@Test
public void settingOff_reflectsCorrectValue() {
setEnabled(false);

View File

@@ -64,7 +64,6 @@ import com.android.settings.R;
import com.android.settings.Settings;
import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.flags.Flags;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.SettingsShadowResources;
@@ -403,9 +402,7 @@ public class FaceEnrollIntroductionTest {
assertThat(getGlifLayout(mActivity).getDescriptionText().toString()).isEqualTo(
mContext.getString(
Flags.biometricsOnboardingEducation()
? R.string.security_settings_face_enroll_introduction_message_class3_2
: R.string.security_settings_face_enroll_introduction_message_class3));
R.string.security_settings_face_enroll_introduction_message_class3));
assertThat(mActivity.findViewById(R.id.info_row_less_secure).getVisibility()).isEqualTo(
View.GONE);
}

View File

@@ -41,8 +41,8 @@ import androidx.preference.PreferenceViewHolder;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.bluetooth.AmbientVolumeUi;
import com.android.settingslib.widget.SliderPreference;
import org.junit.Before;
import org.junit.Rule;
@@ -99,13 +99,13 @@ public class AmbientVolumePreferenceTest {
slider.setMax(4);
if (side == SIDE_LEFT) {
slider.setKey(KEY_LEFT_SLIDER);
slider.setProgress(TEST_LEFT_VOLUME_LEVEL);
slider.setValue(TEST_LEFT_VOLUME_LEVEL);
} else if (side == SIDE_RIGHT) {
slider.setKey(KEY_RIGHT_SLIDER);
slider.setProgress(TEST_RIGHT_VOLUME_LEVEL);
slider.setValue(TEST_RIGHT_VOLUME_LEVEL);
} else {
slider.setKey(KEY_UNIFIED_SLIDER);
slider.setProgress(TEST_UNIFIED_VOLUME_LEVEL);
slider.setValue(TEST_UNIFIED_VOLUME_LEVEL);
}
});
@@ -223,7 +223,7 @@ public class AmbientVolumePreferenceTest {
private void assertControlUiCorrect() {
final boolean expanded = mPreference.isExpanded();
Map<Integer, SeekBarPreference> sliders = mPreference.getSliders();
Map<Integer, SliderPreference> sliders = mPreference.getSliders();
assertThat(sliders.get(SIDE_UNIFIED).isVisible()).isEqualTo(!expanded);
assertThat(sliders.get(SIDE_LEFT).isVisible()).isEqualTo(expanded);
assertThat(sliders.get(SIDE_RIGHT).isVisible()).isEqualTo(expanded);

View File

@@ -56,6 +56,8 @@ public class BluetoothDetailsHearingDeviceControllerTest extends
private BluetoothDetailsHearingAidsPresetsController mPresetsController;
@Mock
private BluetoothDetailsHearingDeviceSettingsController mHearingDeviceSettingsController;
@Mock
private BluetoothDetailsHearingDeviceInputRoutingController mInputRoutingController;
private BluetoothDetailsHearingDeviceController mHearingDeviceController;
@@ -67,7 +69,7 @@ public class BluetoothDetailsHearingDeviceControllerTest extends
mHearingDeviceController = new BluetoothDetailsHearingDeviceController(mContext,
mFragment, mLocalManager, mCachedDevice, mLifecycle);
mHearingDeviceController.setSubControllers(mHearingDeviceSettingsController,
mPresetsController);
mPresetsController, mInputRoutingController);
}
@Test
@@ -84,6 +86,13 @@ public class BluetoothDetailsHearingDeviceControllerTest extends
assertThat(mHearingDeviceController.isAvailable()).isTrue();
}
@Test
public void isAvailable_inputRoutingControllersAvailable_returnFalse() {
when(mInputRoutingController.isAvailable()).thenReturn(true);
assertThat(mHearingDeviceController.isAvailable()).isTrue();
}
@Test
public void isAvailable_noControllersAvailable_returnFalse() {
when(mHearingDeviceSettingsController.isAvailable()).thenReturn(false);
@@ -146,4 +155,24 @@ public class BluetoothDetailsHearingDeviceControllerTest extends
assertThat(mHearingDeviceController.getSubControllers().stream().anyMatch(
c -> c instanceof BluetoothDetailsAmbientVolumePreferenceController)).isFalse();
}
@Test
@RequiresFlagsEnabled(
com.android.settingslib.flags.Flags.FLAG_HEARING_DEVICES_INPUT_ROUTING_CONTROL)
public void initSubControllers_flagEnabled_inputRoutingControllerExist() {
mHearingDeviceController.initSubControllers(false);
assertThat(mHearingDeviceController.getSubControllers().stream().anyMatch(
c -> c instanceof BluetoothDetailsHearingDeviceInputRoutingController)).isTrue();
}
@Test
@RequiresFlagsDisabled(
com.android.settingslib.flags.Flags.FLAG_HEARING_DEVICES_INPUT_ROUTING_CONTROL)
public void initSubControllers_flagDisabled_inputRoutingControllerNotExist() {
mHearingDeviceController.initSubControllers(false);
assertThat(mHearingDeviceController.getSubControllers().stream().anyMatch(
c -> c instanceof BluetoothDetailsHearingDeviceInputRoutingController)).isFalse();
}
}

View File

@@ -0,0 +1,171 @@
/*
* Copyright (C) 2024 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.bluetooth;
import static com.android.settings.bluetooth.BluetoothDetailsHearingDeviceController.KEY_HEARING_DEVICE_GROUP;
import static com.android.settings.bluetooth.BluetoothDetailsHearingDeviceInputRoutingController.KEY_HEARING_DEVICE_INPUT_ROUTING;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothDevice;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.bluetooth.HearingDeviceInputRoutingPreference.InputRoutingValue;
import com.android.settingslib.bluetooth.HapClientProfile;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import java.util.Collections;
import java.util.List;
/** Tests for {@link BluetoothDetailsHearingDeviceInputRoutingController}. */
@RunWith(RobolectricTestRunner.class)
public class BluetoothDetailsHearingDeviceInputRoutingControllerTest extends
BluetoothDetailsControllerTestBase {
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
private static final String TEST_ADDRESS = "55:66:77:88:99:AA";
@Mock
private BluetoothDevice mBluetoothDevice;
@Mock
private HapClientProfile mHapClientProfile;
@Spy
private AudioManager mAudioManager;
private BluetoothDetailsHearingDeviceInputRoutingController mController;
@Override
public void setUp() {
super.setUp();
mContext = spy(ApplicationProvider.getApplicationContext());
mAudioManager = spy(mContext.getSystemService(AudioManager.class));
when(mContext.getSystemService(AudioManager.class)).thenReturn(mAudioManager);
setupDevice(makeDefaultDeviceConfig());
when(mCachedDevice.getDevice()).thenReturn(mBluetoothDevice);
PreferenceCategory deviceControls = new PreferenceCategory(mContext);
deviceControls.setKey(KEY_HEARING_DEVICE_GROUP);
mScreen.addPreference(deviceControls);
mController = new BluetoothDetailsHearingDeviceInputRoutingController(mContext,
mFragment, mCachedDevice, mLifecycle);
}
@Test
public void init_getExpectedPreference() {
mController.init(mScreen);
Preference pref = mScreen.findPreference(KEY_HEARING_DEVICE_INPUT_ROUTING);
assertThat(pref.getKey()).isEqualTo(KEY_HEARING_DEVICE_INPUT_ROUTING);
}
@Test
public void init_setPreferredMicrophoneTrue_expectedSummary() {
when(mBluetoothDevice.isMicrophonePreferredForCalls()).thenReturn(true);
mController.init(mScreen);
Preference pref = mScreen.findPreference(KEY_HEARING_DEVICE_INPUT_ROUTING);
assertThat(pref.getSummary().toString()).isEqualTo(mContext.getString(
R.string.bluetooth_hearing_device_input_routing_hearing_device_option));
}
@Test
public void init_setPreferredMicrophoneFalse_expectedSummary() {
when(mBluetoothDevice.isMicrophonePreferredForCalls()).thenReturn(false);
mController.init(mScreen);
Preference pref = mScreen.findPreference(KEY_HEARING_DEVICE_INPUT_ROUTING);
assertThat(pref.getSummary().toString()).isEqualTo(mContext.getString(
R.string.bluetooth_hearing_device_input_routing_builtin_option));
}
@Test
public void onInputRoutingUpdated_hearingDevice_setMicrophonePreferredForCallsTrue() {
mController.init(mScreen);
mController.onInputRoutingUpdated(InputRoutingValue.HEARING_DEVICE);
verify(mBluetoothDevice).setMicrophonePreferredForCalls(true);
}
@Test
public void onInputRoutingUpdated_builtin_setMicrophonePreferredForCallsFalse() {
mController.init(mScreen);
mController.onInputRoutingUpdated(InputRoutingValue.BUILTIN_MIC);
verify(mBluetoothDevice).setMicrophonePreferredForCalls(false);
}
@Test
public void isAvailable_validInput_supportHapProfile_returnTrue() {
when(mCachedDevice.getAddress()).thenReturn(TEST_ADDRESS);
AudioDeviceInfo[] mockInfo = new AudioDeviceInfo[] {mockTestAddressInfo(TEST_ADDRESS)};
when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn(mockInfo);
when(mCachedDevice.getProfiles()).thenReturn(List.of(mHapClientProfile));
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void isAvailable_notSupportHapProfile_returnFalse() {
when(mCachedDevice.getAddress()).thenReturn(TEST_ADDRESS);
AudioDeviceInfo[] mockInfo = new AudioDeviceInfo[] {mockTestAddressInfo(TEST_ADDRESS)};
when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn(mockInfo);
when(mCachedDevice.getProfiles()).thenReturn(Collections.emptyList());
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isAvailable_notValidInputDevice_returnFalse() {
when(mCachedDevice.getAddress()).thenReturn(TEST_ADDRESS);
when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn(
new AudioDeviceInfo[] {});
when(mCachedDevice.getProfiles()).thenReturn(List.of(mHapClientProfile));
assertThat(mController.isAvailable()).isFalse();
}
private AudioDeviceInfo mockTestAddressInfo(String address) {
final AudioDeviceInfo info = mock(AudioDeviceInfo.class);
when(info.getType()).thenReturn(AudioDeviceInfo.TYPE_BLE_HEADSET);
when(info.getAddress()).thenReturn(address);
return info;
}
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright (C) 2024 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.bluetooth;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.RadioGroup;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.bluetooth.HearingDeviceInputRoutingPreference.InputRoutingValue;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link HearingDeviceInputRoutingPreference}. */
@RunWith(RobolectricTestRunner.class)
public class HearingDeviceInputRoutingPreferenceTest {
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
private final Context mContext = ApplicationProvider.getApplicationContext();
private HearingDeviceInputRoutingPreference mPreference;
private TestInputRoutingCallback mTestInputRoutingCallback;
private View mDialogView;
@Before
public void setup() {
mDialogView = LayoutInflater.from(mContext).inflate(
R.layout.hearing_device_input_routing_dialog, null);
mTestInputRoutingCallback = spy(new TestInputRoutingCallback());
mPreference = new HearingDeviceInputRoutingPreference(mContext);
}
@Test
public void onClick_checkToBuiltinMic_callbackWithBuiltinSpeaker() {
mPreference.setChecked(InputRoutingValue.HEARING_DEVICE);
mPreference.setInputRoutingCallback(mTestInputRoutingCallback);
mPreference.onBindDialogView(mDialogView);
RadioGroup radioGroup = mDialogView.requireViewById(R.id.input_routing_group);
Dialog dialog = mPreference.getDialog();
radioGroup.check(R.id.input_from_builtin_mic);
mPreference.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
verify(mTestInputRoutingCallback).onInputRoutingUpdated(InputRoutingValue.BUILTIN_MIC);
}
@Test
public void setChecked_checkNoChange_noCallback() {
mPreference.setChecked(InputRoutingValue.HEARING_DEVICE);
mPreference.setInputRoutingCallback(mTestInputRoutingCallback);
mPreference.onBindDialogView(mDialogView);
Dialog dialog = mPreference.getDialog();
mPreference.setChecked(InputRoutingValue.HEARING_DEVICE);
mPreference.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
verify(mTestInputRoutingCallback, never()).onInputRoutingUpdated(anyInt());
}
@Test
public void setChecked_builtinMic_expectedSummary() {
mPreference.setChecked(InputRoutingValue.BUILTIN_MIC);
assertThat(mPreference.getSummary().toString()).isEqualTo(
mContext.getString(R.string.bluetooth_hearing_device_input_routing_builtin_option));
}
@Test
public void setChecked_hearingDevice_expectedSummary() {
mPreference.setChecked(InputRoutingValue.HEARING_DEVICE);
assertThat(mPreference.getSummary().toString()).isEqualTo(mContext.getString(
R.string.bluetooth_hearing_device_input_routing_hearing_device_option));
}
private static class TestInputRoutingCallback implements
HearingDeviceInputRoutingPreference.InputRoutingCallback {
@Override
public void onInputRoutingUpdated(int selectedInputRoutingUiValue) {}
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.display.darkmode;
import static android.view.accessibility.Flags.FLAG_FORCE_INVERT_COLOR;
import static com.google.common.truth.Truth.assertThat;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.util.List;
/** Tests for {@link DarkModeSettingsFragment}. */
@RunWith(RobolectricTestRunner.class)
public class DarkModeSettingsFragmentTest {
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
private final Context mContext = ApplicationProvider.getApplicationContext();
private DarkModeSettingsFragment mFragment;
@Before
public void setUp() {
mFragment = new DarkModeSettingsFragment();
}
@Test
public void getMetricsCategory_returnsCorrectCategory() {
assertThat(mFragment.getMetricsCategory()).isEqualTo(
SettingsEnums.DARK_UI_SETTINGS);
}
@Test
public void getPreferenceScreenResId_returnsCorrectXml() {
assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(
R.xml.dark_mode_settings);
}
@Test
public void getLogTag_returnsCorrectTag() {
assertThat(mFragment.getLogTag()).isEqualTo("DarkModeSettingsFrag");
}
@Test
@RequiresFlagsEnabled(FLAG_FORCE_INVERT_COLOR)
public void getNonIndexableKeys_forceInvertEnabled_existInXmlLayout() {
final List<String> niks = DarkModeSettingsFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext,
R.xml.dark_mode_settings);
assertThat(niks).doesNotContain("toggle_force_invert");
assertThat(keys).containsAtLeastElementsIn(niks);
}
@Test
@RequiresFlagsDisabled(FLAG_FORCE_INVERT_COLOR)
public void getNonIndexableKeys_existInXmlLayout() {
final List<String> niks = DarkModeSettingsFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext,
R.xml.dark_mode_settings);
assertThat(niks).contains("toggle_force_invert");
assertThat(keys).containsAtLeastElementsIn(niks);
}
}

View File

@@ -21,8 +21,9 @@ import android.content.Intent
import android.net.wifi.WifiManager
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
import com.android.settingslib.spa.testutils.lastWithTimeoutOrNull
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.runBlocking
import org.junit.Test
@@ -33,16 +34,25 @@ class WifiRepositoryTest {
private val context: Context = ApplicationProvider.getApplicationContext()
private val mockWifiStateChangedActionFlow = flowOf(Intent().apply {
putExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_ENABLED)
})
private val repository = WifiRepository(context, mockWifiStateChangedActionFlow)
@Test
fun wifiStateFlow() = runBlocking {
val wifiState = repository.wifiStateFlow().firstWithTimeoutOrNull()
fun wifiStateFlow_enabled() = runBlocking {
val wifiStateChangedIntent =
Intent().apply {
putExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_ENABLED)
}
val repository = WifiRepository(context, flowOf(wifiStateChangedIntent))
val wifiState = repository.wifiStateFlow().lastWithTimeoutOrNull()
assertThat(wifiState).isEqualTo(WifiManager.WIFI_STATE_ENABLED)
}
@Test
fun wifiStateFlow_unknown() = runBlocking {
val repository = WifiRepository(context, emptyFlow())
val wifiState = repository.wifiStateFlow().lastWithTimeoutOrNull()
assertThat(wifiState).isEqualTo(WifiManager.WIFI_STATE_UNKNOWN)
}
}

View File

@@ -182,7 +182,7 @@ public class GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest {
@Test
public void updateState_PreferenceShouldEnabled() {
mController.updateState(mPreference);
assertThat(mPreference.isEnabled()).isTrue();
assertThat(mPreference.isEnabled()).isFalse();
}
@Test

View File

@@ -24,12 +24,17 @@ import static org.mockito.Mockito.spy;
import android.content.Context;
import android.os.Looper;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.flags.Flags;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
@@ -45,6 +50,8 @@ public class TermsOfAddressCategoryControllerTest {
private TermsOfAddressCategoryController mTermsOfAddressCategoryController;
private Locale mCacheLocale;
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -65,6 +72,7 @@ public class TermsOfAddressCategoryControllerTest {
}
@Test
@DisableFlags(Flags.FLAG_REGIONAL_PREFERENCES_API_ENABLED)
public void getAvailabilityStatus_returnAvailable() {
Locale.setDefault(Locale.forLanguageTag("fr-FR"));