Snap for 11635697 from 72abca0a95 to 24Q3-release

Change-Id: I17bad62f56062e0ae369fbda5b2c4802616efd99
This commit is contained in:
Android Build Coastguard Worker
2024-03-27 23:21:26 +00:00
56 changed files with 1175 additions and 170 deletions

View File

@@ -0,0 +1,11 @@
package: "com.android.settings.flags"
container: "system"
flag {
name: "datetime_feedback"
# "location" is used by the Android System Time team for feature flags.
namespace: "location"
description: "Enable the time feedback feature, a button to launch feedback in Date & Time Settings"
bug: "283239837"
}

View File

@@ -21,17 +21,17 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/color_contrast_preview_background"
android:importantForAccessibility="no"
android:paddingLeft="24dp" android:paddingLeft="24dp"
android:paddingRight="24dp" android:paddingRight="24dp"
android:paddingBottom="24dp" android:paddingBottom="24dp">
android:background="@drawable/color_contrast_preview_background">
<View <View
android:id="@+id/preview_background" android:id="@+id/preview_background"
android:background="?androidprv:attr/materialColorSurface"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:background="?androidprv:attr/materialColorSurface"
app:layout_constraintBottom_toTopOf="@+id/bottom_appbar_background" app:layout_constraintBottom_toTopOf="@+id/bottom_appbar_background"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@@ -41,21 +41,20 @@
android:id="@+id/preview" android:id="@+id/preview"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_margin="8dp" android:layout_margin="8dp"
android:gravity="center_horizontal"
android:text="@string/color_contrast_preview"
android:textColor="?androidprv:attr/textColorPrimary"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent" />
android:textColor="?androidprv:attr/textColorPrimary"
android:text="@string/color_contrast_preview" />
<View <View
android:id="@+id/email_background" android:id="@+id/email_background"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginLeft="12dp" android:layout_marginHorizontal="12dp"
android:layout_marginRight="12dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginBottom="24dp" android:layout_marginBottom="24dp"
android:background="@drawable/color_contrast_preview_dialog_background" android:background="@drawable/color_contrast_preview_dialog_background"
@@ -66,88 +65,137 @@
<ImageView <ImageView
android:id="@+id/ic_group" android:id="@+id/ic_group"
android:contentDescription="@null"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="14dp"
android:layout_marginTop="14dp" android:layout_marginTop="14dp"
android:layout_marginLeft="14dp" android:background="@drawable/color_contrast_preview_icon_group_background"
android:contentDescription="@null"
android:padding="8dp" android:padding="8dp"
android:src="@drawable/ic_group_24dp" android:src="@drawable/ic_group_24dp"
android:background="@drawable/color_contrast_preview_icon_group_background"
app:layout_constraintStart_toStartOf="@+id/email_background" app:layout_constraintStart_toStartOf="@+id/email_background"
app:layout_constraintTop_toTopOf="@+id/email_background" /> app:layout_constraintTop_toTopOf="@+id/email_background" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/email_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginStart="8dp"
android:layout_marginTop="17dp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toStartOf="@+id/ic_star"
app:layout_constraintStart_toEndOf="@id/ic_group"
app:layout_constraintTop_toTopOf="@+id/email_background">
<TextView <TextView
android:id="@+id/sender_name" android:id="@+id/sender_name"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="8dp" android:ellipsize="end"
android:layout_marginTop="17dp" android:maxLines="1"
android:paddingEnd="10dp"
android:text="@string/color_contrast_preview_sender_name"
android:textColor="?androidprv:attr/materialColorOnSurface" android:textColor="?androidprv:attr/materialColorOnSurface"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintStart_toEndOf="@+id/ic_group" app:layout_constraintEnd_toStartOf="@+id/email_tag"
app:layout_constraintTop_toTopOf="@+id/email_background" app:layout_constraintHorizontal_bias="0"
android:text="@string/color_contrast_preview_sender_name" /> app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_max="wrap"
app:layout_constraintWidth_percent="0.5" />
<TextView
android:id="@+id/email_tag"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/color_contrast_preview_tag_background"
android:ellipsize="end"
android:maxLines="1"
android:paddingHorizontal="4dp"
android:text="@string/color_contrast_preview_email_badge"
android:textColor="?androidprv:attr/materialColorOnSurface"
android:textSize="11sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/sender_name"
app:layout_constraintTop_toTopOf="@+id/sender_name"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_max="wrap"
app:layout_constraintWidth_percent="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView <TextView
android:id="@+id/date" android:id="@+id/date"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/color_contrast_preview_email_send_date"
android:textColor="?androidprv:attr/materialColorOnSurfaceVariant" android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
android:textSize="11sp" android:textSize="11sp"
app:layout_constraintStart_toStartOf="@+id/sender_name" app:layout_constrainedWidth="true"
app:layout_constraintTop_toBottomOf="@+id/sender_name" app:layout_constraintEnd_toEndOf="@+id/email_background"
android:text="@string/color_contrast_preview_email_send_date" /> app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/email_header"
<TextView app:layout_constraintTop_toBottomOf="@+id/email_header" />
android:id="@+id/email_tag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:paddingHorizontal="4dp"
android:textColor="?androidprv:attr/materialColorOnSurface"
android:background="@drawable/color_contrast_preview_tag_background"
android:textSize="11sp"
app:layout_constraintStart_toEndOf="@+id/sender_name"
app:layout_constraintTop_toTopOf="@+id/sender_name"
android:text="@string/color_contrast_preview_email_badge" />
<ImageView <ImageView
android:id="@+id/ic_star" android:id="@+id/ic_star"
android:contentDescription="@null"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="14dp" android:layout_marginTop="14dp"
android:layout_marginRight="14dp" android:layout_marginEnd="14dp"
android:background="@drawable/color_contrast_preview_icon_star_background"
android:contentDescription="@null"
android:padding="8dp" android:padding="8dp"
android:src="@drawable/ic_star_24dp" android:src="@drawable/ic_star_24dp"
android:background="@drawable/color_contrast_preview_icon_star_background"
app:layout_constraintEnd_toEndOf="@+id/email_background" app:layout_constraintEnd_toEndOf="@+id/email_background"
app:layout_constraintTop_toTopOf="@+id/email_background" /> app:layout_constraintTop_toTopOf="@+id/email_background" />
<View
android:id="@+id/email_main_background"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginHorizontal="14dp"
app:layout_constraintBottom_toBottomOf="@+id/email_background"
app:layout_constraintEnd_toEndOf="@+id/email_background"
app:layout_constraintStart_toStartOf="@+id/email_background"
app:layout_constraintTop_toBottomOf="@+id/date" />
<TextView <TextView
android:id="@+id/email_title" android:id="@+id/email_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="14dp" android:layout_marginTop="10dp"
android:layout_marginTop="62dp" android:ellipsize="end"
android:maxLines="1"
android:text="@string/color_contrast_preview_email_title"
android:textColor="?androidprv:attr/materialColorOnSurface" android:textColor="?androidprv:attr/materialColorOnSurface"
android:textSize="16sp" android:textSize="16sp"
app:layout_constraintStart_toStartOf="@+id/email_background" app:layout_constrainedWidth="true"
app:layout_constraintTop_toTopOf="@+id/email_background" app:layout_constraintEnd_toEndOf="@+id/email_main_background"
android:text="@string/color_contrast_preview_email_title" /> app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/email_main_background"
app:layout_constraintTop_toTopOf="@+id/email_main_background" />
<TextView <TextView
android:id="@+id/email_body" android:id="@+id/email_body"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:paddingBottom="8dp"
android:text="@string/color_contrast_preview_email_body"
android:textColor="?androidprv:attr/materialColorOnSurfaceVariant" android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
android:textSize="12sp" android:textSize="12sp"
android:paddingBottom="8dp" app:layout_constrainedWidth="true"
android:maxLines="2" app:layout_constraintEnd_toEndOf="@+id/email_main_background"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/email_title" app:layout_constraintStart_toStartOf="@+id/email_title"
app:layout_constraintTop_toBottomOf="@+id/email_title" app:layout_constraintTop_toBottomOf="@+id/email_title" />
android:text="@string/color_contrast_preview_email_body" />
<View <View
android:id="@+id/attachment_background" android:id="@+id/attachment_background"
@@ -161,13 +209,13 @@
<ImageView <ImageView
android:id="@+id/ic_article_filled" android:id="@+id/ic_article_filled"
android:contentDescription="@null"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@drawable/ic_article_filled_24dp" android:contentDescription="@null"
android:paddingVertical="6dp"
android:paddingStart="8dp" android:paddingStart="8dp"
android:paddingEnd="6dp" android:paddingEnd="6dp"
android:paddingVertical="6dp" android:src="@drawable/ic_article_filled_24dp"
app:layout_constraintStart_toStartOf="@+id/email_title" app:layout_constraintStart_toStartOf="@+id/email_title"
app:layout_constraintTop_toBottomOf="@+id/email_body" /> app:layout_constraintTop_toBottomOf="@+id/email_body" />
@@ -175,25 +223,31 @@
android:id="@+id/email_attachment" android:id="@+id/email_attachment"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:ellipsize="end"
android:maxLines="1"
android:paddingEnd="10dp" android:paddingEnd="10dp"
android:text="@string/color_contrast_preview_email_attachment_name"
android:textColor="?androidprv:attr/materialColorOnTertiaryContainer" android:textColor="?androidprv:attr/materialColorOnTertiaryContainer"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintStart_toEndOf="@+id/ic_article_filled" app:layout_constrainedWidth="true"
app:layout_constraintTop_toTopOf="@+id/attachment_background"
app:layout_constraintBottom_toBottomOf="@+id/attachment_background" app:layout_constraintBottom_toBottomOf="@+id/attachment_background"
android:text="@string/color_contrast_preview_email_attachment_name" /> app:layout_constraintEnd_toStartOf="@+id/ic_edit"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/ic_article_filled"
app:layout_constraintTop_toTopOf="@+id/attachment_background" />
<ImageView <ImageView
android:id="@+id/ic_edit" android:id="@+id/ic_edit"
android:contentDescription="@null"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="48dp" android:layout_marginBottom="-8dp"
android:background="@drawable/color_contrast_preview_icon_edit_background"
android:contentDescription="@null"
android:padding="27dp" android:padding="27dp"
android:src="@drawable/ic_edit_24dp" android:src="@drawable/ic_edit_24dp"
android:background="@drawable/color_contrast_preview_icon_edit_background" app:layout_constraintBottom_toBottomOf="@+id/email_background"
app:layout_constraintEnd_toEndOf="@+id/email_background" app:layout_constraintEnd_toEndOf="@+id/email_background" />
app:layout_constraintTop_toBottomOf="@+id/ic_star" />
<View <View
android:id="@+id/bottom_appbar_background" android:id="@+id/bottom_appbar_background"
@@ -206,9 +260,9 @@
app:layout_constraintTop_toTopOf="@+id/ic_inbox" /> app:layout_constraintTop_toTopOf="@+id/ic_inbox" />
<ImageView <ImageView
android:contentDescription="@null"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/color_contrast_preview_icon_inbox_background" android:src="@drawable/color_contrast_preview_icon_inbox_background"
app:layout_constraintBottom_toBottomOf="@+id/ic_inbox" app:layout_constraintBottom_toBottomOf="@+id/ic_inbox"
app:layout_constraintEnd_toEndOf="@+id/ic_inbox" app:layout_constraintEnd_toEndOf="@+id/ic_inbox"
@@ -217,38 +271,38 @@
<ImageView <ImageView
android:id="@+id/ic_inbox" android:id="@+id/ic_inbox"
android:contentDescription="@null"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="42dp" android:layout_marginTop="42dp"
android:contentDescription="@null"
android:padding="24dp" android:padding="24dp"
android:src="@drawable/ic_inbox_24dp" android:src="@drawable/ic_inbox_24dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/ic_article" app:layout_constraintEnd_toStartOf="@+id/ic_article"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ic_article_filled" /> app:layout_constraintTop_toBottomOf="@+id/ic_article_filled" />
<ImageView <ImageView
android:id="@+id/ic_article" android:id="@+id/ic_article"
android:contentDescription="@null"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@null"
android:padding="24dp" android:padding="24dp"
android:src="@drawable/ic_article_24dp" android:src="@drawable/ic_article_24dp"
app:layout_constraintStart_toEndOf="@+id/ic_inbox" app:layout_constraintBottom_toBottomOf="@id/ic_inbox"
app:layout_constraintEnd_toStartOf="@+id/ic_chat_bubble" app:layout_constraintEnd_toStartOf="@+id/ic_chat_bubble"
app:layout_constraintTop_toTopOf="@id/ic_inbox" app:layout_constraintStart_toEndOf="@+id/ic_inbox"
app:layout_constraintBottom_toBottomOf="@id/ic_inbox" /> app:layout_constraintTop_toTopOf="@id/ic_inbox" />
<ImageView <ImageView
android:id="@+id/ic_chat_bubble" android:id="@+id/ic_chat_bubble"
android:contentDescription="@null"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@null"
android:padding="24dp" android:padding="24dp"
android:src="@drawable/ic_chat_bubble_24dp" android:src="@drawable/ic_chat_bubble_24dp"
app:layout_constraintBottom_toBottomOf="@id/ic_inbox"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/ic_article" app:layout_constraintStart_toEndOf="@+id/ic_article"
app:layout_constraintTop_toTopOf="@id/ic_inbox" app:layout_constraintTop_toTopOf="@id/ic_inbox" />
app:layout_constraintBottom_toBottomOf="@id/ic_inbox" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -23,6 +23,7 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<FrameLayout <FrameLayout
android:contentDescription="@string/color_contrast_preview"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingVertical="@dimen/settingslib_illustration_padding" android:paddingVertical="@dimen/settingslib_illustration_padding"
@@ -44,12 +45,12 @@
android:layout_weight="1"/> android:layout_weight="1"/>
<LinearLayout <LinearLayout
android:id="@+id/contrast_button_default"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<FrameLayout <FrameLayout
android:id="@+id/contrast_button_default"
android:layout_width="@dimen/contrast_button_total_size" android:layout_width="@dimen/contrast_button_total_size"
android:layout_height="@dimen/contrast_button_total_size" android:layout_height="@dimen/contrast_button_total_size"
android:background="@drawable/accessibility_contrast_button_background"> android:background="@drawable/accessibility_contrast_button_background">
@@ -58,7 +59,7 @@
android:layout_gravity="center" android:layout_gravity="center"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:contentDescription="@string/contrast_default" android:contentDescription="@null"
android:src="@drawable/ic_contrast_standard"/> android:src="@drawable/ic_contrast_standard"/>
</FrameLayout> </FrameLayout>
@@ -67,6 +68,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/contrast_button_text_spacing" android:layout_marginTop="@dimen/contrast_button_text_spacing"
android:gravity="center_horizontal|top" android:gravity="center_horizontal|top"
android:ellipsize="end"
android:singleLine="true"
android:textSize="@dimen/contrast_button_text_size" android:textSize="@dimen/contrast_button_text_size"
android:text="@string/contrast_default" android:text="@string/contrast_default"
android:textColor="?androidprv:attr/materialColorOnSurface"/> android:textColor="?androidprv:attr/materialColorOnSurface"/>
@@ -77,12 +80,12 @@
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<LinearLayout <LinearLayout
android:id="@+id/contrast_button_medium"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<FrameLayout <FrameLayout
android:id="@+id/contrast_button_medium"
android:layout_width="@dimen/contrast_button_total_size" android:layout_width="@dimen/contrast_button_total_size"
android:layout_height="@dimen/contrast_button_total_size" android:layout_height="@dimen/contrast_button_total_size"
android:background="@drawable/accessibility_contrast_button_background"> android:background="@drawable/accessibility_contrast_button_background">
@@ -91,7 +94,7 @@
android:layout_gravity="center" android:layout_gravity="center"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:contentDescription="@string/contrast_medium" android:contentDescription="@null"
android:src="@drawable/ic_contrast_medium"/> android:src="@drawable/ic_contrast_medium"/>
</FrameLayout> </FrameLayout>
@@ -100,6 +103,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/contrast_button_text_spacing" android:layout_marginTop="@dimen/contrast_button_text_spacing"
android:gravity="center_horizontal|top" android:gravity="center_horizontal|top"
android:ellipsize="end"
android:singleLine="true"
android:textSize="@dimen/contrast_button_text_size" android:textSize="@dimen/contrast_button_text_size"
android:text="@string/contrast_medium" android:text="@string/contrast_medium"
android:textColor="?androidprv:attr/materialColorOnSurface"/> android:textColor="?androidprv:attr/materialColorOnSurface"/>
@@ -110,12 +115,12 @@
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<LinearLayout <LinearLayout
android:id="@+id/contrast_button_high"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<FrameLayout <FrameLayout
android:id="@+id/contrast_button_high"
android:layout_width="@dimen/contrast_button_total_size" android:layout_width="@dimen/contrast_button_total_size"
android:layout_height="@dimen/contrast_button_total_size" android:layout_height="@dimen/contrast_button_total_size"
android:background="@drawable/accessibility_contrast_button_background"> android:background="@drawable/accessibility_contrast_button_background">
@@ -124,7 +129,7 @@
android:layout_gravity="center" android:layout_gravity="center"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:contentDescription="@string/contrast_high" android:contentDescription="@null"
android:src="@drawable/ic_contrast_high"/> android:src="@drawable/ic_contrast_high"/>
</FrameLayout> </FrameLayout>
@@ -133,6 +138,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/contrast_button_text_spacing" android:layout_marginTop="@dimen/contrast_button_text_spacing"
android:gravity="center_horizontal|top" android:gravity="center_horizontal|top"
android:ellipsize="end"
android:singleLine="true"
android:textSize="@dimen/contrast_button_text_size" android:textSize="@dimen/contrast_button_text_size"
android:text="@string/contrast_high" android:text="@string/contrast_high"
android:textColor="?androidprv:attr/materialColorOnSurface"/> android:textColor="?androidprv:attr/materialColorOnSurface"/>

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/setup_wizard_layout"
style="?attr/fingerprint_layout_theme"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
style="@style/SudContentFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center|bottom"
android:orientation="vertical">
<FrameLayout
android:id="@+id/layout_container"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center_horizontal|bottom"
android:clipChildren="false"
android:clipToPadding="false"
tools:ignore="Suspicious0dp">
<!-- Animation res MUST be set in code -->
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/illustration_lottie"
android:layout_width="200dp"
android:layout_height="200dp"
android:clipChildren="false"
android:clipToPadding="false"
android:scaleType="centerInside"
app:lottie_autoPlay="true"
app:lottie_loop="true"
app:lottie_speed=".85" />
</FrameLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.setupdesign.GlifLayout>

View File

@@ -38,7 +38,9 @@
style="@style/LanguageCheckboxAndLabel" style="@style/LanguageCheckboxAndLabel"
android:layout_marginRight="0dp" android:layout_marginRight="0dp"
android:minWidth="24dp" android:minWidth="24dp"
android:paddingEnd="-8dp"/> android:paddingEnd="-8dp"
android:clickable="false"
android:focusable="false"/>
<TextView <TextView
android:id="@+id/miniLabel" android:id="@+id/miniLabel"

View File

@@ -812,4 +812,7 @@
<!-- Array of carrier id that uses reusable activation code--> <!-- Array of carrier id that uses reusable activation code-->
<integer-array name="config_carrier_use_rac" translatable="false"> <integer-array name="config_carrier_use_rac" translatable="false">
</integer-array> </integer-array>
<!-- The Activity intent to trigger to launch time-related feedback. -->
<string name="config_time_feedback_intent_uri" translatable="false" />
</resources> </resources>

View File

@@ -22,6 +22,7 @@
<integer name="device_index_update">103</integer> <integer name="device_index_update">103</integer>
<integer name="sim_notification_send">104</integer> <integer name="sim_notification_send">104</integer>
<integer name="sim_slot_changed">105</integer> <integer name="sim_slot_changed">105</integer>
<integer name="power_monitor_receiver">106</integer>
<!-- Controls the maximum number of faces enrollable during SUW --> <!-- Controls the maximum number of faces enrollable during SUW -->
<integer name="suw_max_faces_enrollable">1</integer> <integer name="suw_max_faces_enrollable">1</integer>

View File

@@ -614,6 +614,15 @@
<!-- The menu item to switch to selecting a time zone with a fixed offset (such as UTC or GMT+0200) [CHAR LIMIT=30] --> <!-- The menu item to switch to selecting a time zone with a fixed offset (such as UTC or GMT+0200) [CHAR LIMIT=30] -->
<string name="zone_menu_by_offset">Select by UTC offset</string> <string name="zone_menu_by_offset">Select by UTC offset</string>
<!-- The settings category title containing the feedback button [CHAR LIMIT=30] -->
<string name="time_feedback_category_title">Feedback</string>
<!-- Search keywords for the feedback category / section in Date & Time settings. [CHAR_LIMIT=NONE] -->
<string name="keywords_time_feedback_category">feedback, bug, time, zone, timezone</string>
<!-- The menu item to start the feedback process [CHAR LIMIT=30] -->
<string name="time_feedback_title">Send feedback about time</string>
<!-- Search keywords for the feedback option in Date & Time settings. [CHAR_LIMIT=NONE] -->
<string name="keywords_time_feedback">feedback, bug, time, zone, timezone</string>
<!-- Security Settings --><skip /> <!-- Security Settings --><skip />
<!-- Security settings screen, setting option name to change screen timeout --> <!-- Security settings screen, setting option name to change screen timeout -->
@@ -4692,9 +4701,11 @@
<!-- Preview screen email title on the contrast page. [CHAR LIMIT=30] --> <!-- Preview screen email title on the contrast page. [CHAR LIMIT=30] -->
<string name="color_contrast_preview_email_title">Business trip report</string> <string name="color_contrast_preview_email_title">Business trip report</string>
<!-- Preview screen email body on the contrast page. [CHAR LIMIT=NONE] --> <!-- Preview screen email body on the contrast page. [CHAR LIMIT=NONE] -->
<string name="color_contrast_preview_email_body">For further assistance, please reach out to \nmyself or Helen. This report will be</string> <string name="color_contrast_preview_email_body">For further assistance, please reach out to myself or Helen. This report will be</string>
<!-- Preview screen email attachment name on the contrast page. [CHAR LIMIT=30] --> <!-- Preview screen email attachment name on the contrast page. [CHAR LIMIT=30] -->
<string name="color_contrast_preview_email_attachment_name">Client Expenses</string> <string name="color_contrast_preview_email_attachment_name">Client Expenses</string>
<!-- Title for color_contrast page footer. [CHAR LIMIT=30] -->
<string name="color_contrast_about_title">About color contrast</string>
<!-- Title for the accessibility text options page. [CHAR LIMIT=50] --> <!-- Title for the accessibility text options page. [CHAR LIMIT=50] -->
<string name="accessibility_turn_screen_darker_title">Turn screen darker</string> <string name="accessibility_turn_screen_darker_title">Turn screen darker</string>
<!-- Title for the accessibility preference category of interaction control services and settings. [CHAR LIMIT=50] --> <!-- Title for the accessibility preference category of interaction control services and settings. [CHAR LIMIT=50] -->
@@ -13168,4 +13179,11 @@
<!--Text for Stylus Pointer Icon preference --> <!--Text for Stylus Pointer Icon preference -->
<string name="show_stylus_pointer_icon">Show pointer while hovering</string> <string name="show_stylus_pointer_icon">Show pointer while hovering</string>
<!-- Developer settings title: Media DRM settings screen. [CHAR LIMIT=50] -->
<string name="media_drm_settings_title">Media DRM settings</string>
<!-- Developer settings title: select whether to enable force Software Secure Crypto fallback. [CHAR LIMIT=50] -->
<string name="force_swcrypto_fallback_title">Force Software Secure Crypto</string>
<!-- Developer settings summary: select to force Software Secure Crypto.[CHAR LIMIT=NONE] -->
<string name="force_swcrypto_fallback_summary">Force DRM key management to use software-based whitebox crypto</string>
</resources> </resources>

View File

@@ -39,8 +39,10 @@
"com.android.settings.accessibility.HighTextContrastPreferenceController" /> "com.android.settings.accessibility.HighTextContrastPreferenceController" />
<com.android.settings.accessibility.AccessibilityFooterPreference <com.android.settings.accessibility.AccessibilityFooterPreference
android:key="color_contrast_footer"
android:title="@string/color_contrast_note" android:title="@string/color_contrast_note"
android:selectable="false" android:selectable="false"
settings:searchable="false"/> settings:searchable="false"
settings:controller="com.android.settings.accessibility.ColorContrastFooterPreferenceController" />
</PreferenceScreen> </PreferenceScreen>

View File

@@ -73,6 +73,21 @@
</PreferenceCategory> </PreferenceCategory>
<!-- An optional preference category for feedback. Only displayed up if enabled via flags and config. -->
<PreferenceCategory
android:key="time_feedback_preference_category"
android:title="@string/time_feedback_category_title"
settings:keywords="@string/keywords_time_feedback_category"
settings:controller="com.android.settings.datetime.TimeFeedbackPreferenceCategoryController">
<Preference
android:key="time_feedback"
android:title="@string/time_feedback_title"
settings:keywords="@string/keywords_time_feedback"
settings:controller="com.android.settings.datetime.TimeFeedbackPreferenceController" />
</PreferenceCategory>
<PreferenceCategory <PreferenceCategory
android:key="time_format_preference_category" android:key="time_format_preference_category"
android:title="@string/time_format_category_title" android:title="@string/time_format_category_title"

View File

@@ -152,7 +152,8 @@
<Preference <Preference
android:key="demo_mode" android:key="demo_mode"
android:title="@string/demo_mode"> android:title="@string/demo_mode">
<intent android:action="com.android.settings.action.DEMO_MODE" /> <intent android:action="com.android.settings.action.DEMO_MODE"
android:targetPackage="com.android.systemui"/>
</Preference> </Preference>
<Preference <Preference
@@ -645,9 +646,9 @@
android:fragment="com.android.settings.development.transcode.TranscodeSettingsFragment" /> android:fragment="com.android.settings.development.transcode.TranscodeSettingsFragment" />
<Preference <Preference
android:key="widevine_settings" android:key="media_drm_settings"
android:title="@string/widevine_settings_title" android:title="@string/media_drm_settings_title"
android:fragment="com.android.settings.development.widevine.WidevineSettingsFragment" /> android:fragment="com.android.settings.development.mediadrm.MediaDrmSettingsFragment" />
</PreferenceCategory> </PreferenceCategory>

View File

@@ -18,12 +18,12 @@
<PreferenceScreen <PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto" xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/widevine_settings_title" android:title="@string/media_drm_settings_title"
settings:searchable="false"> settings:searchable="false">
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:key="force_l3_fallback" android:key="force_swcrypto_fallback"
android:title="@string/force_l3_fallback_title" android:title="@string/force_swcrypto_fallback_title"
android:summary="@string/force_l3_fallback_summary" android:summary="@string/force_swcrypto_fallback_summary"
settings:controller="com.android.settings.development.widevine.ForceL3FallbackPreferenceController" /> settings:controller="com.android.settings.development.mediadrm.ForceSwSecureCryptoFallbackPreferenceController" />
</PreferenceScreen> </PreferenceScreen>

View File

@@ -23,6 +23,8 @@
android:key="run_backup_tasks" android:key="run_backup_tasks"
android:title="@string/run_backup_tasks_title" android:title="@string/run_backup_tasks_title"
android:order="-2000" android:order="-2000"
settings:isPreferenceVisible="false"
settings:searchable="false"
settings:keywords="@string/keywords_run_backup_tasks" settings:keywords="@string/keywords_run_backup_tasks"
settings:controller="com.android.settings.spa.app.specialaccess.BackupTasksAppsPreferenceController"> settings:controller="com.android.settings.spa.app.specialaccess.BackupTasksAppsPreferenceController">
</Preference> </Preference>

View File

@@ -0,0 +1,37 @@
/*
* 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.accessibility;
import android.content.Context;
import androidx.annotation.NonNull;
import com.android.settings.R;
/** Preference controller for footer in color contrast page. */
public class ColorContrastFooterPreferenceController extends
AccessibilityFooterPreferenceController {
public ColorContrastFooterPreferenceController(@NonNull Context context,
@NonNull String key) {
super(context, key);
}
@Override
protected String getIntroductionTitle() {
return mContext.getString(R.string.color_contrast_about_title);
}
}

View File

@@ -26,7 +26,7 @@ import android.app.UiModeManager;
import android.content.Context; import android.content.Context;
import android.provider.Settings; import android.provider.Settings;
import android.view.View; import android.view.View;
import android.widget.FrameLayout; import android.widget.LinearLayout;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@@ -53,7 +53,7 @@ public class ContrastSelectorPreferenceController extends BasePreferenceControll
private final Executor mMainExecutor; private final Executor mMainExecutor;
private final UiModeManager mUiModeManager; private final UiModeManager mUiModeManager;
private Map<Integer, FrameLayout> mContrastButtons = new HashMap<>(); private Map<Integer, LinearLayout> mContrastButtons = new HashMap<>();
public ContrastSelectorPreferenceController(@NonNull Context context, public ContrastSelectorPreferenceController(@NonNull Context context,
@NonNull String preferenceKey) { @NonNull String preferenceKey) {

View File

@@ -61,7 +61,8 @@ public class RTTSettingPreferenceController extends BasePreferenceController {
mDialerPackage = mContext.getString(R.string.config_rtt_setting_package_name); mDialerPackage = mContext.getString(R.string.config_rtt_setting_package_name);
mPackageManager = mContext.getPackageManager(); mPackageManager = mContext.getPackageManager();
mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class); mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
mRTTIntent = new Intent(context.getString(R.string.config_rtt_setting_intent_action)); mRTTIntent = new Intent(context.getString(R.string.config_rtt_setting_intent_action))
.setPackage(mDialerPackage);
Log.d(TAG, "init controller"); Log.d(TAG, "init controller");
} }

View File

@@ -443,7 +443,8 @@ public class ToggleAccessibilityServicePreferenceFragment extends
final ApplicationInfo appInfo = final ApplicationInfo appInfo =
a11yServiceInfo.getResolveInfo().serviceInfo.applicationInfo; a11yServiceInfo.getResolveInfo().serviceInfo.applicationInfo;
final Uri packageUri = Uri.parse("package:" + appInfo.packageName); final Uri packageUri = Uri.parse("package:" + appInfo.packageName);
final Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri); final Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri)
.setPackage(getString(R.string.config_package_installer_package_name));
return uninstallIntent; return uninstallIntent;
} }

View File

@@ -570,6 +570,7 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment
} }
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setPackage(getContext().getPackageName());
intent.setData(Uri.parse("package:" + packageName)); intent.setData(Uri.parse("package:" + packageName));
final Preference appInfoPreference = new Preference(getPrefContext()); final Preference appInfoPreference = new Preference(getPrefContext());

View File

@@ -52,6 +52,8 @@ import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.Finge
import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollIntroV2Fragment import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollIntroV2Fragment
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.fragment.RFPSEnrollFragment import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.fragment.RFPSEnrollFragment
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.viewmodel.RFPSViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.viewmodel.RFPSViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.fragment.UdfpsEnrollFragment
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel.UdfpsViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.BackgroundViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.BackgroundViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintAction import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintAction
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollConfirmationViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollConfirmationViewModel
@@ -100,6 +102,7 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() {
private lateinit var fingerprintFlowViewModel: FingerprintFlowViewModel private lateinit var fingerprintFlowViewModel: FingerprintFlowViewModel
private lateinit var fingerprintEnrollConfirmationViewModel: private lateinit var fingerprintEnrollConfirmationViewModel:
FingerprintEnrollConfirmationViewModel FingerprintEnrollConfirmationViewModel
private lateinit var udfpsViewModel: UdfpsViewModel
private val coroutineDispatcher = Dispatchers.Default private val coroutineDispatcher = Dispatchers.Default
/** Result listener for ChooseLock activity flow. */ /** Result listener for ChooseLock activity flow. */
@@ -306,6 +309,12 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() {
), ),
)[RFPSViewModel::class.java] )[RFPSViewModel::class.java]
udfpsViewModel =
ViewModelProvider(
this,
UdfpsViewModel.UdfpsEnrollmentFactory(),
)[UdfpsViewModel::class.java]
fingerprintEnrollConfirmationViewModel = fingerprintEnrollConfirmationViewModel =
ViewModelProvider( ViewModelProvider(
this, this,
@@ -344,6 +353,8 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() {
is Enrollment -> { is Enrollment -> {
when (step.sensor.sensorType) { when (step.sensor.sensorType) {
FingerprintSensorType.REAR -> RFPSEnrollFragment() FingerprintSensorType.REAR -> RFPSEnrollFragment()
FingerprintSensorType.UDFPS_OPTICAL,
FingerprintSensorType.UDFPS_ULTRASONIC -> UdfpsEnrollFragment()
else -> FingerprintEnrollEnrollingV2Fragment() else -> FingerprintEnrollEnrollingV2Fragment()
} }
} }

View File

@@ -0,0 +1,127 @@
/*
* 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.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.fragment
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.annotation.VisibleForTesting
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieCompositionFactory
import com.android.settings.R
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel.StageViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel.UdfpsViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep
import com.google.android.setupdesign.GlifLayout
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class UdfpsEnrollFragment() : Fragment(R.layout.fingerprint_v2_udfps_enroll_enrolling) {
/** Used for testing purposes */
private var factory: ViewModelProvider.Factory? = null
private val viewModel: UdfpsViewModel by lazy { viewModelProvider[UdfpsViewModel::class.java] }
@VisibleForTesting
constructor(theFactory: ViewModelProvider.Factory) : this() {
factory = theFactory
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val layout = view as GlifLayout
val illustrationLottie: LottieAnimationView = layout.findViewById(R.id.illustration_lottie)!!
viewLifecycleOwner.lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.RESUMED) {
viewLifecycleOwner.lifecycleScope.launch {
viewModel.stageFlow.collect {
layout.setHeaderText(getHeaderText(it))
getDescriptionText(it)?.let { descriptionText ->
layout.setDescriptionText(descriptionText)
}
getLottie(it)?.let { lottie ->
layout.descriptionText = ""
LottieCompositionFactory.fromRawRes(requireContext().applicationContext, lottie)
.addListener { comp ->
comp?.let { composition ->
viewLifecycleOwner.lifecycleScope.launch {
illustrationLottie.setComposition(composition)
illustrationLottie.visibility = View.VISIBLE
illustrationLottie.playAnimation()
}
}
}
}
}
}
}
}
}
private fun getHeaderText(stageViewModel: StageViewModel): Int {
return when (stageViewModel) {
StageViewModel.Center,
StageViewModel.Guided,
StageViewModel.Fingertip,
StageViewModel.Unknown -> R.string.security_settings_udfps_enroll_fingertip_title
StageViewModel.LeftEdge -> R.string.security_settings_udfps_enroll_left_edge_title
StageViewModel.RightEdge -> R.string.security_settings_udfps_enroll_right_edge_title
}
}
private fun getDescriptionText(stageViewModel: StageViewModel): Int? {
return when (stageViewModel) {
StageViewModel.Center,
StageViewModel.Guided,
StageViewModel.Fingertip,
StageViewModel.LeftEdge,
StageViewModel.RightEdge -> null
StageViewModel.Unknown -> R.string.security_settings_udfps_enroll_start_message
}
}
private fun getLottie(stageViewModel: StageViewModel): Int? {
return when (stageViewModel) {
StageViewModel.Center,
StageViewModel.Guided -> R.raw.udfps_center_hint_lottie
StageViewModel.Fingertip -> R.raw.udfps_tip_hint_lottie
StageViewModel.LeftEdge -> R.raw.udfps_left_edge_hint_lottie
StageViewModel.RightEdge -> R.raw.udfps_right_edge_hint_lottie
StageViewModel.Unknown -> null
}
}
private val viewModelProvider: ViewModelProvider by lazy {
if (factory != null) {
ViewModelProvider(requireActivity(), factory!!)
} else {
ViewModelProvider(requireActivity())
}
}
companion object {
private const val TAG = "UDFPSEnrollFragment"
private val navStep = FingerprintNavigationStep.Enrollment::class
}
}

View File

@@ -0,0 +1,36 @@
/*
* 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.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel
/**
* A view model that describes the various stages of UDFPS Enrollment. This stages typically update
* the enrollment UI in a major way, such as changing the lottie animation or changing the location
* of the where the user should press their fingerprint
*/
sealed class StageViewModel {
data object Unknown : StageViewModel()
data object Guided : StageViewModel()
data object Center : StageViewModel()
data object Fingertip : StageViewModel()
data object LeftEdge : StageViewModel()
data object RightEdge : StageViewModel()
}

View File

@@ -0,0 +1,42 @@
/*
* 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.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep
import kotlinx.coroutines.flow.flowOf
/** ViewModel used to drive UDFPS Enrollment through [UdfpsEnrollFragment] */
class UdfpsViewModel() : ViewModel() {
/** Indicates what stage UDFPS enrollment is in. */
val stageFlow = flowOf(StageViewModel.Center)
class UdfpsEnrollmentFactory() : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return UdfpsViewModel() as T
}
}
companion object {
private val navStep = FingerprintNavigationStep.Enrollment::class
private const val TAG = "UDFPSViewModel"
}
}

View File

@@ -68,6 +68,12 @@ public class DateTimeSettings extends DashboardFragment implements
.setTimeAndDateCallback(this) .setTimeAndDateCallback(this)
.setFromSUW(isFromSUW); .setFromSUW(isFromSUW);
// All the elements in the category are optional, so we must ensure the category is only
// available if any of the elements are available.
TimeFeedbackPreferenceCategoryController helpAndFeedbackCategoryController =
use(TimeFeedbackPreferenceCategoryController.class);
use(TimeFeedbackPreferenceController.class)
.registerWithOptionalCategoryController(helpAndFeedbackCategoryController);
} }
@Override @Override

View File

@@ -0,0 +1,52 @@
/*
* 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.datetime;
import static android.provider.DeviceConfig.NAMESPACE_SETTINGS_UI;
import android.provider.DeviceConfig;
import com.android.settings.flags.Flags;
/** A class to avoid duplication of launch-control logic for "time feedback" support. */
final class TimeFeedbackLaunchUtils {
/**
* A {@link DeviceConfig} flag that influences whether the settings entries related to help and
* feedback are supported on this device / for this user.
*/
public static final String KEY_HELP_AND_FEEDBACK_FEATURE_SUPPORTED =
"time_help_and_feedback_feature_supported";
private TimeFeedbackLaunchUtils() {}
static boolean isFeedbackFeatureSupported() {
// Support is determined according to:
// 1) A build-time flag to determine release feature availability.
// 2) A runtime / server-side flag to determine which devices / who gets to see the feature.
// This is launch control for limiting the feedback to droidfooding.
return isFeatureSupportedThisRelease() && isFeatureSupportedOnThisDevice();
}
private static boolean isFeatureSupportedThisRelease() {
return Flags.datetimeFeedback();
}
private static boolean isFeatureSupportedOnThisDevice() {
boolean defaultIsSupported = false;
return DeviceConfig.getBoolean(
NAMESPACE_SETTINGS_UI, KEY_HELP_AND_FEEDBACK_FEATURE_SUPPORTED, defaultIsSupported);
}
}

View File

@@ -0,0 +1,67 @@
/*
* 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.datetime;
import android.content.Context;
import androidx.annotation.NonNull;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* A controller for the Settings category for "time feedback".
*/
public class TimeFeedbackPreferenceCategoryController extends BasePreferenceController {
private final List<AbstractPreferenceController> mChildControllers = new ArrayList<>();
public TimeFeedbackPreferenceCategoryController(
Context context, String preferenceKey) {
super(context, preferenceKey);
}
/**
* Adds a controller whose own availability can determine the category's availability status.
*/
void addChildController(@NonNull AbstractPreferenceController childController) {
mChildControllers.add(Objects.requireNonNull(childController));
}
@Override
public int getAvailabilityStatus() {
// Firstly, hide the category if it is not enabled by flags.
if (!isTimeFeedbackFeatureEnabled()) {
return UNSUPPORTED_ON_DEVICE;
}
// Secondly, only show the category if there's one or more controllers available within it.
for (AbstractPreferenceController childController : mChildControllers) {
if (childController.isAvailable()) {
return AVAILABLE;
}
}
return UNSUPPORTED_ON_DEVICE;
}
protected boolean isTimeFeedbackFeatureEnabled() {
return TimeFeedbackLaunchUtils.isFeedbackFeatureSupported();
}
}

View File

@@ -0,0 +1,95 @@
/*
* 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.datetime;
import static android.content.Intent.URI_INTENT_SCHEME;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import androidx.preference.Preference;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.PreferenceControllerMixin;
import java.net.URISyntaxException;
/**
* A controller for the Settings button that launches "time feedback". The intent launches is
* configured with an Intent URI.
*/
public class TimeFeedbackPreferenceController
extends BasePreferenceController
implements PreferenceControllerMixin {
private final String mIntentUri;
private final int mAvailabilityStatus;
public TimeFeedbackPreferenceController(Context context, String preferenceKey) {
this(context, preferenceKey, context.getResources().getString(
R.string.config_time_feedback_intent_uri));
}
@VisibleForTesting
TimeFeedbackPreferenceController(Context context, String preferenceKey, String intentUri) {
super(context, preferenceKey);
mIntentUri = intentUri;
mAvailabilityStatus = TextUtils.isEmpty(mIntentUri) ? UNSUPPORTED_ON_DEVICE : AVAILABLE;
}
/**
* Registers this controller with a category controller so that the category can be optionally
* displayed, i.e. if all the child controllers are not available, the category heading won't be
* available.
*/
public void registerWithOptionalCategoryController(
TimeFeedbackPreferenceCategoryController categoryController) {
categoryController.addChildController(this);
}
@Override
public int getAvailabilityStatus() {
if (!TimeFeedbackLaunchUtils.isFeedbackFeatureSupported()) {
return UNSUPPORTED_ON_DEVICE;
}
return mAvailabilityStatus;
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
return super.handlePreferenceTreeClick(preference);
}
// Don't allow a monkey user to launch feedback
if (ActivityManager.isUserAMonkey()) {
return true;
}
try {
Intent intent = Intent.parseUri(mIntentUri, URI_INTENT_SCHEME);
mContext.startActivity(intent);
return true;
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Bad intent configuration: " + mIntentUri, e);
}
}
}

View File

@@ -195,7 +195,7 @@ public class GraphicsDriverEnableAngleAsSystemDriverController
@VisibleForTesting @VisibleForTesting
void rebootDevice(Context context) { void rebootDevice(Context context) {
final Intent intent = new Intent(Intent.ACTION_REBOOT); final Intent intent = new Intent(Intent.ACTION_REBOOT).setPackage("android");
context.startActivity(intent); context.startActivity(intent);
} }

View File

@@ -14,9 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
package com.android.settings.development.widevine; package com.android.settings.development.mediadrm;
import android.content.Context; import android.content.Context;
import android.media.MediaDrm;
import android.sysprop.WidevineProperties; import android.sysprop.WidevineProperties;
import android.util.Log; import android.util.Log;
@@ -29,13 +30,12 @@ import com.android.settingslib.development.DevelopmentSettingsEnabler;
import com.android.settings.media_drm.Flags; import com.android.settings.media_drm.Flags;
/** /**
* The controller (in the Media Widevine settings) enforces L3 security level * The controller (in the Media Drm settings) enforces software secure crypto.
* of Widevine CDM.
*/ */
public class ForceL3FallbackPreferenceController extends TogglePreferenceController { public class ForceSwSecureCryptoFallbackPreferenceController extends TogglePreferenceController {
private static final String TAG = "ForceL3FallbackPreferenceController"; private static final String TAG = "ForceSwSecureCryptoFallbackPreferenceController";
public ForceL3FallbackPreferenceController(Context context, String preferenceKey) { public ForceSwSecureCryptoFallbackPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey); super(context, preferenceKey);
} }

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.android.settings.development.widevine; package com.android.settings.development.mediadrm;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
@@ -27,12 +27,12 @@ import com.android.settingslib.development.DevelopmentSettingsEnabler;
import com.android.settingslib.search.SearchIndexable; import com.android.settingslib.search.SearchIndexable;
/** /**
* Fragment for native widevine settings in Developer options. * Fragment for native mediadrm settings in Developer options.
*/ */
@SearchIndexable @SearchIndexable
public class WidevineSettingsFragment extends DashboardFragment implements public class MediaDrmSettingsFragment extends DashboardFragment implements
DeveloperOptionAwareMixin { DeveloperOptionAwareMixin {
private static final String TAG = "WidevineSettings"; private static final String TAG = "MediaDrmSettings";
@Override @Override
protected String getLogTag() { protected String getLogTag() {
@@ -41,16 +41,16 @@ public class WidevineSettingsFragment extends DashboardFragment implements
@Override @Override
protected int getPreferenceScreenResId() { protected int getPreferenceScreenResId() {
return R.xml.widevine_settings; return R.xml.media_drm_settings;
} }
@Override @Override
public int getMetricsCategory() { public int getMetricsCategory() {
return SettingsEnums.WIDEVINE_SETTINGS; return SettingsEnums.MEDIA_DRM_SETTINGS;
} }
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.widevine_settings) { new BaseSearchIndexProvider(R.xml.media_drm_settings) {
@Override @Override
protected boolean isPageSearchEnabled(Context context) { protected boolean isPageSearchEnabled(Context context) {

View File

@@ -62,6 +62,10 @@ public class AutoBrightnessPreferenceController extends TogglePreferenceControll
@Override @Override
public void updateState(Preference preference) { public void updateState(Preference preference) {
super.updateState(preference); super.updateState(preference);
if (!(preference instanceof PrimarySwitchPreference)) {
return;
}
PrimarySwitchPreference pref = (PrimarySwitchPreference) preference; PrimarySwitchPreference pref = (PrimarySwitchPreference) preference;
if (pref.isEnabled() && UserManager.get(mContext).hasBaseUserRestriction( if (pref.isEnabled() && UserManager.get(mContext).hasBaseUserRestriction(
UserManager.DISALLOW_CONFIG_BRIGHTNESS, Process.myUserHandle())) { UserManager.DISALLOW_CONFIG_BRIGHTNESS, Process.myUserHandle())) {

View File

@@ -181,7 +181,8 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment i
if (KEY_SYSTEM_NAV_GESTURAL.equals(info.getKey())) { if (KEY_SYSTEM_NAV_GESTURAL.equals(info.getKey())) {
pref.setExtraWidgetOnClickListener((v) -> startActivity(new Intent( pref.setExtraWidgetOnClickListener((v) -> startActivity(new Intent(
GestureNavigationSettingsFragment.GESTURE_NAVIGATION_SETTINGS))); GestureNavigationSettingsFragment.GESTURE_NAVIGATION_SETTINGS)
.setPackage(getContext().getPackageName())));
} }
if ((KEY_SYSTEM_NAV_2BUTTONS.equals(info.getKey()) if ((KEY_SYSTEM_NAV_2BUTTONS.equals(info.getKey())

View File

@@ -187,6 +187,15 @@ public class SettingsHomepageActivity extends FragmentActivity implements
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// Ensure device is provisioned in order to access Settings home
// TODO(b/331254029): This should later be replaced in favor of an allowlist
boolean unprovisioned = android.provider.Settings.Global.getInt(getContentResolver(),
android.provider.Settings.Global.DEVICE_PROVISIONED, 0) == 0;
if (unprovisioned) {
Log.e(TAG, "Device is not provisioned, exiting Settings");
finish();
}
mIsEmbeddingActivityEnabled = ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this); mIsEmbeddingActivityEnabled = ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this);
if (mIsEmbeddingActivityEnabled) { if (mIsEmbeddingActivityEnabled) {
final UserManager um = getSystemService(UserManager.class); final UserManager um = getSystemService(UserManager.class);

View File

@@ -27,6 +27,7 @@ import android.util.TypedValue;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.CompoundButton; import android.widget.CompoundButton;
@@ -189,6 +190,13 @@ class LocaleDragAndDropAdapter
setCheckBoxDescription(dragCell, checkbox, isChecked); setCheckBoxDescription(dragCell, checkbox, isChecked);
} }
}); });
dragCell.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
checkbox.toggle();
}
});
} }
@VisibleForTesting @VisibleForTesting
@@ -200,8 +208,6 @@ class LocaleDragAndDropAdapter
CharSequence checkedStatus = mContext.getText( CharSequence checkedStatus = mContext.getText(
isChecked ? com.android.internal.R.string.checked isChecked ? com.android.internal.R.string.checked
: com.android.internal.R.string.not_checked); : com.android.internal.R.string.not_checked);
// Talkback
dragCell.setStateDescription(checkedStatus);
// Select to Speak // Select to Speak
checkbox.setContentDescription(checkedStatus); checkbox.setContentDescription(checkedStatus);
} }

View File

@@ -338,11 +338,6 @@ class SimOnboardingService {
suspend fun startSetupPrimarySim(context: Context) { suspend fun startSetupPrimarySim(context: Context) {
withContext(Dispatchers.Default) { withContext(Dispatchers.Default) {
if (SubscriptionUtil.getActiveSubscriptions(subscriptionManager).size <= 1) {
Log.d(TAG,
"startSetupPrimarySim: number of active subscriptionInfo is less than 2"
)
} else {
setDefaultVoice(subscriptionManager, targetPrimarySimCalls) setDefaultVoice(subscriptionManager, targetPrimarySimCalls)
setDefaultSms(subscriptionManager, targetPrimarySimTexts) setDefaultSms(subscriptionManager, targetPrimarySimTexts)
setDefaultData( setDefaultData(
@@ -359,7 +354,6 @@ class SimOnboardingService {
// no next action, send finish // no next action, send finish
callback(CallbackType.CALLBACK_FINISH) callback(CallbackType.CALLBACK_FINISH)
} }
}
suspend fun startEnableDsds(context: Context) { suspend fun startEnableDsds(context: Context) {
withContext(Dispatchers.Default) { withContext(Dispatchers.Default) {

View File

@@ -19,6 +19,7 @@ package com.android.settings.notification.zen;
import static android.app.NotificationManager.EXTRA_AUTOMATIC_RULE_ID; import static android.app.NotificationManager.EXTRA_AUTOMATIC_RULE_ID;
import android.app.AutomaticZenRule; import android.app.AutomaticZenRule;
import android.app.Flags;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.ComponentName; import android.content.ComponentName;
@@ -28,11 +29,9 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ComponentInfo; import android.content.pm.ComponentInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo; import android.content.pm.ServiceInfo;
import android.os.Binder;
import android.provider.Settings; import android.provider.Settings;
import android.service.notification.ConditionProviderService; import android.service.notification.ConditionProviderService;
import android.util.Log; import android.util.Log;
import android.util.Slog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.preference.Preference; import androidx.preference.Preference;
@@ -41,7 +40,6 @@ import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.Map; import java.util.Map;
import java.util.Objects;
abstract public class AbstractZenModeAutomaticRulePreferenceController extends abstract public class AbstractZenModeAutomaticRulePreferenceController extends
AbstractZenModePreferenceController implements PreferenceControllerMixin { AbstractZenModePreferenceController implements PreferenceControllerMixin {
@@ -166,9 +164,20 @@ abstract public class AbstractZenModeAutomaticRulePreferenceController extends
public void onOk(String ruleName, Fragment parent) { public void onOk(String ruleName, Fragment parent) {
mMetricsFeatureProvider.action(mContext, mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK); SettingsEnums.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
AutomaticZenRule rule = new AutomaticZenRule(ruleName, mRuleInfo.serviceComponent, AutomaticZenRule rule;
if (Flags.modesApi() && Flags.modesUi()) {
rule = new AutomaticZenRule.Builder(ruleName, mRuleInfo.defaultConditionId)
.setType(mRuleInfo.type)
.setOwner(mRuleInfo.serviceComponent)
.setConfigurationActivity(mRuleInfo.configurationActivity)
.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY)
.setTriggerDescription(mRuleInfo.defaultTriggerDescription)
.build();
} else {
rule = new AutomaticZenRule(ruleName, mRuleInfo.serviceComponent,
mRuleInfo.configurationActivity, mRuleInfo.defaultConditionId, null, mRuleInfo.configurationActivity, mRuleInfo.defaultConditionId, null,
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
}
String savedRuleId = mBackend.addZenRule(rule); String savedRuleId = mBackend.addZenRule(rule);
if (savedRuleId != null) { if (savedRuleId != null) {
parent.startActivity(getRuleIntent(mRuleInfo.settingsAction, null, parent.startActivity(getRuleIntent(mRuleInfo.settingsAction, null,

View File

@@ -138,7 +138,7 @@ public class ZenModeEventRuleSettings extends ZenModeRuleSettingsBase {
mEvent.userId = Integer.parseInt(key[0]); mEvent.userId = Integer.parseInt(key[0]);
mEvent.calendarId = key[1].equals("") ? null : Long.parseLong(key[1]); mEvent.calendarId = key[1].equals("") ? null : Long.parseLong(key[1]);
mEvent.calName = key[2].equals("") ? null : key[2]; mEvent.calName = key[2].equals("") ? null : key[2];
updateRule(ZenModeConfig.toEventConditionId(mEvent)); updateEventRule(mEvent);
return true; return true;
} }
}); });
@@ -160,7 +160,7 @@ public class ZenModeEventRuleSettings extends ZenModeRuleSettingsBase {
final int reply = Integer.parseInt((String) newValue); final int reply = Integer.parseInt((String) newValue);
if (reply == mEvent.reply) return false; if (reply == mEvent.reply) return false;
mEvent.reply = reply; mEvent.reply = reply;
updateRule(ZenModeConfig.toEventConditionId(mEvent)); updateEventRule(mEvent);
return true; return true;
} }
}); });

View File

@@ -24,9 +24,10 @@ import android.app.NotificationManager;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.service.notification.ConditionProviderService; import android.service.notification.ConditionProviderService;
import android.service.notification.SystemZenRules;
import android.service.notification.ZenModeConfig;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.Toast; import android.widget.Toast;
@@ -162,8 +163,21 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase {
updatePreference(mActionButtons); updatePreference(mActionButtons);
} }
protected void updateRule(Uri newConditionId) { protected void updateScheduleRule(ZenModeConfig.ScheduleInfo schedule) {
mRule.setConditionId(newConditionId); mRule.setConditionId(ZenModeConfig.toScheduleConditionId(schedule));
if (Flags.modesApi() && Flags.modesUi()) {
mRule.setTriggerDescription(
SystemZenRules.getTriggerDescriptionForScheduleTime(mContext, schedule));
}
mBackend.updateZenRule(mId, mRule);
}
protected void updateEventRule(ZenModeConfig.EventInfo event) {
mRule.setConditionId(ZenModeConfig.toEventConditionId(event));
if (Flags.modesApi() && Flags.modesUi()) {
mRule.setTriggerDescription(
SystemZenRules.getTriggerDescriptionForScheduleEvent(mContext, event));
}
mBackend.updateZenRule(mId, mRule); mBackend.updateZenRule(mId, mRule);
} }

View File

@@ -108,7 +108,7 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
if (DEBUG) Log.d(TAG, "onPrefChange start h=" + hour + " m=" + minute); if (DEBUG) Log.d(TAG, "onPrefChange start h=" + hour + " m=" + minute);
mSchedule.startHour = hour; mSchedule.startHour = hour;
mSchedule.startMinute = minute; mSchedule.startMinute = minute;
updateRule(ZenModeConfig.toScheduleConditionId(mSchedule)); updateScheduleRule(mSchedule);
return true; return true;
} }
}); });
@@ -130,7 +130,7 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
if (DEBUG) Log.d(TAG, "onPrefChange end h=" + hour + " m=" + minute); if (DEBUG) Log.d(TAG, "onPrefChange end h=" + hour + " m=" + minute);
mSchedule.endHour = hour; mSchedule.endHour = hour;
mSchedule.endMinute = minute; mSchedule.endMinute = minute;
updateRule(ZenModeConfig.toScheduleConditionId(mSchedule)); updateScheduleRule(mSchedule);
return true; return true;
} }
}); });
@@ -142,7 +142,7 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
@Override @Override
public boolean onPreferenceChange(Preference preference, Object o) { public boolean onPreferenceChange(Preference preference, Object o) {
mSchedule.exitAtAlarm = (Boolean) o; mSchedule.exitAtAlarm = (Boolean) o;
updateRule(ZenModeConfig.toScheduleConditionId(mSchedule)); updateScheduleRule(mSchedule);
return true; return true;
} }
}); });
@@ -214,7 +214,7 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
if (Arrays.equals(days, mSchedule.days)) return; if (Arrays.equals(days, mSchedule.days)) return;
if (DEBUG) Log.d(TAG, "days.onChanged days=" + Arrays.toString(days)); if (DEBUG) Log.d(TAG, "days.onChanged days=" + Arrays.toString(days));
mSchedule.days = days; mSchedule.days = days;
updateRule(ZenModeConfig.toScheduleConditionId(mSchedule)); updateScheduleRule(mSchedule);
} }
}) })
.setOnDismissListener(new OnDismissListener() { .setOnDismissListener(new OnDismissListener() {

View File

@@ -29,6 +29,7 @@ import android.util.Log;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.dashboard.RestrictedDashboardFragment; import com.android.settings.dashboard.RestrictedDashboardFragment;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
@@ -59,7 +60,12 @@ abstract public class ZenModeSettingsBase extends RestrictedDashboardFragment {
public void onAttach(Context context) { public void onAttach(Context context) {
super.onAttach(context); super.onAttach(context);
mContext = context; mContext = context;
mBackend = ZenModeBackend.getInstance(mContext); setBackend(ZenModeBackend.getInstance(mContext));
}
@VisibleForTesting
void setBackend(ZenModeBackend backend) {
mBackend = backend;
} }
@Override @Override

View File

@@ -1,5 +1,7 @@
package com.android.settings.notification.zen; package com.android.settings.notification.zen;
import android.annotation.Nullable;
import android.app.AutomaticZenRule;
import android.content.ComponentName; import android.content.ComponentName;
import android.net.Uri; import android.net.Uri;
@@ -35,7 +37,9 @@ public class ZenRuleInfo {
public String title; public String title;
public String settingsAction; public String settingsAction;
public ComponentName configurationActivity; public ComponentName configurationActivity;
@AutomaticZenRule.Type public int type;
public Uri defaultConditionId; public Uri defaultConditionId;
@Nullable public String defaultTriggerDescription;
public ComponentName serviceComponent; public ComponentName serviceComponent;
public boolean isSystem; public boolean isSystem;
public CharSequence packageLabel; public CharSequence packageLabel;

View File

@@ -17,6 +17,7 @@
package com.android.settings.notification.zen; package com.android.settings.notification.zen;
import android.app.AutomaticZenRule; import android.app.AutomaticZenRule;
import android.app.Flags;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@@ -25,6 +26,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.ScheduleInfo; import android.service.notification.ZenModeConfig.ScheduleInfo;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
@@ -141,6 +143,11 @@ public class ZenRulePreference extends PrimarySwitchPreference {
private String computeRuleSummary(AutomaticZenRule rule) { private String computeRuleSummary(AutomaticZenRule rule) {
if (rule != null) { if (rule != null) {
if (Flags.modesApi() && Flags.modesUi()
&& !TextUtils.isEmpty(rule.getTriggerDescription())) {
return rule.getTriggerDescription();
}
// handle schedule-based rules // handle schedule-based rules
ScheduleInfo schedule = ScheduleInfo schedule =
ZenModeConfig.tryParseScheduleConditionId(rule.getConditionId()); ZenModeConfig.tryParseScheduleConditionId(rule.getConditionId());

View File

@@ -16,7 +16,9 @@
package com.android.settings.notification.zen; package com.android.settings.notification.zen;
import android.app.AutomaticZenRule;
import android.app.Dialog; import android.app.Dialog;
import android.app.Flags;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
@@ -29,6 +31,7 @@ import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.service.notification.SystemZenRules;
import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -178,6 +181,11 @@ public class ZenRuleSelectionDialog extends InstrumentedDialogFragment {
rt.title = mContext.getString(R.string.zen_schedule_rule_type_name); rt.title = mContext.getString(R.string.zen_schedule_rule_type_name);
rt.packageName = ZenModeConfig.getEventConditionProvider().getPackageName(); rt.packageName = ZenModeConfig.getEventConditionProvider().getPackageName();
rt.defaultConditionId = ZenModeConfig.toScheduleConditionId(schedule); rt.defaultConditionId = ZenModeConfig.toScheduleConditionId(schedule);
if (Flags.modesApi() && Flags.modesUi()) {
rt.type = AutomaticZenRule.TYPE_SCHEDULE_TIME;
rt.defaultTriggerDescription = SystemZenRules.getTriggerDescriptionForScheduleTime(
mContext, schedule);
}
rt.serviceComponent = ZenModeConfig.getScheduleConditionProvider(); rt.serviceComponent = ZenModeConfig.getScheduleConditionProvider();
rt.isSystem = true; rt.isSystem = true;
return rt; return rt;
@@ -193,6 +201,11 @@ public class ZenRuleSelectionDialog extends InstrumentedDialogFragment {
rt.title = mContext.getString(R.string.zen_event_rule_type_name); rt.title = mContext.getString(R.string.zen_event_rule_type_name);
rt.packageName = ZenModeConfig.getScheduleConditionProvider().getPackageName(); rt.packageName = ZenModeConfig.getScheduleConditionProvider().getPackageName();
rt.defaultConditionId = ZenModeConfig.toEventConditionId(event); rt.defaultConditionId = ZenModeConfig.toEventConditionId(event);
if (Flags.modesApi() && Flags.modesUi()) {
rt.type = AutomaticZenRule.TYPE_SCHEDULE_CALENDAR;
rt.defaultTriggerDescription = SystemZenRules.getTriggerDescriptionForScheduleEvent(
mContext, event);
}
rt.serviceComponent = ZenModeConfig.getEventConditionProvider(); rt.serviceComponent = ZenModeConfig.getEventConditionProvider();
rt.isSystem = true; rt.isSystem = true;
return rt; return rt;

View File

@@ -143,7 +143,8 @@ public class BiometricFragment extends InstrumentedFragment {
.setShowEmergencyCallButton(promptInfo.isShowEmergencyCallButton()) .setShowEmergencyCallButton(promptInfo.isShowEmergencyCallButton())
.setReceiveSystemEvents(true); .setReceiveSystemEvents(true);
if (Flags.enableBiometricsToUnlockPrivateSpace()) { if (android.os.Flags.allowPrivateProfile() && Flags.enablePrivateSpaceFeatures()
&& Flags.enableBiometricsToUnlockPrivateSpace()) {
promptBuilder = promptBuilder.setAllowBackgroundAuthentication(true /* allow */, promptBuilder = promptBuilder.setAllowBackgroundAuthentication(true /* allow */,
promptInfo.shouldUseParentProfileForDeviceCredential()); promptInfo.shouldUseParentProfileForDeviceCredential());
} else { } else {

View File

@@ -87,7 +87,7 @@ public class PrivateSpaceMaintainer {
return true; return true;
} }
// a name indicating that the profile was created from the PS Settings page // a name indicating that the profile was created from the PS Settings page
final String userName = "psSettingsUser"; final String userName = "Private space";
if (mUserHandle == null) { if (mUserHandle == null) {
try { try {

View File

@@ -19,14 +19,11 @@ package com.android.settings.spa.app.specialaccess
import android.content.Context import android.content.Context
import androidx.preference.Preference import androidx.preference.Preference
import com.android.settings.core.BasePreferenceController import com.android.settings.core.BasePreferenceController
import com.android.settings.flags.Flags
import com.android.settings.spa.SpaActivity.Companion.startSpaActivity import com.android.settings.spa.SpaActivity.Companion.startSpaActivity
class BackupTasksAppsPreferenceController(context: Context, preferenceKey: String) : class BackupTasksAppsPreferenceController(context: Context, preferenceKey: String) :
BasePreferenceController(context, preferenceKey) { BasePreferenceController(context, preferenceKey) {
override fun getAvailabilityStatus() = override fun getAvailabilityStatus() = CONDITIONALLY_UNAVAILABLE
if (Flags.enablePerformBackupTasksInSettings()) AVAILABLE
else CONDITIONALLY_UNAVAILABLE
override fun handlePreferenceTreeClick(preference: Preference): Boolean { override fun handlePreferenceTreeClick(preference: Preference): Boolean {
if (preference.key == mPreferenceKey) { if (preference.key == mPreferenceKey) {

View File

@@ -27,6 +27,7 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.ActionBar;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@@ -114,6 +115,15 @@ public class SettingsActivityTest {
assertThat(((ListenerFragment) fragments.get(1)).mOnActivityResultCalled).isTrue(); assertThat(((ListenerFragment) fragments.get(1)).mOnActivityResultCalled).isTrue();
} }
@Test
public void getActionBar_hasNoActionBar() {
final SettingsActivity activity = Robolectric.buildActivity(SettingsActivity.class).get();
final ActionBar actionBar = activity.getActionBar();
assertThat(actionBar).isNull();
}
public static class ListenerFragment extends Fragment implements OnActivityResultListener { public static class ListenerFragment extends Fragment implements OnActivityResultListener {
private boolean mOnActivityResultCalled; private boolean mOnActivityResultCalled;

View File

@@ -30,7 +30,6 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.ActionBar;
import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyResourcesManager; import android.app.admin.DevicePolicyResourcesManager;
import android.content.ComponentName; import android.content.ComponentName;
@@ -56,11 +55,9 @@ import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo; import android.os.storage.VolumeInfo;
import android.util.IconDrawableFactory; import android.util.IconDrawableFactory;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView; import android.widget.TextView;
import androidx.core.graphics.drawable.IconCompat; import androidx.core.graphics.drawable.IconCompat;
import androidx.fragment.app.FragmentActivity;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils; import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
@@ -71,7 +68,6 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment; import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
@@ -270,17 +266,6 @@ public class UtilsTest {
Utils.setActionBarShadowAnimation(null, null, null); Utils.setActionBarShadowAnimation(null, null, null);
} }
@Test
public void setActionBarShadowAnimation_shouldSetElevationToZero() {
final FragmentActivity activity = Robolectric.setupActivity(FragmentActivity.class);
final ActionBar actionBar = activity.getActionBar();
Utils.setActionBarShadowAnimation(activity, activity.getLifecycle(),
new ScrollView(mContext));
assertThat(actionBar.getElevation()).isEqualTo(0.f);
}
@Test @Test
public void isSettingsIntelligence_IsSI_returnTrue() { public void isSettingsIntelligence_IsSI_returnTrue() {
final String siPackageName = mContext.getString( final String siPackageName = mContext.getString(

View File

@@ -27,7 +27,7 @@ import static org.mockito.Mockito.when;
import android.app.UiModeManager; import android.app.UiModeManager;
import android.content.Context; import android.content.Context;
import android.widget.FrameLayout; import android.widget.LinearLayout;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
@@ -57,7 +57,7 @@ public class ContrastSelectorPreferenceControllerTest {
@Mock @Mock
private PreferenceScreen mScreen; private PreferenceScreen mScreen;
@Mock @Mock
private FrameLayout mFrameLayout; private LinearLayout mLinearLayout;
@Mock @Mock
private LayoutPreference mLayoutPreference; private LayoutPreference mLayoutPreference;
private Context mContext; private Context mContext;
@@ -72,7 +72,7 @@ public class ContrastSelectorPreferenceControllerTest {
when(mContext.getSystemService(UiModeManager.class)).thenReturn(mUiService); when(mContext.getSystemService(UiModeManager.class)).thenReturn(mUiService);
mController = new ContrastSelectorPreferenceController(mContext, PREFERENCE_KEY); mController = new ContrastSelectorPreferenceController(mContext, PREFERENCE_KEY);
when(mScreen.findPreference(PREFERENCE_KEY)).thenReturn(mLayoutPreference); when(mScreen.findPreference(PREFERENCE_KEY)).thenReturn(mLayoutPreference);
when(mLayoutPreference.findViewById(anyInt())).thenReturn(mFrameLayout); when(mLayoutPreference.findViewById(anyInt())).thenReturn(mLinearLayout);
} }
@Test @Test
@@ -102,7 +102,7 @@ public class ContrastSelectorPreferenceControllerTest {
public void displayPreference_shouldAddClickListener() { public void displayPreference_shouldAddClickListener() {
mController.displayPreference(mScreen); mController.displayPreference(mScreen);
verify(mFrameLayout, times(3)).setOnClickListener(any()); verify(mLinearLayout, times(3)).setOnClickListener(any());
} }
@Test @Test
@@ -110,6 +110,6 @@ public class ContrastSelectorPreferenceControllerTest {
mController.displayPreference(mScreen); mController.displayPreference(mScreen);
mController.onContrastChanged(1); mController.onContrastChanged(1);
verify(mFrameLayout, times(2)).setSelected(true); verify(mLinearLayout, times(2)).setSelected(true);
} }
} }

View File

@@ -0,0 +1,97 @@
/*
* 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.datetime;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import com.android.settingslib.core.AbstractPreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class TimeFeedbackPreferenceCategoryControllerTest {
private TestTimeFeedbackPreferenceCategoryController mController;
@Mock private AbstractPreferenceController mChildController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
Context context = RuntimeEnvironment.getApplication();
mController = new TestTimeFeedbackPreferenceCategoryController(context, "test_key");
mController.addChildController(mChildController);
}
@Test
public void getAvailabilityStatus_featureEnabledPrimary() {
mController.setTimeFeedbackFeatureEnabled(false);
when(mChildController.isAvailable()).thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void getAvailabilityStatus_childControllerSecondary() {
mController.setTimeFeedbackFeatureEnabled(true);
when(mChildController.isAvailable()).thenReturn(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
when(mChildController.isAvailable()).thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
/**
* Extend class under test to change {@link #isTimeFeedbackFeatureEnabled} to not call
* {@link TimeFeedbackLaunchUtils} because that's non-trivial to fake.
*/
private static class TestTimeFeedbackPreferenceCategoryController
extends TimeFeedbackPreferenceCategoryController {
private boolean mTimeFeedbackFeatureEnabled;
TestTimeFeedbackPreferenceCategoryController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
void setTimeFeedbackFeatureEnabled(boolean value) {
this.mTimeFeedbackFeatureEnabled = value;
}
@Override
protected boolean isTimeFeedbackFeatureEnabled() {
return mTimeFeedbackFeatureEnabled;
}
}
}

View File

@@ -0,0 +1,90 @@
/*
* 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.datetime;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import androidx.preference.Preference;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class TimeFeedbackPreferenceControllerTest {
private Context mContext;
@Before
public void setUp() {
mContext = spy(Robolectric.setupActivity(Activity.class));
}
@Test
public void emptyIntentUri_controllerNotAvailable() {
String emptyIntentUri = "";
TimeFeedbackPreferenceController controller =
new TimeFeedbackPreferenceController(mContext, "test_key", emptyIntentUri);
assertThat(controller.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void clickPreference() {
Preference preference = new Preference(mContext);
String intentUri =
"intent:#Intent;"
+ "action=com.android.settings.test.LAUNCH_USER_FEEDBACK;"
+ "package=com.android.settings.test.target;"
+ "end";
TimeFeedbackPreferenceController controller =
new TimeFeedbackPreferenceController(mContext, "test_key", intentUri);
// Click a preference that's not controlled by this controller.
preference.setKey("fake_key");
assertThat(controller.handlePreferenceTreeClick(preference)).isFalse();
// Check for startActivity() call.
verify(mContext, never()).startActivity(any());
// Click a preference controlled by this controller.
preference.setKey(controller.getPreferenceKey());
assertThat(controller.handlePreferenceTreeClick(preference)).isTrue();
// Check for startActivity() call.
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext).startActivity(intentCaptor.capture());
Intent actualIntent = intentCaptor.getValue();
assertThat(actualIntent.getAction()).isEqualTo(
"com.android.settings.test.LAUNCH_USER_FEEDBACK");
assertThat(actualIntent.getPackage()).isEqualTo("com.android.settings.test.target");
}
}

View File

@@ -36,6 +36,7 @@ import android.provider.Settings;
import com.android.server.display.feature.flags.Flags; import com.android.server.display.feature.flags.Flags;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@@ -85,6 +86,7 @@ public class EvenDimmerPreferenceControllerTest {
Settings.Secure.EVEN_DIMMER_ACTIVATED)).isEqualTo(0.0f); // false Settings.Secure.EVEN_DIMMER_ACTIVATED)).isEqualTo(0.0f); // false
} }
@Ignore("b/331324279")
@RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER) @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
@Test @Test
public void testGetAvailabilityStatus_flagOnConfigTrue() { public void testGetAvailabilityStatus_flagOnConfigTrue() {
@@ -97,6 +99,7 @@ public class EvenDimmerPreferenceControllerTest {
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
} }
@Ignore("b/331324279")
@Test @Test
@RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER) @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
public void testSetChecked_enable() throws Settings.SettingNotFoundException { public void testSetChecked_enable() throws Settings.SettingNotFoundException {
@@ -113,6 +116,7 @@ public class EvenDimmerPreferenceControllerTest {
Settings.Secure.EVEN_DIMMER_ACTIVATED)).isEqualTo(0.0f); // false Settings.Secure.EVEN_DIMMER_ACTIVATED)).isEqualTo(0.0f); // false
} }
@Ignore("b/331324279")
@Test @Test
@RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER) @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
public void testDisabledIfAutobrightnessIsOff() { public void testDisabledIfAutobrightnessIsOff() {

View File

@@ -38,6 +38,7 @@ import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.provider.Settings;
import android.view.View; import android.view.View;
import android.view.Window; import android.view.Window;
import android.view.WindowManager; import android.view.WindowManager;
@@ -54,6 +55,7 @@ import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin; import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
import org.junit.After; import org.junit.After;
import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@@ -80,11 +82,28 @@ public class SettingsHomepageActivityTest {
@Rule @Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule(); public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Before
public void setup() {
Settings.Global.putInt(ApplicationProvider.getApplicationContext().getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 1);
}
@After @After
public void tearDown() { public void tearDown() {
ShadowPasswordUtils.reset(); ShadowPasswordUtils.reset();
} }
@Test
public void launch_deviceUnprovisioned_finish() {
Settings.Global.putInt(ApplicationProvider.getApplicationContext().getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0);
SettingsHomepageActivity activity = Robolectric.buildActivity(
SettingsHomepageActivity.class).create().get();
assertThat(activity.isFinishing()).isTrue();
}
@Test @Test
public void launch_shouldHaveAnimationForIaFragment() { public void launch_shouldHaveAnimationForIaFragment() {
final SettingsHomepageActivity activity = Robolectric.buildActivity( final SettingsHomepageActivity activity = Robolectric.buildActivity(

View File

@@ -16,17 +16,26 @@
package com.android.settings.notification.zen; package com.android.settings.notification.zen;
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.AutomaticZenRule;
import android.app.Flags;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.net.Uri;
import android.os.Looper; import android.os.Looper;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.service.notification.ZenModeConfig;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
@@ -34,6 +43,7 @@ import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R; import com.android.settings.R;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
@@ -51,11 +61,15 @@ import java.util.List;
}) })
public class ZenModeEventRuleSettingsTest { public class ZenModeEventRuleSettingsTest {
@Mock @Rule
private FragmentActivity mActivity; public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
@Mock
private FragmentActivity mActivity;
@Mock @Mock
private Intent mIntent; private Intent mIntent;
@Mock
private ZenModeBackend mBackend;
private ZenModeEventRuleSettings mFragment; private ZenModeEventRuleSettings mFragment;
private Context mContext; private Context mContext;
@@ -92,6 +106,26 @@ public class ZenModeEventRuleSettingsTest {
//should not crash //should not crash
} }
@Test
@EnableFlags({Flags.FLAG_MODES_API, Flags.FLAG_MODES_UI})
public void updateEventRule_updatesConditionAndTriggerDescription() {
mFragment.setBackend(mBackend);
mFragment.mId = "id";
mFragment.mRule = new AutomaticZenRule.Builder("name", Uri.parse("condition")).build();
ZenModeConfig.EventInfo eventInfo = new ZenModeConfig.EventInfo();
eventInfo.calendarId = 1L;
eventInfo.calName = "My events";
mFragment.updateEventRule(eventInfo);
verify(mBackend).updateZenRule(eq("id"),
eq(new AutomaticZenRule.Builder(
"name",
ZenModeConfig.toEventConditionId(eventInfo))
.setTriggerDescription("My events")
.build()));
}
@Test @Test
public void testNoDuplicateCalendars() { public void testNoDuplicateCalendars() {
List<ZenModeEventRuleSettings.CalendarInfo> calendarsList = new ArrayList<>(); List<ZenModeEventRuleSettings.CalendarInfo> calendarsList = new ArrayList<>();

View File

@@ -16,17 +16,26 @@
package com.android.settings.notification.zen; package com.android.settings.notification.zen;
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.AutomaticZenRule;
import android.app.Flags;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.net.Uri;
import android.os.Looper; import android.os.Looper;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.service.notification.ZenModeConfig;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
@@ -34,25 +43,33 @@ import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R; import com.android.settings.R;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowToast; import org.robolectric.shadows.ShadowToast;
import java.util.Calendar;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@Config(shadows = { @Config(shadows = {
com.android.settings.testutils.shadow.ShadowFragment.class, com.android.settings.testutils.shadow.ShadowFragment.class,
}) })
public class ZenModeScheduleRuleSettingsTest { public class ZenModeScheduleRuleSettingsTest {
@Mock @Rule
private FragmentActivity mActivity; public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
@Mock
private FragmentActivity mActivity;
@Mock @Mock
private Intent mIntent; private Intent mIntent;
@Mock
private ZenModeBackend mBackend;
private ZenModeScheduleRuleSettings mFragment; private ZenModeScheduleRuleSettings mFragment;
private Context mContext; private Context mContext;
@@ -88,4 +105,25 @@ public class ZenModeScheduleRuleSettingsTest {
//should not crash //should not crash
} }
@Test
@EnableFlags({Flags.FLAG_MODES_API, Flags.FLAG_MODES_UI})
public void updateScheduleRule_updatesConditionAndTriggerDescription() {
mFragment.setBackend(mBackend);
mFragment.mId = "id";
mFragment.mRule = new AutomaticZenRule.Builder("name", Uri.parse("condition")).build();
ZenModeConfig.ScheduleInfo scheduleInfo = new ZenModeConfig.ScheduleInfo();
scheduleInfo.days = new int[] { Calendar.MONDAY };
scheduleInfo.startHour = 1;
scheduleInfo.endHour = 2;
mFragment.updateScheduleRule(scheduleInfo);
ArgumentCaptor<AutomaticZenRule> updatedRuleCaptor = ArgumentCaptor.forClass(
AutomaticZenRule.class);
verify(mBackend).updateZenRule(eq("id"), updatedRuleCaptor.capture());
assertThat(updatedRuleCaptor.getValue().getConditionId())
.isEqualTo(ZenModeConfig.toScheduleConditionId(scheduleInfo));
assertThat(updatedRuleCaptor.getValue().getTriggerDescription()).isNotEmpty();
}
} }

View File

@@ -55,7 +55,8 @@ class BackupTasksAppsPreferenceControllerTest {
@Test @Test
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_PERFORM_BACKUP_TASKS_IN_SETTINGS) @RequiresFlagsEnabled(Flags.FLAG_ENABLE_PERFORM_BACKUP_TASKS_IN_SETTINGS)
fun getAvailabilityStatus_enableBackupTasksApps_returnAvailable() { fun getAvailabilityStatus_enableBackupTasksApps_returnAvailable() {
assertThat(controller.isAvailable).isTrue() // Feature is currently disabled so it should return false regardless of flag status.
assertThat(controller.isAvailable).isFalse()
} }
@Test @Test

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.android.settings.development.widevine; package com.android.settings.development.mediadrm;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assume.assumeTrue; import static org.junit.Assume.assumeTrue;
@@ -43,23 +43,23 @@ import org.junit.runner.RunWith;
import java.util.UUID; import java.util.UUID;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public class ForceL3FallbackPreferenceControllerTest { public class ForceSwSecureCryptoFallbackPreferenceControllerTest {
private static final String PREF_KEY = "force_l3_fallback"; private static final String PREF_KEY = "force_swcrypto_fallback";
private static final UUID WIDEVINE_UUID = private static final UUID WIDEVINE_UUID =
new UUID(0xEDEF8BA979D64ACEL, 0xA3C827DCD51D21EDL); new UUID(0xEDEF8BA979D64ACEL, 0xA3C827DCD51D21EDL);
private static final String TAG = "ForceL3FallbackPreferenceControllerTest"; private static final String TAG = "ForceSwSecureCryptoFallbackPreferenceControllerTest";
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private Context mContext; private Context mContext;
private ForceL3FallbackPreferenceController mController; private ForceSwSecureCryptoFallbackPreferenceController mController;
private SwitchPreference mPreference; private SwitchPreference mPreference;
@Before @Before
public void setUp() { public void setUp() {
mContext = ApplicationProvider.getApplicationContext(); mContext = ApplicationProvider.getApplicationContext();
mController = new ForceL3FallbackPreferenceController(mContext, PREF_KEY); mController = new ForceSwSecureCryptoFallbackPreferenceController(mContext, PREF_KEY);
mPreference = new SwitchPreference(mContext); mPreference = new SwitchPreference(mContext);
WidevineProperties.forcel3_enabled(false); WidevineProperties.forcel3_enabled(false);
} }