Snap for 5198681 from 92da0c0005 to qt-release

Change-Id: I18aff416fd8f97b7b3365a0a284f18c3b790e42d
This commit is contained in:
android-build-team Robot
2018-12-23 04:03:10 +00:00
197 changed files with 5607 additions and 1465 deletions

View File

@@ -2973,11 +2973,16 @@
android:label="@string/settings_panel_title"
android:theme="@style/Theme.BottomDialog"
android:excludeFromRecents="true"
android:launchMode="singleTask">
android:launchMode="singleTask"
android:exported="true">
<intent-filter>
<action android:name="android.settings.SETTINGSPANEL" />
<action android:name="android.settings.panel.action.INTERNET_CONNECTIVITY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.settings.panel.action.VOLUME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<provider android:name=".slices.SettingsSliceProvider"

3
OWNERS
View File

@@ -8,6 +8,7 @@ dehboxturtle@google.com
dhnishi@google.com
dling@google.com
edgarwang@google.com
emilychuang@google.com
jackqdyulei@google.com
mfritze@google.com
rafftsai@google.com
@@ -18,4 +19,4 @@ zhfan@google.com
miket@google.com
# Exempt resource files (because they are in a flat directory and too hard to manage via OWNERS)
per-file *.xml=*
per-file *.xml=*

View File

@@ -21,5 +21,5 @@
android:height="18dp">
<path
android:pathData="M36 16l-2 0 0 -4C34 6.48 29.52 2 24 2 18.48 2 14 6.48 14 12l0 4 -2 0c-2.21 0 -4 1.79 -4 4l0 20c0 2.21 1.79 4 4 4l24 0c2.21 0 4 -1.79 4 -4l0 -20c0 -2.21 -1.79 -4 -4 -4zM24 34c-2.21 0 -4 -1.79 -4 -4 0 -2.21 1.79 -4 4 -4 2.21 0 4 1.79 4 4 0 2.21 -1.79 4 -4 4zm6.2 -18l-12.4 0 0 -4c0 -3.42 2.78 -6.2 6.2 -6.2 3.42 0 6.2 2.78 6.2 6.2l0 4z"
android:fillColor="?attr/frictionIconColor" />
android:fillColor="?android:attr/colorControlNormal" />
</vector>

View File

@@ -20,7 +20,7 @@
android:width="18dp"
android:height="18dp">
<path android:fillColor="?attr/frictionIconColor"
<path android:fillColor="?android:attr/colorControlNormal"
android:pathData="M9.56 8.1c-1.6-.51-2.66-.71-2.66-1.88 0-.83 .72 -1.62 2.1-1.62 1.59 0 2.1 .88
2.1 1.94H13c0-1.79-1.17-3.09-3-3.44V1H8v2.11c-1.58 .32 -3 1.37-3 3.12 0 2.25
1.78 2.8 4 3.52 1.88 .61 2.25 1.04 2.25 2.09 0 .9-.67 1.56-2.25 1.56-1.2

View File

@@ -70,41 +70,6 @@
android:layout_height="wrap_content"
android:text="@string/security_settings_fingerprint_enroll_finish_message"/>
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<com.google.android.setupdesign.view.ButtonBarLayout
style="@style/SuwGlifButtonBar.Stackable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipChildren="false"
android:clipToPadding="false">
<Button
style="@style/SetupWizardButton.Negative"
android:id="@+id/add_another_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="@string/fingerprint_enroll_button_add" />
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
style="@style/SetupWizardButton.Positive"
android:id="@+id/next_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/security_settings_fingerprint_enroll_done" />
</com.google.android.setupdesign.view.ButtonBarLayout>
</LinearLayout>
<com.google.android.setupdesign.view.FillContentLayout

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2015 The Android Open Source Project
<!-- Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,37 +16,31 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/suw_layout_navigation_bar"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:layout_height="match_parent"
android:paddingEnd="16dp"
android:paddingStart="16dp">
<Button
android:id="@+id/suw_navbar_back"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="@+id/suw_navbar_more"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone" />
<Button
android:id="@+id/suw_navbar_next"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:text="@string/wizard_next"
android:textColor="@android:color/white"
android:backgroundTint="@color/storage_wizard_button" />
android:id="@+id/title"/>
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="?android:attr/listDivider" />
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/toggle"
android:checked="true"/>
</LinearLayout>

View File

@@ -21,8 +21,7 @@
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="?attr/face_layout_theme"
app:sucFooter="@layout/face_enroll_enrolling_footer">
style="?attr/face_layout_theme">
<LinearLayout
style="@style/SuwContentFrame"

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2018 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
style="@style/SuwGlifButton.Secondary"
android:id="@+id/skip_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/security_settings_face_enroll_enrolling_skip" />
</LinearLayout>

View File

@@ -21,8 +21,7 @@
android:id="@+id/setup_wizard_layout"
style="?attr/face_layout_theme"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:sucFooter="@layout/face_enroll_finish_footer">
android:layout_height="match_parent">
<LinearLayout
style="@style/SuwContentFrame"

View File

@@ -1,37 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2018 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
<com.google.android.setupdesign.view.ButtonBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar.Stackable"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
style="@style/SuwGlifButton.Primary"
android:id="@+id/next_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/security_settings_face_enroll_done" />
</com.google.android.setupdesign.view.ButtonBarLayout>

View File

@@ -18,11 +18,11 @@
<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:FaceEnrollAccessibilitySwitch="http://schemas.android.com/apk/res/com.android.settings"
style="?attr/face_layout_theme"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:sucFooter="@layout/face_enroll_introduction_footer">
android:layout_height="match_parent">
<LinearLayout
style="@style/SuwContentFrame"
@@ -59,6 +59,41 @@
</com.google.android.setupdesign.view.FillContentLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<Button
android:id="@+id/accessibility_button"
style="@style/SuwGlifButton.Secondary"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/security_settings_face_enroll_introduction_accessibility" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/accessibility_layout"
android:orientation="vertical"
android:visibility="invisible">
<com.android.settings.biometrics.face.FaceEnrollAccessibilityToggle
android:id="@+id/toggle_diversity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
FaceEnrollAccessibilitySwitch:messageText="@string/security_settings_face_enroll_introduction_accessibility_diversity"/>
<com.android.settings.biometrics.face.FaceEnrollAccessibilityToggle
android:id="@+id/toggle_vision"
android:layout_width="match_parent"
android:layout_height="wrap_content"
FaceEnrollAccessibilitySwitch:messageText="@string/security_settings_face_enroll_introduction_accessibility_vision"/>
</LinearLayout>
</FrameLayout>
</LinearLayout>
</com.google.android.setupdesign.GlifLayout>

View File

@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2018 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
<com.google.android.setupdesign.view.ButtonBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar.Stackable"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/face_cancel_button"
style="@style/SuwGlifButton.Secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/security_settings_face_enroll_introduction_cancel" />
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="@+id/face_next_button"
style="@style/SuwGlifButton.Primary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/wizard_next" />
</com.google.android.setupdesign.view.ButtonBarLayout>

View File

@@ -21,8 +21,7 @@
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="?attr/fingerprint_layout_theme"
app:sucFooter="@layout/fingerprint_enroll_enrolling_base_footer">
style="?attr/fingerprint_layout_theme">
<LinearLayout
style="@style/SuwContentFrame"

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
style="@style/SuwGlifButton.Secondary"
android:id="@+id/skip_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/security_settings_fingerprint_enroll_enrolling_skip" />
</LinearLayout>

View File

@@ -21,8 +21,7 @@
android:id="@+id/setup_wizard_layout"
style="?attr/fingerprint_layout_theme"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:sucFooter="@layout/fingerprint_enroll_find_sensor_base_footer">
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
style="@style/SuwGlifButton.Secondary"
android:id="@+id/skip_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/skip_label" />
</LinearLayout>

View File

@@ -21,8 +21,7 @@
android:id="@+id/setup_wizard_layout"
style="?attr/fingerprint_layout_theme"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:sucFooter="@layout/fingerprint_enroll_finish_base_footer">
android:layout_height="match_parent">
<LinearLayout
style="@style/SuwContentFrame"

View File

@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
<com.google.android.setupdesign.view.ButtonBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar.Stackable"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
style="@style/SuwGlifButton.Secondary"
android:id="@+id/add_another_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fingerprint_enroll_button_add" />
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
style="@style/SuwGlifButton.Primary"
android:id="@+id/next_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/security_settings_fingerprint_enroll_done" />
</com.google.android.setupdesign.view.ButtonBarLayout>

View File

@@ -21,8 +21,7 @@
style="?attr/fingerprint_layout_theme"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:sucFooter="@layout/fingerprint_enroll_introduction_footer">
android:layout_height="match_parent">
<LinearLayout
style="@style/SuwContentFrame"

View File

@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License
-->
<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
<com.google.android.setupdesign.view.ButtonBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar.Stackable"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/fingerprint_cancel_button"
style="@style/SuwGlifButton.Secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/security_settings_fingerprint_enroll_introduction_cancel" />
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="@+id/fingerprint_next_button"
style="@style/SuwGlifButton.Primary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/wizard_next" />
</com.google.android.setupdesign.view.ButtonBarLayout>

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dismissal_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/homepage_card_padding_start"
android:layout_marginTop="@dimen/homepage_card_padding_start"
android:text="@string/contextual_card_dismiss_confirm_message"
android:textAppearance="@style/TextAppearance.ContextualCardDismissalText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom|end">
<Button
android:id="@+id/keep"
style="@style/ContextualCardDismissalButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/contextual_card_dismiss_keep"/>
<Button
android:id="@+id/remove"
style="@style/ContextualCardDismissalButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/contextual_card_dismiss_remove"/>
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/ContextualCardStyle">
<ViewFlipper
android:id="@+id/view_flipper"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/homepage_card_padding_start"
android:paddingEnd="@dimen/homepage_card_padding_end"
android:paddingTop="@dimen/homepage_half_card_padding_top"
android:paddingBottom="@dimen/homepage_half_card_padding_bottom"
android:orientation="vertical">
<ImageView
android:id="@android:id/icon"
android:layout_width="@dimen/homepage_card_icon_size"
android:layout_height="@dimen/homepage_card_icon_size"
android:tint="?android:attr/colorAccent"/>
<TextView
android:id="@android:id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:minLines="1"
android:ellipsize="end"
android:layout_marginTop="@dimen/homepage_half_card_title_margin_top"
android:textAppearance="@style/TextAppearance.ConditionCardTitle"/>
</LinearLayout>
<!--dismissal view-->
<include layout="@layout/homepage_dismissal_view"/>
</ViewFlipper>
</com.google.android.material.card.MaterialCardView>

View File

@@ -22,7 +22,7 @@
style="@style/ContextualCardStyle">
<ViewFlipper
android:id="@+id/viewFlipper"
android:id="@+id/view_flipper"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@@ -34,40 +34,7 @@
android:paddingEnd="@dimen/homepage_card_padding_end"/>
<!--dismissal view-->
<LinearLayout
android:id="@+id/dismissal_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/homepage_dismissal_view"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/homepage_card_padding_start"
android:layout_marginTop="@dimen/homepage_card_padding_start"
android:text="@string/contextual_card_dismiss_confirm_message"
style="@style/TextAppearance.ContextualCardDismissalText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom|end">
<Button
android:id="@+id/keep"
style="@style/ContextualCardDismissalButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/contextual_card_dismiss_keep"/>
<Button
android:id="@+id/remove"
style="@style/ContextualCardDismissalButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/contextual_card_dismiss_remove"/>
</LinearLayout>
</LinearLayout>
</ViewFlipper>
</com.google.android.material.card.MaterialCardView>

View File

@@ -22,7 +22,7 @@
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:id="@+id/panel_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"

View File

@@ -1,46 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/storage_back_button"
style="@style/SuwGlifButton.Secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onNavigateBack"
android:visibility="gone"
android:text="@string/wizard_back" />
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="@+id/storage_next_button"
style="@style/SuwGlifButton.Primary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onNavigateNext"
android:visibility="gone"
android:text="@string/wizard_next" />
</LinearLayout>

View File

@@ -19,8 +19,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:sucFooter="@layout/storage_wizard_footer">
android:layout_height="match_parent">
<LinearLayout
style="@style/SuwContentFrame"

View File

@@ -19,8 +19,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:sucFooter="@layout/storage_wizard_footer">
android:layout_height="match_parent">
<LinearLayout
style="@style/SuwContentFrame"

View File

@@ -19,8 +19,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:sucFooter="@layout/storage_wizard_footer">
android:layout_height="match_parent">
<LinearLayout
style="@style/SuwContentFrame"

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2015 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"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:sucFooter="@layout/storage_wizard_footer">
<LinearLayout
style="@style/SuwContentFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/storage_wizard_ready_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/suw_description_margin_top"
android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
android:textColor="?android:attr/textColorPrimary" />
</LinearLayout>
</com.google.android.setupdesign.GlifLayout>

View File

@@ -0,0 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fadeScrollbars="false"
android:scrollIndicators="top|bottom">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="24dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_calls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_mode_calls" />
<TextView
android:id="@+id/zen_custom_settings_dialog_calls_allow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_messages"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_mode_messages" />
<TextView
android:id="@+id/zen_custom_settings_dialog_messages_allow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_alarms"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_mode_alarms" />
<TextView
android:id="@+id/zen_custom_settings_dialog_alarms_allow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_media"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_mode_media" />
<TextView
android:id="@+id/zen_custom_settings_dialog_media_allow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_system"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_mode_system" />
<TextView
android:id="@+id/zen_custom_settings_dialog_system_allow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_reminders"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_mode_reminders"/>
<TextView
android:id="@+id/zen_custom_settings_dialog_reminders_allow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_events"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_mode_events"/>
<TextView
android:id="@+id/zen_custom_settings_dialog_events_allow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="14dp">
<TextView
android:id="@+id/zen_custom_settings_dialog_notifications"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_custom_settings_notifications_header" />
<TextView
android:id="@+id/zen_custom_settings_dialog_show_notifications"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@@ -219,7 +219,7 @@
</string-array>
<!-- Values for security type for wireless tether -->
<string-array name="wifi_tether_security_values">
<string-array name="wifi_tether_security_values" translatable="false">
<!-- Do not translate. -->
<item>4</item>
<!-- Do not translate. -->
@@ -1081,14 +1081,14 @@
<item>@string/zen_mode_from_anyone</item>
<item>@string/zen_mode_from_contacts</item>
<item>@string/zen_mode_from_starred</item>
<item>@string/zen_mode_from_none_calls</item>
<item>@string/zen_mode_from_none_messages</item>
</string-array>
<string-array name="zen_mode_contacts_calls_entries" translatable="false">
<item>@string/zen_mode_from_anyone</item>
<item>@string/zen_mode_from_contacts</item>
<item>@string/zen_mode_from_starred</item>
<item>@string/zen_mode_from_none_messages</item>
<item>@string/zen_mode_from_none_calls</item>
</string-array>
<string-array name="zen_mode_contacts_values" translatable="false">

View File

@@ -146,6 +146,11 @@
<attr name="thickness" format="dimension" />
</declare-styleable>
<!-- For Face enroll accessibility toggle -->
<declare-styleable name="FaceEnrollAccessibilityToggle">
<attr name="messageText" format="reference" />
</declare-styleable>
<!-- For TwoStatesButtonPreference -->
<declare-styleable name="TwoStateButtonPreference">
<attr name="textOn" format="reference" />
@@ -163,6 +168,4 @@
<attr name="ic_menu_moreoverflow" format="reference" />
<attr name="side_margin" format="reference|dimension" />
<attr name="wifi_signal_color" format="reference" />
<attr name="frictionIconColor" format="reference|color" />
</resources>

View File

@@ -168,4 +168,7 @@
<!-- Uri that represents extra bluetooth settings -->
<string name="config_bluetooth_device_settings_uri" translatable="false">content://com.google.android.gms.nearby.fastpair/settings_slice?addr=<xliff:g id="mac_address">%1$s</xliff:g></string>
<!-- ComponentName to launch a vendor-specific enrollment activity if available -->
<string name="config_face_enroll" translatable="false"></string>
</resources>

View File

@@ -329,6 +329,9 @@
<dimen name="homepage_card_side_margin">4dp</dimen>
<dimen name="homepage_card_padding_start">16dp</dimen>
<dimen name="homepage_card_padding_end">16dp</dimen>
<dimen name="homepage_half_card_padding_top">12dp</dimen>
<dimen name="homepage_half_card_padding_bottom">16dp</dimen>
<dimen name="homepage_half_card_title_margin_top">12dp</dimen>
<!-- Horizontal divider size and margin -->
<dimen name="horizontal_divider_margin_top">4dp</dimen>

View File

@@ -877,6 +877,12 @@
<string name="security_settings_face_preference_summary_none">Tap to set up face authentication</string>
<!-- Title shown for menu item that launches face settings or enrollment. [CHAR LIMIT=32] -->
<string name="security_settings_face_preference_title">Face authentication</string>
<!-- Button shown which shows accessibility toggles for face enrollment when clicked. [CHAR LIMIT=32] -->
<string name="security_settings_face_enroll_introduction_accessibility">Use accessibility setup</string>
<!-- Message shown for a toggle which when disabled, allows the user to enroll using a simpler flow for accessibility [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_accessibility_diversity"></string>
<!-- Message shown for a toggle which when disabled, allows the user to enroll using a simpler flow for accessibility [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_accessibility_vision"></string>
<!-- Button text to cancel enrollment from the introduction [CHAR LIMIT=22] -->
<string name="security_settings_face_enroll_introduction_cancel">Cancel</string>
<!-- Introduction title shown in face enrollment to introduce the face unlock feature [CHAR LIMIT=40] -->
@@ -6938,7 +6944,7 @@
<string name="keywords_sounds">speaker beep, speaker, volume, mute, silence, audio, music</string>
<string name="keywords_sounds_and_notifications_interruptions">dont don\u2019t disturb, interrupt, interruption, break</string>
<string name="keywords_app">RAM</string>
<string name="keywords_location">nearby, location, history, reporting</string>
<string name="keywords_location">nearby, location, history, reporting, GPS</string>
<string name="keywords_accounts">account</string>
<string name="keywords_users">restriction, restrict, restricted</string>
<string name="keywords_keyboard_and_ime">text correction, correct, sound, vibrate, auto, language, gesture, suggest, suggestion, theme, offensive, word, type, emoji, international</string>
@@ -7330,8 +7336,8 @@
<!-- [CHAR LIMIT=110] Zen mode settings footer: Footer showing length of DND -->
<string name="zen_mode_settings_dnd_manual_indefinite">Do Not Disturb will stay on until you turn it off</string>
<!-- [CHAR LIMIT=110] Zen mode settings footer: Footer showing how DND was triggered by an automatic DND rule -->
<string name="zen_mode_settings_dnd_automatic_rule">Do Not Disturb was automatically turned on by a rule (<xliff:g id="rule_name" example="Weeknights">%s</xliff:g>)</string>
<!-- [CHAR LIMIT=110] Zen mode settings footer: Footer showing how DND was triggered by an automatic DND schedule -->
<string name="zen_mode_settings_dnd_automatic_rule">Do Not Disturb was automatically turned on by a schedule (<xliff:g id="rule_name" example="Weeknights">%s</xliff:g>)</string>
<!-- [CHAR LIMIT=110] Zen mode settings footer: Footer how DND was triggered by an app -->
<string name="zen_mode_settings_dnd_automatic_rule_app">Do Not Disturb was automatically turned on by an app (<xliff:g id="app_name" example="Android Services">%s</xliff:g>)</string>
@@ -7339,6 +7345,9 @@
<!-- [CHAR LIMIT=120] Zen mode settings footer: Footer informing user DND has custom settings. -->
<string name="zen_mode_settings_dnd_custom_settings_footer">Do Not Disturb is on for <xliff:g id="rule_names" example="Sleeping and Work">%s</xliff:g> with custom settings.</string>
<!-- [CHAR LIMIT=120] Zen mode settings footer: Link following zen_mode_settings_dnd_custom_settings_footer to see the currently applied custom dnd settings. -->
<string name="zen_mode_settings_dnd_custom_settings_footer_link"><annotation id="link"> View custom settings</annotation></string>
<!--[CHAR LIMIT=40] Zen Interruption level: Priority. -->
<string name="zen_interruption_level_priority">Priority only</string>
@@ -7402,6 +7411,17 @@
<!-- Do not disturb settings, sound and vibrations summary [CHAR LIMIT=100]-->
<string name="zen_sound_three_allowed">Muted, but allow <xliff:g id="sound_type" example="alarms">%1$s</xliff:g>, <xliff:g id="sound_type" example="alarms">%2$s</xliff:g>, and <xliff:g id="sound_type" example="media">%3$s</xliff:g></string>
<!-- Do not disturb custom settings dialog title [CHAR LIMIT=40]-->
<string name="zen_custom_settings_dialog_title">Custom settings</string>
<!-- Do not disturb custom settings dialog button label [CHAR LIMIT=40]-->
<string name="zen_custom_settings_dialog_review_schedule">Review schedule</string>
<!-- Do not disturb custom settings dialog button label [CHAR LIMIT=40]-->
<string name="zen_custom_settings_dialog_ok">Got it</string>
<!-- Do not disturb custom settings notifications header [CHAR LIMIT=40]-->
<string name="zen_custom_settings_notifications_header">Notifications</string>
<!-- Do not disturb custom settings duration header [CHAR LIMIT=40]-->
<string name="zen_custom_settings_duration_header">Duration</string>
<!-- Do not disturb settings, messages, events and reminders title [CHAR LIMIT=100]-->
<string name="zen_msg_event_reminder_title">Messages, events &amp; reminders</string>
<!-- Do not disturb settings, messages, events and reminders footer [CHAR LIMIT=NONE]-->
@@ -7943,6 +7963,9 @@
<!-- [CHAR LIMIT=120] Zen mode settings: Summay text indicating the currenty dnd schedule is using custom behavior -->
<string name="zen_mode_custom_behavior_summary">Create custom settings for this schedule</string>
<!-- [CHAR LIMIT=100] Zen mode settings: Category text indicating the schedule this custom behavior will be configured for-->
<string name="zen_mode_custom_behavior_category_title">For \u2018<xliff:g id="schedule_name" example="Schedule 1">%1$s</xliff:g>\u2019</string>
<!-- [CHAR LIMIT=40] General divider text when concatenating multiple items in a text summary -->
<string name="summary_divider_text">,\u0020</string>
@@ -7958,9 +7981,12 @@
<!-- [CHAR LIMIT=40] Zen mode settings: Allow calls toggle title -->
<string name="zen_mode_calls_title">Calls</string>
<!-- [CHAR LIMIT=20] Zen mode settings: Calls screen footer -->
<!-- [CHAR LIMIT=NONE] Zen mode settings: Calls screen footer -->
<string name="zen_mode_calls_footer">When Do Not Disturb is on, incoming calls are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
<!-- [CHAR LIMIT=NONE] Zen mode custom rule settings: Calls screen footer -->
<string name="zen_mode_custom_calls_footer">For \u2018<xliff:g id="schedule_name" example="Schedule 1">%1$s</xliff:g>\u2019 incoming calls are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
<!-- [CHAR LIMIT=50] Zen mode settings: Starred contacts preference title -->
<string name="zen_mode_starred_contacts_title">Starred contacts</string>
@@ -7976,6 +8002,9 @@
<!-- Do not disturb settings, messages, events and reminders footer [CHAR LIMIT=NONE]-->
<string name="zen_mode_messages_footer">When Do Not Disturb is on, incoming text messages are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
<!-- [CHAR LIMIT=NONE] Zen mode custom rule settings: Messages screen footer -->
<string name="zen_mode_custom_messages_footer">For \u2018<xliff:g id="schedule_name" example="Schedule 1">%1$s</xliff:g>\u2019 incoming text messages are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Allow messages to bypass DND title -->
<string name="zen_mode_messages_title">Text messages</string>
@@ -8039,11 +8068,11 @@
<!-- [CHAR LIMIT=100] Zen mode settings: Allow apps to bypass DND title-->
<string name="zen_mode_bypassing_apps_title">App exceptions</string>
<!-- [CHAR LIMIT=80] Zen mode settings: Allow apps to bypass DND -->
<!-- [CHAR LIMIT=120] Zen mode settings: Allow apps to bypass DND -->
<plurals name="zen_mode_bypassing_apps_subtext">
<item quantity="zero">No apps can override Do Not Disturb</item>
<item quantity="one">1 app can override Do Not Disturb</item>
<item quantity="other"><xliff:g id="number" example="2">%1$d</xliff:g> apps can override Do Not Disturb</item>
<item quantity="one">Notifications from 1 app can override Do Not Disturb</item>
<item quantity="other">Notifications from <xliff:g id="number" example="2">%1$d</xliff:g> apps can override Do Not Disturb</item>
</plurals>
<!-- [CHAR LIMIT=50] Zen mode settings: Events (ie: calendar events) -->

View File

@@ -37,7 +37,6 @@
<item name="wifi_signal">@drawable/wifi_signal</item>
<item name="wifi_signal_color">?android:attr/colorAccent</item>
<item name="wifi_friction">@drawable/wifi_friction</item>
<item name="frictionIconColor">?android:colorControlNormal</item>
<item name="side_margin">@dimen/settings_side_margin</item>
<item name="suwListItemIconColor">?android:attr/colorAccent</item>
@@ -187,7 +186,7 @@
<item name="preferenceTheme">@style/PreferenceTheme</item>
<!-- action bar, needed for search bar icon tinting -->
<item name="android:actionBarTheme">@*android:style/ThemeOverlay.DeviceDefault.ActionBar.Accent</item>
<item name="android:actionBarTheme">@*android:style/ThemeOverlay.DeviceDefault.ActionBar</item>
<!-- For battery status icons in -->
<item name="batteryGoodColor">@color/battery_good_color_light</item>

View File

@@ -17,7 +17,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="mobile_network_pref_screen"
android:title="@string/network_settings_title"
settings:initialExpandedChildrenCount="4">
<Preference

View File

@@ -33,7 +33,7 @@
android:order="1"
android:title="@string/my_device_info_device_name_preference_title"
android:summary="@string/summary_placeholder"
settings:enableCopying="true" />
settings:enableCopying="true"/>
<!-- Account name -->
<Preference
@@ -52,7 +52,7 @@
settings:allowDynamicSummaryInSlice="true"
settings:controller=
"com.android.settings.deviceinfo.PhoneNumberPreferenceController"
settings:enableCopying="true" />
settings:enableCopying="true"/>
<Preference
android:key="emergency_info"
@@ -103,7 +103,7 @@
android:summary="@string/summary_placeholder"
settings:allowDynamicSummaryInSlice="true"
settings:controller=
"com.android.settings.deviceinfo.DeviceModelPreferenceController" />
"com.android.settings.deviceinfo.DeviceModelPreferenceController"/>
<!-- IMEI -->
<Preference
@@ -122,7 +122,7 @@
android:summary="@string/summary_placeholder"
settings:allowDynamicSummaryInSlice="true"
settings:controller=
"com.android.settings.deviceinfo.firmwareversion.FirmwareVersionPreferenceController" />
"com.android.settings.deviceinfo.firmwareversion.FirmwareVersionPreferenceController"/>
<!--IP address -->
<Preference
@@ -132,7 +132,7 @@
android:summary="@string/summary_placeholder"
android:selectable="false"
settings:allowDividerAbove="true"
settings:enableCopying="true" />
settings:enableCopying="true"/>
<!-- Wi-Fi MAC address -->
<Preference
@@ -141,7 +141,7 @@
android:title="@string/status_wifi_mac_address"
android:summary="@string/summary_placeholder"
android:selectable="false"
settings:enableCopying="true" />
settings:enableCopying="true"/>
<!-- Bluetooth address -->
<Preference
@@ -150,7 +150,7 @@
android:title="@string/status_bt_address"
android:summary="@string/summary_placeholder"
android:selectable="false"
settings:enableCopying="true" />
settings:enableCopying="true"/>
<!-- Device up time -->
<Preference
@@ -158,7 +158,7 @@
android:order="37"
android:title="@string/status_up_time"
android:summary="@string/summary_placeholder"
android:selectable="false" />
android:selectable="false"/>
<!-- Manual -->
<Preference
@@ -173,7 +173,7 @@
android:key="device_feedback"
android:order="41"
android:title="@string/device_feedback"
settings:keywords="@string/keywords_device_feedback" />
settings:keywords="@string/keywords_device_feedback"/>
<!-- Device FCC equipment id -->
<Preference
@@ -189,6 +189,7 @@
android:title="@string/build_number"
android:summary="@string/summary_placeholder"
settings:allowDividerAbove="true"
settings:enableCopying="true" />
settings:enableCopying="true"
settings:controller="com.android.settings.deviceinfo.BuildNumberPreferenceController"/>
</PreferenceScreen>

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="zen_custom_rule_configuration_page"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/zen_mode_settings_title">
<PreferenceCategory
android:key="zen_custom_rule_configuration_category">
<!-- Calls -->
<Preference
android:key="zen_rule_calls_settings"
android:title="@string/zen_mode_calls" />
<!-- Messages -->
<Preference
android:key="zen_rule_messages_settings"
android:title="@string/zen_mode_messages" />
<!-- Alarms -->
<SwitchPreference
android:key="zen_rule_alarms"
android:title="@string/zen_mode_alarms"/>
<!-- Media -->
<SwitchPreference
android:key="zen_rule_media"
android:title="@string/zen_mode_media"/>
<!-- System -->
<SwitchPreference
android:key="zen_rule_system"
android:title="@string/zen_mode_system"/>
<!-- Reminders -->
<SwitchPreference
android:key="zen_rule_reminders"
android:title="@string/zen_mode_reminders"/>
<!-- Events -->
<SwitchPreference
android:key="zen_rule_events"
android:title="@string/zen_mode_events"/>
</PreferenceCategory>
<Preference
android:key="zen_rule_notifications"
android:title="@string/zen_mode_restrict_notifications_title"
settings:allowDividerAbove="true"/>
</PreferenceScreen>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="zen_custom_rule_settings_page"
android:title="@string/zen_mode_custom_behavior_title">
<PreferenceCategory
android:key="zen_custom_rule_category">
<com.android.settings.notification.ZenCustomRadioButtonPreference
android:key="zen_custom_rule_setting_default"
android:title="@string/zen_mode_custom_behavior_summary_default"/>
<com.android.settings.notification.ZenCustomRadioButtonPreference
android:key="zen_custom_rule_setting"
android:title="@string/zen_mode_custom_behavior_summary" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -45,4 +45,10 @@
android:title="@string/zen_mode_event_rule_reply"
android:summary="%s" />
<!-- Custom Do Not Disturb Setting-->
<Preference
android:key="zen_custom_setting"
android:title="@string/zen_mode_custom_behavior_title"
android:order="100" />
</PreferenceScreen>

View File

@@ -50,7 +50,7 @@
<!-- Custom Do Not Disturb Setting-->
<Preference
android:key="zen_schedule_custom_setting"
android:key="zen_custom_setting"
android:title="@string/zen_mode_custom_behavior_title"
android:order="100" />

View File

@@ -22,7 +22,6 @@ import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
@@ -35,8 +34,7 @@ import java.io.File;
public class ManualDisplayActivity extends Activity {
private static final String TAG = "SettingsManualActivity";
private static final String DEFAULT_MANUAL_PATH = "/system/etc/MANUAL.html.gz";
private static final String PROPERTY_MANUAL_PATH = "ro.config.manual_path";
private static final String MANUAL_PATH = "/system/etc/MANUAL.html.gz";
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -47,16 +45,9 @@ public class ManualDisplayActivity extends Activity {
finish(); // No manual to display for this device
}
final String path = SystemProperties.get(PROPERTY_MANUAL_PATH, DEFAULT_MANUAL_PATH);
if (TextUtils.isEmpty(path)) {
Log.e(TAG, "The system property for the manual is empty");
showErrorAndFinish();
return;
}
final File file = new File(path);
final File file = new File(MANUAL_PATH);
if (!file.exists() || file.length() == 0) {
Log.e(TAG, "Manual file " + path + " does not exist");
Log.e(TAG, "Manual file " + MANUAL_PATH + " does not exist");
showErrorAndFinish();
return;
}

View File

@@ -21,7 +21,6 @@ import android.content.ContentResolver;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
@@ -44,8 +43,7 @@ public class SettingsLicenseActivity extends FragmentActivity implements
LoaderManager.LoaderCallbacks<File> {
private static final String TAG = "SettingsLicenseActivity";
private static final String DEFAULT_LICENSE_PATH = "/system/etc/NOTICE.html.gz";
private static final String PROPERTY_LICENSE_PATH = "ro.config.license_path";
private static final String LICENSE_PATH = "/system/etc/NOTICE.html.gz";
private static final int LOADER_ID_LICENSE_HTML_LOADER = 0;
@@ -53,10 +51,9 @@ public class SettingsLicenseActivity extends FragmentActivity implements
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final String licenseHtmlPath =
SystemProperties.get(PROPERTY_LICENSE_PATH, DEFAULT_LICENSE_PATH);
if (isFilePathValid(licenseHtmlPath)) {
showSelectedFile(licenseHtmlPath);
File file = new File(LICENSE_PATH);
if (isFileValid(file)) {
showHtmlFromUri(Uri.fromFile(file));
} else {
showHtmlFromDefaultXmlFiles();
}
@@ -95,22 +92,6 @@ public class SettingsLicenseActivity extends FragmentActivity implements
}
}
private void showSelectedFile(final String path) {
if (TextUtils.isEmpty(path)) {
Log.e(TAG, "The system property for the license file is empty");
showErrorAndFinish();
return;
}
final File file = new File(path);
if (!isFileValid(file)) {
Log.e(TAG, "License file " + path + " does not exist");
showErrorAndFinish();
return;
}
showHtmlFromUri(Uri.fromFile(file));
}
private void showHtmlFromUri(Uri uri) {
// Kick off external viewer due to WebView security restrictions; we
// carefully point it at HTMLViewer, since it offers to decompress
@@ -139,10 +120,6 @@ public class SettingsLicenseActivity extends FragmentActivity implements
finish();
}
private boolean isFilePathValid(final String path) {
return !TextUtils.isEmpty(path) && isFileValid(new File(path));
}
@VisibleForTesting
boolean isFileValid(final File file) {
return file.exists() && file.length() != 0;

View File

@@ -17,7 +17,7 @@
package com.android.settings;
import android.content.Intent;
import android.os.SystemProperties;
import android.sysprop.SetupWizardProperties;
import androidx.annotation.VisibleForTesting;
@@ -27,13 +27,10 @@ import com.google.android.setupdesign.util.ThemeHelper;
public class SetupWizardUtils {
@VisibleForTesting
static final String SYSTEM_PROP_SETUPWIZARD_THEME = "setupwizard.theme";
public static int getTheme(Intent intent) {
String theme = intent.getStringExtra(WizardManagerHelper.EXTRA_THEME);
if (theme == null) {
theme = SystemProperties.get(SYSTEM_PROP_SETUPWIZARD_THEME);
theme = SetupWizardProperties.theme().orElse("");
}
if (theme != null) {
switch (theme) {

View File

@@ -24,7 +24,6 @@ import android.os.Bundle;
import android.os.UserHandle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.android.settings.R;
@@ -33,15 +32,18 @@ import com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling;
import com.android.settings.core.InstrumentedActivity;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.google.android.setupcompat.item.FooterButton;
import com.google.android.setupcompat.template.ButtonFooterMixin;
import com.google.android.setupdesign.GlifLayout;
/**
* Base activity for all biometric enrollment steps.
*/
public abstract class BiometricEnrollBase extends InstrumentedActivity
implements View.OnClickListener {
public static final String EXTRA_KEY_LAUNCHED_CONFIRM = "launched_confirm_lock";
public abstract class BiometricEnrollBase extends InstrumentedActivity {
public static final String EXTRA_KEY_LAUNCHED_CONFIRM = "launched_confirm_lock";
public static final String EXTRA_KEY_REQUIRE_VISION = "accessibility_vision";
public static final String EXTRA_KEY_REQUIRE_DIVERSITY = "accessibility_diversity";
/**
* Used by the choose fingerprint wizard to indicate the wizard is
@@ -76,6 +78,7 @@ public abstract class BiometricEnrollBase extends InstrumentedActivity
protected boolean mLaunchedConfirmLock;
protected byte[] mToken;
protected int mUserId;
protected ButtonFooterMixin mButtonFooterMixin;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -110,10 +113,6 @@ public abstract class BiometricEnrollBase extends InstrumentedActivity
protected void initViews() {
getWindow().setStatusBarColor(Color.TRANSPARENT);
Button nextButton = getNextButton();
if (nextButton != null) {
nextButton.setOnClickListener(this);
}
}
protected GlifLayout getLayout() {
@@ -137,18 +136,14 @@ public abstract class BiometricEnrollBase extends InstrumentedActivity
setHeaderText(resId, false /* force */);
}
protected Button getNextButton() {
return (Button) findViewById(R.id.next_button);
}
@Override
public void onClick(View v) {
if (v == getNextButton()) {
onNextButtonClick();
protected FooterButton getNextButton() {
if (mButtonFooterMixin != null) {
return mButtonFooterMixin.getPrimaryButton();
}
return null;
}
protected void onNextButtonClick() {
protected void onNextButtonClick(View view) {
}
protected Intent getFingerprintEnrollingIntent() {

View File

@@ -22,13 +22,13 @@ import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.android.settings.R;
import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.google.android.setupcompat.item.FooterButton;
import com.google.android.setupdesign.span.LinkSpan;
/**
@@ -70,12 +70,12 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
/**
* @return the cancel button
*/
protected abstract Button getCancelButton();
protected abstract FooterButton getCancelButton();
/**
* @return the next button
*/
protected abstract Button getNextButton();
protected abstract FooterButton getNextButton();
/**
* @return the error TextView
@@ -127,9 +127,6 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
setHeaderText(getHeaderResDefault());
}
Button cancelButton = getCancelButton();
cancelButton.setOnClickListener(v -> onCancelButtonClick());
mErrorText = getErrorTextView();
mUserManager = UserManager.get(this);
@@ -164,7 +161,7 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
}
@Override
protected void onNextButtonClick() {
protected void onNextButtonClick(View view) {
// Lock thingy is already set up, launch directly to the next page
launchNextEnrollingActivity(mToken);
}
@@ -234,7 +231,7 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
super.onActivityResult(requestCode, resultCode, data);
}
protected void onCancelButtonClick() {
protected void onCancelButtonClick(View view) {
finish();
}

View File

@@ -85,16 +85,9 @@ public abstract class BiometricsEnrollEnrolling extends BiometricEnrollBase
super.onBackPressed();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.skip_button:
setResult(RESULT_SKIP);
finish();
break;
default:
super.onClick(v);
}
protected void onSkipButtonClick(View view) {
setResult(RESULT_SKIP);
finish();
}
public void startEnrollment() {

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.settings.biometrics.face;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;
import com.android.settings.R;
/**
* A layout that contains a start-justified title, and an end-justified switch.
*/
public class FaceEnrollAccessibilityToggle extends LinearLayout {
private Switch mSwitch;
public FaceEnrollAccessibilityToggle(Context context) {
this(context, null /* attrs */);
}
public FaceEnrollAccessibilityToggle(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FaceEnrollAccessibilityToggle(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
LayoutInflater.from(context).inflate(R.layout.face_enroll_accessibility_toggle,
this, true /* attachToRoot */);
final TypedArray a =
context.obtainStyledAttributes(attrs, R.styleable.FaceEnrollAccessibilityToggle);
try {
final CharSequence title =
a.getText(R.styleable.FaceEnrollAccessibilityToggle_messageText);
final TextView titleTextView = findViewById(R.id.title);
titleTextView.setText(title);
} finally {
a.recycle();
}
mSwitch = findViewById(R.id.toggle);
}
public boolean isChecked() {
return mSwitch.isChecked();
}
}

View File

@@ -29,7 +29,6 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import com.android.settings.biometrics.BiometricEnrollSidecar;
import com.android.settings.overlay.FeatureFactory;
/**
* A drawable containing the circle cutout as well as the animations.
@@ -42,17 +41,17 @@ public class FaceEnrollAnimationDrawable extends Drawable
private static final int BORDER_BOUNDS = 20;
private final Context mContext;
private final FaceFeatureProvider.Listener mListener;
private final ParticleCollection.Listener mListener;
private Rect mBounds;
private final Paint mSquarePaint;
private final Paint mCircleCutoutPaint;
private FaceFeatureProvider.EnrollingAnimation mEnrollingAnimation;
private ParticleCollection mParticleCollection;
private TimeAnimator mTimeAnimator;
private final FaceFeatureProvider.Listener mAnimationListener
= new FaceFeatureProvider.Listener() {
private final ParticleCollection.Listener mAnimationListener
= new ParticleCollection.Listener() {
@Override
public void onEnrolled() {
if (mTimeAnimator != null && mTimeAnimator.isStarted()) {
@@ -62,7 +61,7 @@ public class FaceEnrollAnimationDrawable extends Drawable
}
};
public FaceEnrollAnimationDrawable(Context context, FaceFeatureProvider.Listener listener) {
public FaceEnrollAnimationDrawable(Context context, ParticleCollection.Listener listener) {
mContext = context;
mListener = listener;
@@ -78,29 +77,29 @@ public class FaceEnrollAnimationDrawable extends Drawable
@Override
public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) {
mEnrollingAnimation.onEnrollmentHelp(helpMsgId, helpString);
mParticleCollection.onEnrollmentHelp(helpMsgId, helpString);
}
@Override
public void onEnrollmentError(int errMsgId, CharSequence errString) {
mEnrollingAnimation.onEnrollmentError(errMsgId, errString);
mParticleCollection.onEnrollmentError(errMsgId, errString);
}
@Override
public void onEnrollmentProgressChange(int steps, int remaining) {
mEnrollingAnimation.onEnrollmentProgressChange(steps, remaining);
mParticleCollection.onEnrollmentProgressChange(steps, remaining);
}
@Override
protected void onBoundsChange(Rect bounds) {
mBounds = bounds;
mEnrollingAnimation = FeatureFactory.getFactory(mContext).getFaceFeatureProvider()
.getEnrollingAnimation(mContext, mAnimationListener, bounds, BORDER_BOUNDS);
mParticleCollection =
new ParticleCollection(mContext, mAnimationListener, bounds, BORDER_BOUNDS);
if (mTimeAnimator == null) {
mTimeAnimator = new TimeAnimator();
mTimeAnimator.setTimeListener((animation, totalTimeMs, deltaTimeMs) -> {
mEnrollingAnimation.update(totalTimeMs, deltaTimeMs);
mParticleCollection.update(totalTimeMs, deltaTimeMs);
FaceEnrollAnimationDrawable.this.invalidateSelf();
});
mTimeAnimator.start();
@@ -122,7 +121,7 @@ public class FaceEnrollAnimationDrawable extends Drawable
mBounds.height() / 2 - BORDER_BOUNDS, mCircleCutoutPaint);
// Draw the animation
mEnrollingAnimation.draw(canvas);
mParticleCollection.draw(canvas);
canvas.restore();
}

View File

@@ -24,17 +24,19 @@ import android.util.Log;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.Button;
import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.biometrics.BiometricEnrollSidecar;
import com.android.settings.biometrics.BiometricErrorDialog;
import com.android.settings.biometrics.BiometricsEnrollEnrolling;
import com.android.settings.password.ChooseLockSettingsHelper;
import java.util.ArrayList;
import com.google.android.setupcompat.item.FooterButton;
import com.google.android.setupcompat.template.ButtonFooterMixin;
public class FaceEnrollEnrolling extends BiometricsEnrollEnrolling {
@@ -46,7 +48,8 @@ public class FaceEnrollEnrolling extends BiometricsEnrollEnrolling {
private Interpolator mLinearOutSlowInInterpolator;
private FaceEnrollPreviewFragment mPreviewFragment;
private FaceFeatureProvider.Listener mListener = new FaceFeatureProvider.Listener() {
private ArrayList<Integer> mDisabledFeatures = new ArrayList<>();
private ParticleCollection.Listener mListener = new ParticleCollection.Listener() {
@Override
public void onEnrolled() {
FaceEnrollEnrolling.this.launchFinish(mToken);
@@ -88,8 +91,22 @@ public class FaceEnrollEnrolling extends BiometricsEnrollEnrolling {
mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(
this, android.R.interpolator.linear_out_slow_in);
Button skipButton = findViewById(R.id.skip_button);
skipButton.setOnClickListener(this);
mButtonFooterMixin = getLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setSecondaryButton(
new FooterButton(
this,
R.string.security_settings_face_enroll_enrolling_skip,
this::onSkipButtonClick,
FooterButton.ButtonType.SKIP,
R.style.SuwGlifButton_Secondary)
);
if (!getIntent().getBooleanExtra(BiometricEnrollBase.EXTRA_KEY_REQUIRE_DIVERSITY, true)) {
mDisabledFeatures.add(FaceManager.FEATURE_REQUIRE_REQUIRE_DIVERSITY);
}
if (!getIntent().getBooleanExtra(BiometricEnrollBase.EXTRA_KEY_REQUIRE_VISION, true)) {
mDisabledFeatures.add(FaceManager.FEATURE_REQUIRE_ATTENTION);
}
startEnrollment();
}
@@ -114,7 +131,12 @@ public class FaceEnrollEnrolling extends BiometricsEnrollEnrolling {
@Override
protected BiometricEnrollSidecar getSidecar() {
return new FaceEnrollSidecar();
final int[] disabledFeatures = new int[mDisabledFeatures.size()];
for (int i = 0; i < mDisabledFeatures.size(); i++) {
disabledFeatures[i] = mDisabledFeatures.get(i);
}
return new FaceEnrollSidecar(disabledFeatures);
}
@Override

View File

@@ -17,11 +17,15 @@
package com.android.settings.biometrics.face;
import android.os.Bundle;
import android.view.View;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.biometrics.BiometricEnrollBase;
import com.google.android.setupcompat.item.FooterButton;
import com.google.android.setupcompat.template.ButtonFooterMixin;
/**
* Activity which concludes face enrollment.
*/
@@ -32,6 +36,16 @@ public class FaceEnrollFinish extends BiometricEnrollBase {
super.onCreate(savedInstanceState);
setContentView(R.layout.face_enroll_finish);
setHeaderText(R.string.security_settings_face_enroll_finish_title);
mButtonFooterMixin = getLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setPrimaryButton(
new FooterButton(
this,
R.string.security_settings_face_enroll_done,
this::onNextButtonClick,
FooterButton.ButtonType.NEXT,
R.style.SuwGlifButton_Primary)
);
}
@Override
@@ -40,7 +54,7 @@ public class FaceEnrollFinish extends BiometricEnrollBase {
}
@Override
public void onNextButtonClick() {
public void onNextButtonClick(View view) {
setResult(RESULT_FINISHED);
finish();
}

View File

@@ -17,10 +17,14 @@
package com.android.settings.biometrics.face;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Intent;
import android.hardware.face.FaceManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto;
@@ -30,6 +34,8 @@ import com.android.settings.biometrics.BiometricEnrollIntroduction;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.google.android.setupcompat.item.FooterButton;
import com.google.android.setupcompat.template.ButtonFooterMixin;
import com.google.android.setupdesign.span.LinkSpan;
public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
@@ -37,11 +43,41 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
private static final String TAG = "FaceIntro";
private FaceManager mFaceManager;
private FaceEnrollAccessibilityToggle mSwitchVision;
private FaceEnrollAccessibilityToggle mSwitchDiversity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFaceManager = Utils.getFaceManagerOrNull(this);
final LinearLayout accessibilityLayout = findViewById(R.id.accessibility_layout);
final Button accessibilityButton = findViewById(R.id.accessibility_button);
accessibilityButton.setOnClickListener(view -> {
accessibilityButton.setVisibility(View.INVISIBLE);
accessibilityLayout.setVisibility(View.VISIBLE);
});
mSwitchVision = findViewById(R.id.toggle_vision);
mSwitchDiversity = findViewById(R.id.toggle_diversity);
mButtonFooterMixin = getLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setSecondaryButton(
new FooterButton(
this,
R.string.security_settings_face_enroll_introduction_cancel,
this::onCancelButtonClick,
FooterButton.ButtonType.SKIP,
R.style.SuwGlifButton_Secondary)
);
mButtonFooterMixin.setPrimaryButton(
new FooterButton(
this,
R.string.wizard_next,
this::onNextButtonClick,
FooterButton.ButtonType.NEXT,
R.style.SuwGlifButton_Primary)
);
}
@Override
@@ -71,13 +107,19 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
}
@Override
protected Button getCancelButton() {
return findViewById(R.id.face_cancel_button);
protected FooterButton getCancelButton() {
if (mButtonFooterMixin != null) {
return mButtonFooterMixin.getSecondaryButton();
}
return null;
}
@Override
protected Button getNextButton() {
return findViewById(R.id.face_next_button);
protected FooterButton getNextButton() {
if (mButtonFooterMixin != null) {
return mButtonFooterMixin.getPrimaryButton();
}
return null;
}
@Override
@@ -116,7 +158,18 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
@Override
protected Intent getEnrollingIntent() {
return new Intent(this, FaceEnrollEnrolling.class);
final String flattenedString = getString(R.string.config_face_enroll);
final Intent intent = new Intent();
if (!TextUtils.isEmpty(flattenedString)) {
ComponentName componentName = ComponentName.unflattenFromString(flattenedString);
intent.setComponent(componentName);
} else {
intent.setClass(this, FaceEnrollEnrolling.class);
}
intent.putExtra(EXTRA_KEY_REQUIRE_VISION, mSwitchVision.isChecked());
intent.putExtra(EXTRA_KEY_REQUIRE_DIVERSITY, mSwitchDiversity.isChecked());
return intent;
}
@Override

View File

@@ -63,7 +63,7 @@ public class FaceEnrollPreviewFragment extends InstrumentedPreferenceFragment
private CameraCaptureSession mCaptureSession;
private CaptureRequest mPreviewRequest;
private Size mPreviewSize;
private FaceFeatureProvider.Listener mListener;
private ParticleCollection.Listener mListener;
// View used to contain the circular cutout and enrollment animation drawable
private ImageView mCircleView;
@@ -75,8 +75,8 @@ public class FaceEnrollPreviewFragment extends InstrumentedPreferenceFragment
private FaceSquareTextureView mTextureView;
// Listener sent to the animation drawable
private final FaceFeatureProvider.Listener mAnimationListener
= new FaceFeatureProvider.Listener() {
private final ParticleCollection.Listener mAnimationListener
= new ParticleCollection.Listener() {
@Override
public void onEnrolled() {
mListener.onEnrolled();
@@ -234,7 +234,7 @@ public class FaceEnrollPreviewFragment extends InstrumentedPreferenceFragment
mAnimationDrawable.onEnrollmentProgressChange(steps, remaining);
}
public void setListener(FaceFeatureProvider.Listener listener) {
public void setListener(ParticleCollection.Listener listener) {
mListener = listener;
}

View File

@@ -24,13 +24,22 @@ import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollSidecar;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Sidecar fragment to handle the state around face enrollment
*/
public class FaceEnrollSidecar extends BiometricEnrollSidecar {
private final int[] mDisabledFeatures;
private FaceManager mFaceManager;
public FaceEnrollSidecar(int[] disabledFeatures) {
mDisabledFeatures = Arrays.copyOf(disabledFeatures, disabledFeatures.length);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
@@ -43,9 +52,9 @@ public class FaceEnrollSidecar extends BiometricEnrollSidecar {
if (mUserId != UserHandle.USER_NULL) {
mFaceManager.setActiveUser(mUserId);
}
// TODO: Send the list of disabled features
mFaceManager.enroll(mToken, mEnrollmentCancel,
mEnrollmentCallback, new int[0] /* disabledFeatures */);
mEnrollmentCallback, mDisabledFeatures);
}
private FaceManager.EnrollmentCallback mEnrollmentCallback

View File

@@ -1,42 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.settings.biometrics.face;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
/**
* Feature provider for face authentication.
*/
public interface FaceFeatureProvider {
interface EnrollingAnimation {
void onEnrollmentHelp(int helpMsgId, CharSequence helpString);
void onEnrollmentError(int errMsgId, CharSequence errString);
void onEnrollmentProgressChange(int steps, int remaining);
void draw(Canvas canvas);
void update(long t, long dt);
}
interface Listener {
void onEnrolled();
}
EnrollingAnimation getEnrollingAnimation(Context context, Listener listener, Rect bounds,
int borderWidth);
}

View File

@@ -1,28 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.settings.biometrics.face;
import android.content.Context;
import android.graphics.Rect;
public class FaceFeatureProviderImpl implements FaceFeatureProvider {
@Override
public EnrollingAnimation getEnrollingAnimation(Context context, Listener listener, Rect bounds,
int borderWidth) {
return new ParticleCollection(context, listener, bounds, borderWidth);
}
}

View File

@@ -35,7 +35,7 @@ import java.util.List;
* are updated/drawn in a special order so that the overlap is correct during the final completion
* effect.
*/
public class ParticleCollection implements FaceFeatureProviderImpl.EnrollingAnimation {
public class ParticleCollection implements BiometricEnrollSidecar.Listener {
private static final String TAG = "AnimationController";
@@ -49,7 +49,11 @@ public class ParticleCollection implements FaceFeatureProviderImpl.EnrollingAnim
private final List<AnimationParticle> mParticleList;
private final List<Integer> mPrimariesInProgress; // primary particles not done animating yet
private int mState;
private FaceFeatureProvider.Listener mListener;
private Listener mListener;
public interface Listener {
void onEnrolled();
}
private final AnimationParticle.Listener mParticleListener = new AnimationParticle.Listener() {
@Override
@@ -68,8 +72,7 @@ public class ParticleCollection implements FaceFeatureProviderImpl.EnrollingAnim
}
};
public ParticleCollection(Context context, FaceFeatureProvider.Listener listener, Rect bounds,
int borderWidth) {
public ParticleCollection(Context context, Listener listener, Rect bounds, int borderWidth) {
mParticleList = new ArrayList<>();
mListener = listener;
@@ -100,14 +103,12 @@ public class ParticleCollection implements FaceFeatureProviderImpl.EnrollingAnim
updateState(STATE_STARTED);
}
@Override
public void update(long t, long dt) {
for (int i = 0; i < mParticleList.size(); i++) {
mParticleList.get(i).update(t, dt);
}
}
@Override
public void draw(Canvas canvas) {
for (int i = 0; i < mParticleList.size(); i++) {
mParticleList.get(i).draw(canvas);

View File

@@ -35,7 +35,6 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
@@ -48,6 +47,9 @@ import com.android.settings.biometrics.BiometricErrorDialog;
import com.android.settings.biometrics.BiometricsEnrollEnrolling;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.google.android.setupcompat.item.FooterButton;
import com.google.android.setupcompat.template.ButtonFooterMixin;
/**
* Activity which handles the actual enrolling for fingerprint.
*/
@@ -135,8 +137,15 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
mProgressBar = (ProgressBar) findViewById(R.id.fingerprint_progress_bar);
mVibrator = getSystemService(Vibrator.class);
Button skipButton = findViewById(R.id.skip_button);
skipButton.setOnClickListener(this);
mButtonFooterMixin = getLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setSecondaryButton(
new FooterButton(
this,
R.string.security_settings_fingerprint_enroll_enrolling_skip,
this::onSkipButtonClick,
FooterButton.ButtonType.SKIP,
R.style.SuwGlifButton_Secondary)
);
final LayerDrawable fingerprintDrawable = (LayerDrawable) mProgressBar.getBackground();
mIconAnimationDrawable = (AnimatedVectorDrawable)

View File

@@ -20,7 +20,6 @@ import android.content.Intent;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.annotation.Nullable;
@@ -30,6 +29,8 @@ import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.biometrics.BiometricEnrollSidecar.Listener;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.google.android.setupcompat.item.FooterButton;
import com.google.android.setupcompat.template.ButtonFooterMixin;
/**
* Activity explaining the fingerprint sensor location for fingerprint enrollment.
@@ -46,8 +47,15 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getContentView());
Button skipButton = findViewById(R.id.skip_button);
skipButton.setOnClickListener(this);
mButtonFooterMixin = getLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setSecondaryButton(
new FooterButton(
this,
R.string.skip_label,
this::onSkipButtonClick,
FooterButton.ButtonType.SKIP,
R.style.SuwGlifButton_Secondary)
);
setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title);
@@ -120,18 +128,7 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase {
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.skip_button:
onSkipButtonClick();
break;
default:
super.onClick(v);
}
}
protected void onSkipButtonClick() {
protected void onSkipButtonClick(View view) {
setResult(RESULT_SKIP);
finish();
}

View File

@@ -20,13 +20,15 @@ import android.content.Intent;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollBase;
import com.google.android.setupcompat.item.FooterButton;
import com.google.android.setupcompat.template.ButtonFooterMixin;
/**
* Activity which concludes fingerprint enrollment.
*/
@@ -39,13 +41,32 @@ public class FingerprintEnrollFinish extends BiometricEnrollBase {
super.onCreate(savedInstanceState);
setContentView(R.layout.fingerprint_enroll_finish);
setHeaderText(R.string.security_settings_fingerprint_enroll_finish_title);
mButtonFooterMixin = getLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setSecondaryButton(
new FooterButton(
this,
R.string.fingerprint_enroll_button_add,
null,
FooterButton.ButtonType.SKIP,
R.style.SuwGlifButton_Secondary)
);
mButtonFooterMixin.setPrimaryButton(
new FooterButton(
this,
R.string.security_settings_fingerprint_enroll_done,
this::onNextButtonClick,
FooterButton.ButtonType.NEXT,
R.style.SuwGlifButton_Primary)
);
}
@Override
protected void onResume() {
super.onResume();
Button addButton = (Button) findViewById(R.id.add_another_button);
FooterButton addButton = mButtonFooterMixin.getSecondaryButton();
final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(this);
boolean hideAddAnother = false;
@@ -59,22 +80,18 @@ public class FingerprintEnrollFinish extends BiometricEnrollBase {
// Don't show "Add" button if too many fingerprints already added
addButton.setVisibility(View.INVISIBLE);
} else {
addButton.setOnClickListener(this);
addButton.setOnClickListener(this::onAddAnotherButtonClick);
}
}
@Override
protected void onNextButtonClick() {
protected void onNextButtonClick(View view) {
setResult(RESULT_FINISHED);
finish();
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.add_another_button) {
startActivityForResult(getFingerprintEnrollingIntent(), REQUEST_ADD_ANOTHER);
}
super.onClick(v);
private void onAddAnotherButtonClick(View view) {
startActivityForResult(getFingerprintEnrollingIntent(), REQUEST_ADD_ANOTHER);
}
@Override

View File

@@ -22,7 +22,6 @@ import android.content.Intent;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto;
@@ -33,6 +32,8 @@ import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settingslib.HelpUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.google.android.setupcompat.item.FooterButton;
import com.google.android.setupcompat.template.ButtonFooterMixin;
import com.google.android.setupdesign.span.LinkSpan;
public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction {
@@ -45,6 +46,25 @@ public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFingerprintManager = Utils.getFingerprintManagerOrNull(this);
mButtonFooterMixin = getLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setSecondaryButton(
new FooterButton(
this,
R.string.security_settings_face_enroll_introduction_cancel,
this::onCancelButtonClick,
FooterButton.ButtonType.SKIP,
R.style.SuwGlifButton_Secondary)
);
mButtonFooterMixin.setPrimaryButton(
new FooterButton(
this,
R.string.wizard_next,
this::onNextButtonClick,
FooterButton.ButtonType.NEXT,
R.style.SuwGlifButton_Primary)
);
}
@Override
@@ -74,13 +94,19 @@ public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction {
}
@Override
protected Button getCancelButton() {
return findViewById(R.id.fingerprint_cancel_button);
protected FooterButton getCancelButton() {
if (mButtonFooterMixin != null) {
return mButtonFooterMixin.getSecondaryButton();
}
return null;
}
@Override
protected Button getNextButton() {
return findViewById(R.id.fingerprint_next_button);
protected FooterButton getNextButton() {
if (mButtonFooterMixin != null) {
return mButtonFooterMixin.getPrimaryButton();
}
return null;
}
@Override

View File

@@ -19,19 +19,21 @@ package com.android.settings.biometrics.fingerprint;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.hardware.fingerprint.FingerprintManager;
import android.widget.Button;
import com.android.settings.R;
import com.android.settings.Utils;
import com.google.android.setupcompat.item.FooterButton;
public class FingerprintSuggestionActivity extends SetupFingerprintEnrollIntroduction {
@Override
protected void initViews() {
super.initViews();
final Button cancelButton = findViewById(R.id.fingerprint_cancel_button);
cancelButton.setText(R.string.security_settings_fingerprint_enroll_introduction_cancel);
final FooterButton cancelButton = getCancelButton();
cancelButton.setText(
this, R.string.security_settings_fingerprint_enroll_introduction_cancel);
}
@Override

View File

@@ -22,6 +22,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
@@ -53,7 +54,7 @@ public class SetupFingerprintEnrollFindSensor extends FingerprintEnrollFindSenso
}
@Override
protected void onSkipButtonClick() {
protected void onSkipButtonClick(View view) {
new SkipFingerprintDialog().show(getSupportFragmentManager());
}

View File

@@ -25,6 +25,8 @@ import com.android.settings.R;
import com.android.settings.SetupWizardUtils;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.google.android.setupcompat.item.FooterButton;
public class SetupFingerprintEnrollFinish extends FingerprintEnrollFinish {
@Override
@@ -41,8 +43,8 @@ public class SetupFingerprintEnrollFinish extends FingerprintEnrollFinish {
@Override
protected void initViews() {
super.initViews();
Button nextButton = findViewById(R.id.next_button);
nextButton.setText(R.string.next_label);
FooterButton nextButton = getNextButton();
nextButton.setText(this, R.string.next_label);
}
@Override

View File

@@ -23,7 +23,7 @@ import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.widget.Button;
import android.view.View;
import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -34,6 +34,8 @@ import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment
import com.android.settings.password.SetupChooseLockGeneric;
import com.android.settings.password.SetupSkipDialog;
import com.google.android.setupcompat.item.FooterButton;
public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntroduction {
private static final String KEY_LOCK_SCREEN_PRESENT = "wasLockScreenPresent";
private boolean mAlreadyHadLockScreenSetup = false;
@@ -84,13 +86,13 @@ public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntrodu
description.setText(
R.string.security_settings_fingerprint_enroll_introduction_message_setup);
Button nextButton = getNextButton();
FooterButton nextButton = getNextButton();
nextButton.setText(
R.string.security_settings_fingerprint_enroll_introduction_continue_setup);
this, R.string.security_settings_fingerprint_enroll_introduction_continue_setup);
final Button cancelButton = (Button) findViewById(R.id.fingerprint_cancel_button);
final FooterButton cancelButton = getCancelButton();
cancelButton.setText(
R.string.security_settings_fingerprint_enroll_introduction_cancel_setup);
this, R.string.security_settings_fingerprint_enroll_introduction_cancel_setup);
}
@Override
@@ -116,7 +118,7 @@ public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntrodu
}
@Override
protected void onCancelButtonClick() {
protected void onCancelButtonClick(View view) {
if (isKeyguardSecure()) {
// If the keyguard is already set up securely (maybe the user added a backup screen
// lock and skipped fingerprint), return RESULT_SKIP directly.

View File

@@ -15,9 +15,12 @@
*/
package com.android.settings.connecteddevice.usb;
import static android.hardware.usb.UsbPortStatus.DATA_ROLE_DEVICE;
import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SINK;
import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SOURCE;
import android.content.Context;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbPort;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
@@ -43,7 +46,7 @@ public class ConnectedUsbDeviceUpdater {
UsbConnectionBroadcastReceiver.UsbConnectionListener mUsbConnectionListener =
(connected, functions, powerRole, dataRole) -> {
if (connected) {
mUsbPreference.setSummary(getSummary(dataRole == UsbPort.DATA_ROLE_DEVICE
mUsbPreference.setSummary(getSummary(dataRole == DATA_ROLE_DEVICE
? functions : UsbManager.FUNCTION_NONE, powerRole));
mDevicePreferenceCallback.onDeviceAdded(mUsbPreference);
} else {
@@ -100,7 +103,7 @@ public class ConnectedUsbDeviceUpdater {
public static int getSummary(long functions, int power) {
switch (power) {
case UsbPort.POWER_ROLE_SINK:
case POWER_ROLE_SINK:
if (functions == UsbManager.FUNCTION_MTP) {
return R.string.usb_summary_file_transfers;
} else if (functions == UsbManager.FUNCTION_RNDIS) {
@@ -112,7 +115,7 @@ public class ConnectedUsbDeviceUpdater {
} else {
return R.string.usb_summary_charging_only;
}
case UsbPort.POWER_ROLE_SOURCE:
case POWER_ROLE_SOURCE:
if (functions == UsbManager.FUNCTION_MTP) {
return R.string.usb_summary_file_transfers_power;
} else if (functions == UsbManager.FUNCTION_RNDIS) {

View File

@@ -15,6 +15,13 @@
*/
package com.android.settings.connecteddevice.usb;
import static android.hardware.usb.UsbPortStatus.DATA_ROLE_DEVICE;
import static android.hardware.usb.UsbPortStatus.POWER_ROLE_NONE;
import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SOURCE;
import static android.service.usb.UsbPortStatusProto.DATA_ROLE_HOST;
import static android.service.usb.UsbPortStatusProto.DATA_ROLE_NONE;
import static android.service.usb.UsbPortStatusProto.POWER_ROLE_SINK;
import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -27,6 +34,8 @@ import android.os.UserManager;
import androidx.annotation.VisibleForTesting;
import java.util.List;
/**
* Provides access to underlying system USB functionality.
*/
@@ -96,30 +105,30 @@ public class UsbBackend {
public int getPowerRole() {
updatePorts();
return mPortStatus == null ? UsbPort.POWER_ROLE_NONE : mPortStatus.getCurrentPowerRole();
return mPortStatus == null ? POWER_ROLE_NONE : mPortStatus.getCurrentPowerRole();
}
public int getDataRole() {
updatePorts();
return mPortStatus == null ? UsbPort.DATA_ROLE_NONE : mPortStatus.getCurrentDataRole();
return mPortStatus == null ? DATA_ROLE_NONE : mPortStatus.getCurrentDataRole();
}
public void setPowerRole(int role) {
int newDataRole = getDataRole();
if (!areAllRolesSupported()) {
switch (role) {
case UsbPort.POWER_ROLE_SINK:
newDataRole = UsbPort.DATA_ROLE_DEVICE;
case POWER_ROLE_SINK:
newDataRole = DATA_ROLE_DEVICE;
break;
case UsbPort.POWER_ROLE_SOURCE:
newDataRole = UsbPort.DATA_ROLE_HOST;
case POWER_ROLE_SOURCE:
newDataRole = DATA_ROLE_HOST;
break;
default:
newDataRole = UsbPort.DATA_ROLE_NONE;
newDataRole = DATA_ROLE_NONE;
}
}
if (mPort != null) {
mUsbManager.setPortRoles(mPort, role, newDataRole);
mPort.setRoles(role, newDataRole);
}
}
@@ -127,31 +136,27 @@ public class UsbBackend {
int newPowerRole = getPowerRole();
if (!areAllRolesSupported()) {
switch (role) {
case UsbPort.DATA_ROLE_DEVICE:
newPowerRole = UsbPort.POWER_ROLE_SINK;
case DATA_ROLE_DEVICE:
newPowerRole = POWER_ROLE_SINK;
break;
case UsbPort.DATA_ROLE_HOST:
newPowerRole = UsbPort.POWER_ROLE_SOURCE;
case DATA_ROLE_HOST:
newPowerRole = POWER_ROLE_SOURCE;
break;
default:
newPowerRole = UsbPort.POWER_ROLE_NONE;
newPowerRole = POWER_ROLE_NONE;
}
}
if (mPort != null) {
mUsbManager.setPortRoles(mPort, newPowerRole, role);
mPort.setRoles(newPowerRole, role);
}
}
public boolean areAllRolesSupported() {
return mPort != null && mPortStatus != null
&& mPortStatus
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE)
&& mPortStatus
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_HOST)
&& mPortStatus
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_DEVICE)
&& mPortStatus
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST);
&& mPortStatus.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_DEVICE)
&& mPortStatus.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_HOST)
&& mPortStatus.isRoleCombinationSupported(POWER_ROLE_SOURCE, DATA_ROLE_DEVICE)
&& mPortStatus.isRoleCombinationSupported(POWER_ROLE_SOURCE, DATA_ROLE_HOST);
}
public static String usbFunctionsToString(long functions) {
@@ -205,17 +210,14 @@ public class UsbBackend {
private void updatePorts() {
mPort = null;
mPortStatus = null;
UsbPort[] ports = mUsbManager.getPorts();
if (ports == null) {
return;
}
List<UsbPort> ports = mUsbManager.getPorts();
// For now look for a connected port, in the future we should identify port in the
// notification and pick based on that.
final int N = ports.length;
final int N = ports.size();
for (int i = 0; i < N; i++) {
UsbPortStatus status = mUsbManager.getPortStatus(ports[i]);
UsbPortStatus status = ports.get(i).getStatus();
if (status.isConnected()) {
mPort = ports[i];
mPort = ports.get(i);
mPortStatus = status;
break;
}

View File

@@ -49,8 +49,8 @@ public class UsbConnectionBroadcastReceiver extends BroadcastReceiver implements
mUsbBackend = backend;
mFunctions = UsbManager.FUNCTION_NONE;
mDataRole = UsbPort.DATA_ROLE_NONE;
mPowerRole = UsbPort.POWER_ROLE_NONE;
mDataRole = UsbPortStatus.DATA_ROLE_NONE;
mPowerRole = UsbPortStatus.POWER_ROLE_NONE;
}
@Override

View File

@@ -16,6 +16,10 @@
package com.android.settings.connecteddevice.usb;
import static android.hardware.usb.UsbPortStatus.DATA_ROLE_DEVICE;
import static android.hardware.usb.UsbPortStatus.DATA_ROLE_HOST;
import static android.hardware.usb.UsbPortStatus.DATA_ROLE_NONE;
import android.content.Context;
import android.hardware.usb.UsbPort;
@@ -55,23 +59,23 @@ public class UsbDetailsDataRoleController extends UsbDetailsController
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreferenceCategory = (PreferenceCategory) screen.findPreference(getPreferenceKey());
mHostPref = makeRadioPreference(UsbBackend.dataRoleToString(UsbPort.DATA_ROLE_HOST),
mHostPref = makeRadioPreference(UsbBackend.dataRoleToString(DATA_ROLE_HOST),
R.string.usb_control_host);
mDevicePref = makeRadioPreference(UsbBackend.dataRoleToString(UsbPort.DATA_ROLE_DEVICE),
mDevicePref = makeRadioPreference(UsbBackend.dataRoleToString(DATA_ROLE_DEVICE),
R.string.usb_control_device);
}
@Override
protected void refresh(boolean connected, long functions, int powerRole, int dataRole) {
if (dataRole == UsbPort.DATA_ROLE_DEVICE) {
if (dataRole == DATA_ROLE_DEVICE) {
mDevicePref.setChecked(true);
mHostPref.setChecked(false);
mPreferenceCategory.setEnabled(true);
} else if (dataRole == UsbPort.DATA_ROLE_HOST) {
} else if (dataRole == DATA_ROLE_HOST) {
mDevicePref.setChecked(false);
mHostPref.setChecked(true);
mPreferenceCategory.setEnabled(true);
} else if (!connected || dataRole == UsbPort.DATA_ROLE_NONE){
} else if (!connected || dataRole == DATA_ROLE_NONE){
mPreferenceCategory.setEnabled(false);
if (mNextRolePref == null) {
// Disconnected with no operation pending, so clear subtexts
@@ -80,7 +84,7 @@ public class UsbDetailsDataRoleController extends UsbDetailsController
}
}
if (mNextRolePref != null && dataRole != UsbPort.DATA_ROLE_NONE) {
if (mNextRolePref != null && dataRole != DATA_ROLE_NONE) {
if (UsbBackend.dataRoleFromString(mNextRolePref.getKey()) == dataRole) {
// Clear switching text if switch succeeded
mNextRolePref.setSummary("");

View File

@@ -16,6 +16,7 @@
package com.android.settings.connecteddevice.usb;
import static android.hardware.usb.UsbPortStatus.DATA_ROLE_DEVICE;
import static android.net.ConnectivityManager.TETHERING_USB;
import android.content.Context;
@@ -88,7 +89,7 @@ public class UsbDetailsFunctionsController extends UsbDetailsController
@Override
protected void refresh(boolean connected, long functions, int powerRole, int dataRole) {
if (!connected || dataRole != UsbPort.DATA_ROLE_DEVICE) {
if (!connected || dataRole != DATA_ROLE_DEVICE) {
mProfilesContainer.setEnabled(false);
} else {
// Functions are only available in device mode

View File

@@ -16,8 +16,13 @@
package com.android.settings.connecteddevice.usb;
import static android.hardware.usb.UsbPortStatus.POWER_ROLE_NONE;
import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SINK;
import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SOURCE;
import android.content.Context;
import android.hardware.usb.UsbPort;
import android.hardware.usb.UsbPortStatus;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceClickListener;
@@ -40,16 +45,16 @@ public class UsbDetailsPowerRoleController extends UsbDetailsController
private int mNextPowerRole;
private final Runnable mFailureCallback = () -> {
if (mNextPowerRole != UsbPort.POWER_ROLE_NONE) {
if (mNextPowerRole != POWER_ROLE_NONE) {
mSwitchPreference.setSummary(R.string.usb_switching_failed);
mNextPowerRole = UsbPort.POWER_ROLE_NONE;
mNextPowerRole = POWER_ROLE_NONE;
}
};
public UsbDetailsPowerRoleController(Context context, UsbDetailsFragment fragment,
UsbBackend backend) {
super(context, fragment, backend);
mNextPowerRole = UsbPort.POWER_ROLE_NONE;
mNextPowerRole = POWER_ROLE_NONE;
}
@Override
@@ -70,20 +75,21 @@ public class UsbDetailsPowerRoleController extends UsbDetailsController
} else if (connected && mUsbBackend.areAllRolesSupported()){
mFragment.getPreferenceScreen().addPreference(mPreferenceCategory);
}
if (powerRole == UsbPort.POWER_ROLE_SOURCE) {
if (powerRole == POWER_ROLE_SOURCE) {
mSwitchPreference.setChecked(true);
mPreferenceCategory.setEnabled(true);
} else if (powerRole == UsbPort.POWER_ROLE_SINK) {
} else if (powerRole == POWER_ROLE_SINK) {
mSwitchPreference.setChecked(false);
mPreferenceCategory.setEnabled(true);
} else if (!connected || powerRole == UsbPort.POWER_ROLE_NONE){
} else if (!connected || powerRole == POWER_ROLE_NONE){
mPreferenceCategory.setEnabled(false);
if (mNextPowerRole == UsbPort.POWER_ROLE_NONE) {
if (mNextPowerRole == POWER_ROLE_NONE) {
mSwitchPreference.setSummary("");
}
}
if (mNextPowerRole != UsbPort.POWER_ROLE_NONE && powerRole != UsbPort.POWER_ROLE_NONE) {
if (mNextPowerRole != POWER_ROLE_NONE
&& powerRole != POWER_ROLE_NONE) {
if (mNextPowerRole == powerRole) {
// Clear switching text if switch succeeded
mSwitchPreference.setSummary("");
@@ -91,16 +97,16 @@ public class UsbDetailsPowerRoleController extends UsbDetailsController
// Set failure text if switch failed
mSwitchPreference.setSummary(R.string.usb_switching_failed);
}
mNextPowerRole = UsbPort.POWER_ROLE_NONE;
mNextPowerRole = POWER_ROLE_NONE;
mHandler.removeCallbacks(mFailureCallback);
}
}
@Override
public boolean onPreferenceClick(Preference preference) {
int newRole = mSwitchPreference.isChecked() ? UsbPort.POWER_ROLE_SOURCE
: UsbPort.POWER_ROLE_SINK;
if (mUsbBackend.getPowerRole() != newRole && mNextPowerRole == UsbPort.POWER_ROLE_NONE
int newRole = mSwitchPreference.isChecked() ? POWER_ROLE_SOURCE
: POWER_ROLE_SINK;
if (mUsbBackend.getPowerRole() != newRole && mNextPowerRole == POWER_ROLE_NONE
&& !Utils.isMonkeyRunning()) {
mUsbBackend.setPowerRole(newRole);

View File

@@ -22,6 +22,7 @@ import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.XmlRes;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.overlay.FeatureFactory;
@@ -78,6 +79,14 @@ public abstract class InstrumentedPreferenceFragment extends ObservablePreferenc
updateActivityTitleWithScreenTitle(getPreferenceScreen());
}
@Override
public <T extends Preference> T findPreference(CharSequence key) {
if (key == null) {
return null;
}
return super.findPreference(key);
}
protected final Context getPrefContext() {
return getPreferenceManager().getContext();
}

View File

@@ -16,7 +16,11 @@
package com.android.settings.deviceinfo;
import static android.content.Context.CLIPBOARD_SERVICE;
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -29,34 +33,30 @@ import android.text.TextUtils;
import android.widget.Toast;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.slices.Copyable;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.development.DevelopmentSettingsEnabler;
public class BuildNumberPreferenceController extends AbstractPreferenceController implements
PreferenceControllerMixin, LifecycleObserver, OnResume {
public class BuildNumberPreferenceController extends BasePreferenceController implements Copyable,
LifecycleObserver, OnStart {
static final int TAPS_TO_BE_A_DEVELOPER = 7;
static final int REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF = 100;
private static final String KEY_BUILD_NUMBER = "build_number";
private final Activity mActivity;
private final InstrumentedPreferenceFragment mFragment;
private Activity mActivity;
private InstrumentedPreferenceFragment mFragment;
private final UserManager mUm;
private final MetricsFeatureProvider mMetricsFeatureProvider;
@@ -66,44 +66,28 @@ public class BuildNumberPreferenceController extends AbstractPreferenceControlle
private int mDevHitCountdown;
private boolean mProcessingLastDevHit;
public BuildNumberPreferenceController(Context context, Activity activity,
InstrumentedPreferenceFragment fragment, Lifecycle lifecycle) {
super(context);
mActivity = activity;
mFragment = fragment;
public BuildNumberPreferenceController(Context context, String key) {
super(context, key);
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
if (lifecycle != null) {
lifecycle.addObserver(this);
}
public void setHost(InstrumentedPreferenceFragment fragment) {
mFragment = fragment;
mActivity = fragment.getActivity();
}
@Override
public CharSequence getSummary() {
try {
return BidiFormatter.getInstance().unicodeWrap(Build.DISPLAY);
} catch (Exception e) {
return mContext.getText(R.string.device_info_default);
}
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
final Preference preference = screen.findPreference(KEY_BUILD_NUMBER);
if (preference != null) {
try {
preference.setSummary(BidiFormatter.getInstance().unicodeWrap(Build.DISPLAY));
preference.setEnabled(true);
} catch (Exception e) {
preference.setSummary(R.string.device_info_default);
}
}
}
@Override
public String getPreferenceKey() {
return KEY_BUILD_NUMBER;
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public void onResume() {
public void onStart() {
mDebuggingFeaturesDisallowedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
mContext, UserManager.DISALLOW_DEBUGGING_FEATURES, UserHandle.myUserId());
mDebuggingFeaturesDisallowedBySystem = RestrictedLockUtilsInternal.hasBaseUserRestriction(
@@ -113,9 +97,31 @@ public class BuildNumberPreferenceController extends AbstractPreferenceControlle
mDevHitToast = null;
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public boolean isSliceable() {
return true;
}
@Override
public void copy() {
final ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(
CLIPBOARD_SERVICE);
final ClipData clip = ClipData.newPlainText("text", getSummary());
clipboard.setPrimaryClip(clip);
final String toast = mContext.getString(R.string.copyable_slice_toast,
mContext.getText(R.string.build_number));
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!TextUtils.equals(preference.getKey(), KEY_BUILD_NUMBER)) {
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
return false;
}
if (Utils.isMonkeyRunning()) {

View File

@@ -35,7 +35,6 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
@@ -45,6 +44,8 @@ import androidx.fragment.app.FragmentActivity;
import com.android.settings.R;
import com.android.settingslib.Utils;
import com.google.android.setupcompat.item.FooterButton;
import com.google.android.setupcompat.template.ButtonFooterMixin;
import com.google.android.setupdesign.GlifLayout;
import java.text.NumberFormat;
@@ -62,8 +63,9 @@ public abstract class StorageWizardBase extends FragmentActivity {
protected VolumeInfo mVolume;
protected DiskInfo mDisk;
private Button mBack;
private Button mNext;
private ButtonFooterMixin mButtonFooterMixin;
private FooterButton mBack;
private FooterButton mNext;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -92,8 +94,25 @@ public abstract class StorageWizardBase extends FragmentActivity {
public void setContentView(@LayoutRes int layoutResID) {
super.setContentView(layoutResID);
mBack = requireViewById(R.id.storage_back_button);
mNext = requireViewById(R.id.storage_next_button);
mButtonFooterMixin = getGlifLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setSecondaryButton(
new FooterButton(
this,
R.string.wizard_back,
this::onNavigateBack,
FooterButton.ButtonType.OTHER,
R.style.SuwGlifButton_Secondary)
);
mButtonFooterMixin.setPrimaryButton(
new FooterButton(
this,
R.string.wizard_next,
this::onNavigateNext,
FooterButton.ButtonType.NEXT,
R.style.SuwGlifButton_Primary)
);
mBack = mButtonFooterMixin.getSecondaryButton();
mNext = mButtonFooterMixin.getPrimaryButton();
setIcon(com.android.internal.R.drawable.ic_sd_card_48dp);
}
@@ -104,11 +123,11 @@ public abstract class StorageWizardBase extends FragmentActivity {
super.onDestroy();
}
protected Button getBackButton() {
protected FooterButton getBackButton() {
return mBack;
}
protected Button getNextButton() {
protected FooterButton getNextButton() {
return mNext;
}

View File

@@ -30,7 +30,6 @@ import com.android.settings.R;
import com.android.settings.overlay.FeatureFactory;
public class StorageWizardInit extends StorageWizardBase {
private Button mExternal;
private Button mInternal;
private boolean mIsPermittedToAdopt;
@@ -49,7 +48,6 @@ public class StorageWizardInit extends StorageWizardBase {
setHeaderText(R.string.storage_wizard_init_v2_title, getDiskShortDescription());
mExternal = requireViewById(R.id.storage_wizard_init_external);
mInternal = requireViewById(R.id.storage_wizard_init_internal);
setBackButtonText(R.string.storage_wizard_init_v2_later);

View File

@@ -64,6 +64,8 @@ public class MyDeviceInfoFragment extends DashboardFragment
private static final String LOG_TAG = "MyDeviceInfoFragment";
private static final String KEY_MY_DEVICE_INFO_HEADER = "my_device_info_header";
private BuildNumberPreferenceController mBuildNumberPreferenceController;
@Override
public int getMetricsCategory() {
return MetricsEvent.DEVICEINFO;
@@ -79,6 +81,8 @@ public class MyDeviceInfoFragment extends DashboardFragment
super.onAttach(context);
use(FirmwareVersionPreferenceController.class).setHost(this /*parent*/);
use(DeviceModelPreferenceController.class).setHost(this /* parent */);
mBuildNumberPreferenceController = use(BuildNumberPreferenceController.class);
mBuildNumberPreferenceController.setHost(this /* parent */);
}
@Override
@@ -126,17 +130,13 @@ public class MyDeviceInfoFragment extends DashboardFragment
controllers.add(new ManualPreferenceController(context));
controllers.add(new FeedbackPreferenceController(fragment, context));
controllers.add(new FccEquipmentIdPreferenceController(context));
controllers.add(
new BuildNumberPreferenceController(context, activity, fragment, lifecycle));
controllers.add(new UptimePreferenceController(context, lifecycle));
return controllers;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
final BuildNumberPreferenceController buildNumberPreferenceController =
use(BuildNumberPreferenceController.class);
if (buildNumberPreferenceController.onActivityResult(requestCode, resultCode, data)) {
if (mBuildNumberPreferenceController.onActivityResult(requestCode, resultCode, data)) {
return;
}
super.onActivityResult(requestCode, resultCode, data);

View File

@@ -449,12 +449,14 @@ public class BatteryUtils {
final BatteryStats stats = statsHelper.getStats();
BatteryInfo batteryInfo;
final Estimate estimate;
Estimate estimate = null;
// Get enhanced prediction if available
if (mPowerUsageFeatureProvider != null &&
mPowerUsageFeatureProvider.isEnhancedBatteryPredictionEnabled(mContext)) {
estimate = mPowerUsageFeatureProvider.getEnhancedBatteryPrediction(mContext);
} else {
}
if (estimate == null) {
estimate = new Estimate(
PowerUtil.convertUsToMs(stats.computeBatteryTimeRemaining(elapsedRealtimeUs)),
false /* isBasedOnUsage */,

View File

@@ -16,24 +16,21 @@
package com.android.settings.homepage.contextualcards;
import android.content.Context;
import java.util.List;
/** Feature provider for the contextual card feature. */
public interface ContextualCardFeatureProvider {
/** Homepage displays. */
void logHomepageDisplay(Context context, long latency);
void logHomepageDisplay(long latency);
/** When user clicks dismiss in contextual card */
void logContextualCardDismiss(Context context, ContextualCard card);
void logContextualCardDismiss(ContextualCard card);
/** After ContextualCardManager decides which cards will be displayed/hidden */
void logContextualCardDisplay(Context context, List<ContextualCard> showedCards,
void logContextualCardDisplay(List<ContextualCard> showedCards,
List<ContextualCard> hiddenCards);
/** When user clicks toggle/title area of a contextual card. */
void logContextualCardClick(Context context, ContextualCard card, int row,
int tapTarget);
void logContextualCardClick(ContextualCard card, int row, int tapTarget);
}

View File

@@ -51,6 +51,9 @@ public class ContextualCardFeatureProviderImpl implements ContextualCardFeatureP
// contextual card name
private static final String EXTRA_CONTEXTUALCARD_NAME = "name";
// contextual card uri
private static final String EXTRA_CONTEXTUALCARD_URI = "uri";
// contextual card score
private static final String EXTRA_CONTEXTUALCARD_SCORE = "score";
@@ -84,51 +87,59 @@ public class ContextualCardFeatureProviderImpl implements ContextualCardFeatureP
// Click slider
private static final int TARGET_SLIDER = 3;
private final Context mContext;
public ContextualCardFeatureProviderImpl(Context context) {
mContext = context;
}
@Override
public void logHomepageDisplay(Context context, long latency) {
sendBroadcast(context, new Intent()
public void logHomepageDisplay(long latency) {
sendBroadcast(new Intent()
.putExtra(EXTRA_CONTEXTUALCARD_ACTION_TYPE, CONTEXTUAL_HOME_SHOW)
.putExtra(EXTRA_LATENCY, latency));
}
@Override
public void logContextualCardDismiss(Context context, ContextualCard card) {
public void logContextualCardDismiss(ContextualCard card) {
final Intent intent = new Intent();
intent.putExtra(EXTRA_CONTEXTUALCARD_ACTION_TYPE, CONTEXTUAL_CARD_DISMISS);
intent.putExtra(EXTRA_CONTEXTUALCARD_NAME, card.getName());
intent.putExtra(EXTRA_CONTEXTUALCARD_URI, card.getSliceUri().toString());
intent.putExtra(EXTRA_CONTEXTUALCARD_SCORE, card.getRankingScore());
sendBroadcast(context, intent);
sendBroadcast(intent);
}
@Override
public void logContextualCardDisplay(Context context, List<ContextualCard> visibleCards,
public void logContextualCardDisplay(List<ContextualCard> visibleCards,
List<ContextualCard> hiddenCards) {
final Intent intent = new Intent();
intent.putExtra(EXTRA_CONTEXTUALCARD_ACTION_TYPE, CONTEXTUAL_CARD_SHOW);
intent.putExtra(EXTRA_CONTEXTUALCARD_VISIBLE, serialize(visibleCards));
intent.putExtra(EXTRA_CONTEXTUALCARD_HIDDEN, serialize(hiddenCards));
sendBroadcast(context, intent);
sendBroadcast(intent);
}
@Override
public void logContextualCardClick(Context context, ContextualCard card, int row,
public void logContextualCardClick(ContextualCard card, int row,
int actionType) {
final Intent intent = new Intent();
intent.putExtra(EXTRA_CONTEXTUALCARD_ACTION_TYPE, CONTEXTUAL_CARD_CLICK);
intent.putExtra(EXTRA_CONTEXTUALCARD_NAME, card.getName());
intent.putExtra(EXTRA_CONTEXTUALCARD_URI, card.getSliceUri().toString());
intent.putExtra(EXTRA_CONTEXTUALCARD_SCORE, card.getRankingScore());
intent.putExtra(EXTRA_CONTEXTUALCARD_ROW, row);
intent.putExtra(EXTRA_CONTEXTUALCARD_TAP_TARGET, actionTypeToTapTarget(actionType));
sendBroadcast(context, intent);
sendBroadcast(intent);
}
@VisibleForTesting
void sendBroadcast(final Context context, final Intent intent) {
intent.setPackage(context.getString(R.string.config_settingsintelligence_package_name));
final String action = context.getString(R.string.config_settingsintelligence_log_action);
void sendBroadcast(final Intent intent) {
intent.setPackage(mContext.getString(R.string.config_settingsintelligence_package_name));
final String action = mContext.getString(R.string.config_settingsintelligence_log_action);
if (!TextUtils.isEmpty(action)) {
intent.setAction(action);
context.sendBroadcastAsUser(intent, UserHandle.ALL);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
}
}

View File

@@ -21,7 +21,7 @@ import static android.app.slice.Slice.HINT_ERROR;
import static androidx.slice.widget.SliceLiveData.SUPPORTED_SPECS;
import static com.android.settings.slices.CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI;
import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI;
import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
@@ -149,10 +149,10 @@ public class ContextualCardLoader extends AsyncLoaderCompat<List<ContextualCard>
// Two large cards
return visibleCards;
} finally {
//TODO(b/121196921): Should not call this if user click dismiss
final ContextualCardFeatureProvider contextualCardFeatureProvider =
FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider();
contextualCardFeatureProvider.logContextualCardDisplay(mContext, visibleCards,
hiddenCards);
FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider(mContext);
contextualCardFeatureProvider.logContextualCardDisplay(visibleCards, hiddenCards);
}
}
@@ -204,7 +204,7 @@ public class ContextualCardLoader extends AsyncLoaderCompat<List<ContextualCard>
}
private boolean isLargeCard(ContextualCard card) {
return card.getSliceUri().equals(WIFI_SLICE_URI)
return card.getSliceUri().equals(CONTEXTUAL_WIFI_SLICE_URI)
|| card.getSliceUri().equals(BLUETOOTH_DEVICES_SLICE_URI);
}

View File

@@ -201,8 +201,8 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
.collect(groupingBy(ContextualCard::getCardType)));
}
final long totalTime = System.currentTimeMillis() - mStartTime;
FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider()
.logHomepageDisplay(mContext, totalTime);
FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider(mContext)
.logHomepageDisplay(totalTime);
mIsFirstLaunch = false;
}

View File

@@ -34,8 +34,8 @@ public class SettingsContextualCardProvider extends ContextualCardProvider {
public ContextualCardList getContextualCards() {
final ContextualCard wifiCard =
ContextualCard.newBuilder()
.setSliceUri(CustomSliceRegistry.WIFI_SLICE_URI.toString())
.setCardName(CustomSliceRegistry.WIFI_SLICE_URI.toString())
.setSliceUri(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString())
.setCardName(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString())
.setCardCategory(ContextualCard.Category.IMPORTANT)
.build();
final ContextualCard connectedDeviceCard =

View File

@@ -98,10 +98,10 @@ public class BatteryFixSlice implements CustomSliceable {
ListBuilder.ICON_IMAGE,
batteryTip.getTitle(mContext));
sliceBuilder.addRow(new RowBuilder()
.setTitleItem(icon, ListBuilder.ICON_IMAGE)
.setTitle(batteryTip.getTitle(mContext))
.setSubtitle(batteryTip.getSummary(mContext))
.setPrimaryAction(primaryAction)
.addEndItem(icon, ListBuilder.ICON_IMAGE));
.setPrimaryAction(primaryAction));
break;
}
}
@@ -144,9 +144,9 @@ public class BatteryFixSlice implements CustomSliceable {
final SliceAction primaryAction = SliceAction.createDeeplink(getPrimaryAction(), icon,
ListBuilder.ICON_IMAGE, title);
sliceBuilder.addRow(new RowBuilder()
.setTitleItem(icon, ListBuilder.ICON_IMAGE)
.setTitle(title)
.setPrimaryAction(primaryAction)
.addEndItem(icon, ListBuilder.ICON_IMAGE))
.setPrimaryAction(primaryAction))
.setIsError(isError);
return sliceBuilder.build();
}

View File

@@ -46,6 +46,7 @@ import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.slices.CustomSliceRegistry;
import com.android.settings.slices.CustomSliceable;
import com.android.settings.slices.SliceBroadcastReceiver;
import com.android.settings.slices.SliceBuilderUtils;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -59,19 +60,22 @@ import java.util.stream.Collectors;
public class BluetoothDevicesSlice implements CustomSliceable {
/**
* TODO(b/114807655): Contextual Home Page - Connected Device
* Re-design sorting for new rule:
* Sorting rule: Audio Streaming > Last connected > Recently connected.
*/
private static final Comparator<CachedBluetoothDevice> COMPARATOR
= Comparator.naturalOrder();
@VisibleForTesting
static final String BLUETOOTH_DEVICE_HASH_CODE = "bluetooth_device_hash_code";
/**
* Add the "Pair new device" in the end of slice, when the number of Bluetooth devices is less
* than {@link #DEFAULT_EXPANDED_ROW_COUNT}.
*/
private static final int DEFAULT_EXPANDED_ROW_COUNT = 3;
@VisibleForTesting
static final int DEFAULT_EXPANDED_ROW_COUNT = 3;
/**
* Refer {@link com.android.settings.bluetooth.BluetoothDevicePreference#compareTo} to sort the
* Bluetooth devices by {@link CachedBluetoothDevice}.
*/
private static final Comparator<CachedBluetoothDevice> COMPARATOR
= Comparator.naturalOrder();
private static final String TAG = "BluetoothDevicesSlice";
@@ -109,12 +113,11 @@ public class BluetoothDevicesSlice implements CustomSliceable {
final SliceAction primarySliceAction = SliceAction.createDeeplink(primaryActionIntent, icon,
ListBuilder.ICON_IMAGE, title);
final ListBuilder listBuilder =
new ListBuilder(mContext, CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI,
ListBuilder.INFINITY)
new ListBuilder(mContext, getUri(), ListBuilder.INFINITY)
.setAccentColor(Utils.getColorAccentDefaultColor(mContext));
// Get row builders by Bluetooth devices.
final List<ListBuilder.RowBuilder> rows = getBluetoothRowBuilder(primarySliceAction);
final List<ListBuilder.RowBuilder> rows = getBluetoothRowBuilder();
// Return a header with IsError flag, if no Bluetooth devices.
if (rows.isEmpty()) {
@@ -125,15 +128,18 @@ public class BluetoothDevicesSlice implements CustomSliceable {
.build();
}
// According the number of Bluetooth devices to set sub title of header.
// Get displayable device count.
final int deviceCount = Math.min(rows.size(), DEFAULT_EXPANDED_ROW_COUNT);
// According to the displayable device count to set sub title of header.
listBuilder.setHeader(new ListBuilder.HeaderBuilder()
.setTitle(title)
.setSubtitle(getSubTitle(rows.size()))
.setSubtitle(getSubTitle(deviceCount))
.setPrimaryAction(primarySliceAction));
// Add bluetooth device rows.
for (ListBuilder.RowBuilder rowBuilder : rows) {
listBuilder.addRow(rowBuilder);
// According to the displayable device count to add bluetooth device rows.
for (int i = 0; i < deviceCount; i++) {
listBuilder.addRow(rows.get(i));
}
// Add "Pair new device" if need.
@@ -154,11 +160,19 @@ public class BluetoothDevicesSlice implements CustomSliceable {
screenTitle,
MetricsProto.MetricsEvent.SLICE)
.setClassName(mContext.getPackageName(), SubSettings.class.getName())
.setData(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI);
.setData(getUri());
}
@Override
public void onNotifyChange(Intent intent) {
// Activate available media device.
final int bluetoothDeviceHashCode = intent.getIntExtra(BLUETOOTH_DEVICE_HASH_CODE, -1);
for (CachedBluetoothDevice cachedBluetoothDevice : getConnectedBluetoothDevices()) {
if (cachedBluetoothDevice.hashCode() == bluetoothDeviceHashCode) {
cachedBluetoothDevice.setActive();
return;
}
}
}
@Override
@@ -167,10 +181,10 @@ public class BluetoothDevicesSlice implements CustomSliceable {
}
@VisibleForTesting
List<CachedBluetoothDevice> getBluetoothDevices() {
List<CachedBluetoothDevice> getConnectedBluetoothDevices() {
final List<CachedBluetoothDevice> bluetoothDeviceList = new ArrayList<>();
// If Bluetooth is disable, skip to get the bluetooth devices.
// If Bluetooth is disable, skip to get the Bluetooth devices.
if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
Log.i(TAG, "Cannot get Bluetooth devices, Bluetooth is disabled.");
return bluetoothDeviceList;
@@ -188,12 +202,13 @@ public class BluetoothDevicesSlice implements CustomSliceable {
/**
* TODO(b/114807655): Contextual Home Page - Connected Device
* Re-design to get all Bluetooth devices and sort them by new rule:
* Sorting rule: Audio Streaming > Last connected > Recently connected.
* It's under discussion for including available media devices and currently connected
* devices from Bluetooth. Will update the devices list or remove TODO later.
*/
// Get connected Bluetooth devices and sort them.
return cachedDevices.stream().filter(device -> device.isConnected()).sorted(
COMPARATOR).collect(Collectors.toList());
// Get available media device list and sort them.
return cachedDevices.stream()
.filter(device -> device.isConnected() && device.isConnectedA2dpDevice())
.sorted(COMPARATOR).collect(Collectors.toList());
}
@VisibleForTesting
@@ -226,27 +241,35 @@ public class BluetoothDevicesSlice implements CustomSliceable {
}
}
private List<ListBuilder.RowBuilder> getBluetoothRowBuilder(SliceAction primarySliceAction) {
private List<ListBuilder.RowBuilder> getBluetoothRowBuilder() {
// According to Bluetooth devices to create row builders.
final List<ListBuilder.RowBuilder> bluetoothRows = new ArrayList<>();
/**
* TODO(b/114807655): Contextual Home Page - Connected Device
* Re-design to do action "activating" in primary action.
*/
// According Bluetooth device to create row builders.
final List<CachedBluetoothDevice> bluetoothDevices = getBluetoothDevices();
final List<CachedBluetoothDevice> bluetoothDevices = getConnectedBluetoothDevices();
for (CachedBluetoothDevice bluetoothDevice : bluetoothDevices) {
bluetoothRows.add(new ListBuilder.RowBuilder()
.setTitleItem(getBluetoothDeviceIcon(bluetoothDevice), ListBuilder.ICON_IMAGE)
.setTitle(bluetoothDevice.getName())
.setSubtitle(bluetoothDevice.getConnectionSummary())
.setPrimaryAction(primarySliceAction)
.setPrimaryAction(buildBluetoothDeviceAction(bluetoothDevice))
.addEndItem(buildBluetoothDetailDeepLinkAction(bluetoothDevice)));
}
return bluetoothRows;
}
private SliceAction buildBluetoothDeviceAction(CachedBluetoothDevice bluetoothDevice) {
// Send broadcast to activate available media device.
final Intent intent = new Intent(getUri().toString())
.setClass(mContext, SliceBroadcastReceiver.class)
.putExtra(BLUETOOTH_DEVICE_HASH_CODE, bluetoothDevice.hashCode());
return SliceAction.create(
PendingIntent.getBroadcast(mContext, bluetoothDevice.hashCode(), intent, 0),
getBluetoothDeviceIcon(bluetoothDevice),
ListBuilder.ICON_IMAGE,
bluetoothDevice.getName());
}
private SliceAction buildBluetoothDetailDeepLinkAction(CachedBluetoothDevice bluetoothDevice) {
return SliceAction.createDeeplink(
getBluetoothDetailIntent(bluetoothDevice),

View File

@@ -119,15 +119,10 @@ public class LowStorageSlice implements CustomSliceable {
PendingIntent.getActivity(mContext, 0, getIntent(), 0), icon,
ListBuilder.ICON_IMAGE, title);
/**
* TODO(b/114808204): Contextual Home Page - "Low Storage"
* Slices doesn't support "Icon on the left" in header. Now we intend to start with Icon
* right aligned. Will update the icon to left until Slices support it.
*/
return new RowBuilder()
.setTitleItem(icon, ListBuilder.ICON_IMAGE)
.setTitle(title)
.setSubtitle(summary)
.addEndItem(icon, ListBuilder.ICON_IMAGE)
.setPrimaryAction(primarySliceAction);
}
}

View File

@@ -70,8 +70,8 @@ public class SliceContextualCardController implements ContextualCardController {
});
showFeedbackDialog(card);
final ContextualCardFeatureProvider contextualCardFeatureProvider =
FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider();
contextualCardFeatureProvider.logContextualCardDismiss(mContext, card);
FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider(mContext);
contextualCardFeatureProvider.logContextualCardDismiss(card);
}
@Override

View File

@@ -132,6 +132,7 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer,
cardHolder.sliceView.setOnSliceActionListener(this);
// Customize slice view for Settings
cardHolder.sliceView.showTitleItems(true);
if (card.isLargeCard()) {
cardHolder.sliceView.showHeaderDivider(true);
cardHolder.sliceView.showActionDividers(true);
@@ -173,8 +174,9 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer,
if (sliceItem.getSlice().getUri().toString().startsWith(
card.getSliceUri().toString())) {
ContextualCardFeatureProvider contexualCardFeatureProvider =
FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider();
contexualCardFeatureProvider.logContextualCardClick(mContext, card,
FeatureFactory.getFactory(mContext)
.getContextualCardFeatureProvider(mContext);
contexualCardFeatureProvider.logContextualCardClick(card,
eventInfo.rowIndex, eventInfo.actionType);
break;
}
@@ -194,7 +196,7 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer,
public SliceViewHolder(View view) {
super(view);
sliceView = view.findViewById(R.id.slice_view);
viewFlipper = view.findViewById(R.id.viewFlipper);
viewFlipper = view.findViewById(R.id.view_flipper);
}
public void resetCard() {

View File

@@ -16,7 +16,6 @@
package com.android.settings.location;
import android.app.Activity;
import android.content.Context;
import android.location.SettingInjectorService;
import android.os.Bundle;
@@ -29,7 +28,6 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.widget.SwitchBar;
@@ -103,12 +101,8 @@ public class LocationSettings extends DashboardFragment {
static void addPreferencesSorted(List<Preference> prefs, PreferenceGroup container) {
// If there's some items to display, sort the items and add them to the container.
Collections.sort(prefs, new Comparator<Preference>() {
@Override
public int compare(Preference lhs, Preference rhs) {
return lhs.getTitle().toString().compareTo(rhs.getTitle().toString());
}
});
Collections.sort(prefs,
Comparator.comparing(lhs -> lhs.getTitle().toString()));
for (Preference entry : prefs) {
container.addPreference(entry);
}

View File

@@ -277,7 +277,7 @@ public class ApnSettings extends RestrictedSettingsFragment {
private void fillList() {
final int subId = mSubscriptionInfo != null ? mSubscriptionInfo.getSubscriptionId()
: SubscriptionManager.INVALID_SUBSCRIPTION_ID;
final Uri simApnUri = Uri.withAppendedPath(Telephony.Carriers.SIM_APN_LIST,
final Uri simApnUri = Uri.withAppendedPath(Telephony.Carriers.SIM_APN_URI,
String.valueOf(subId));
StringBuilder where = new StringBuilder("NOT (type='ia' AND (apn=\"\" OR apn IS NULL)) AND "
+ "user_visible!=0");

View File

@@ -20,10 +20,13 @@ import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import com.android.settings.R;
import com.android.settings.network.telephony.MobileNetworkActivity;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.Map;
@@ -125,7 +128,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
mSubscriptionPreferences = new ArrayMap<>();
int order = mStartOrder;
for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(mManager) ) {
for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(mManager)) {
final int subId = info.getSubscriptionId();
Preference pref = existingPrefs.remove(subId);
if (pref == null) {
@@ -139,8 +142,9 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
// TODO(asargent) - set summary here to indicate default for calls/sms and data
pref.setOnPreferenceClickListener(clickedPref -> {
// TODO(asargent) - make this start MobileNetworkActivity once we've
// added support for it to take a subscription id
final Intent intent = new Intent(mContext, MobileNetworkActivity.class);
intent.putExtra(Settings.EXTRA_SUB_ID, subId);
mContext.startActivity(intent);
return true;
});

View File

@@ -126,7 +126,6 @@ public class EnabledNetworkModePreferenceController extends BasePreferenceContro
private void updatePreferenceEntries(ListPreference preference) {
final int phoneType = mTelephonyManager.getPhoneType();
final Resources resources = mContext.getResources();
final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
final int lteForced = android.provider.Settings.Global.getInt(
@@ -216,6 +215,7 @@ public class EnabledNetworkModePreferenceController extends BasePreferenceContro
}
private void updatePreferenceValueAndSummary(ListPreference preference, int networkMode) {
preference.setValue(Integer.toString(networkMode));
switch (networkMode) {
case TelephonyManager.NETWORK_MODE_TDSCDMA_WCDMA:
case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA:

View File

@@ -25,7 +25,6 @@ import android.os.Bundle;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.util.Log;
import android.view.Menu;
import android.view.View;
@@ -43,14 +42,12 @@ import com.android.settings.core.SettingsBaseActivity;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
public class MobileNetworkActivity extends SettingsBaseActivity {
private static final String TAG = "MobileSettingsActivity";
private static final String TAG = "MobileNetworkActivity";
@VisibleForTesting
static final String MOBILE_SETTINGS_TAG = "mobile_settings:";
@VisibleForTesting
@@ -94,6 +91,13 @@ public class MobileNetworkActivity extends SettingsBaseActivity {
actionBar.setDisplayHomeAsUpEnabled(true);
}
// Set the title to the name of the subscription. If we don't have subscription info, the
// title will just default to the label for this activity that's already specified in
// AndroidManifest.xml.
final SubscriptionInfo subscription = getSubscription();
if (subscription != null) {
setTitle(subscription.getDisplayName());
}
updateSubscriptions(savedInstanceState);
}
@@ -136,25 +140,41 @@ public class MobileNetworkActivity extends SettingsBaseActivity {
}
/**
* Get the current subId to display. First check whether intent has {@link
* Settings#EXTRA_SUB_ID}. If not, just display first one in list
* since it is already sorted by sim slot.
* Get the current subscription to display. First check whether intent has {@link
* Settings#EXTRA_SUB_ID} and if so find the subscription with that id. If not, just return the
* first one in the mSubscriptionInfos list since it is already sorted by sim slot.
*/
@VisibleForTesting
int getSubscriptionId() {
SubscriptionInfo getSubscription() {
final Intent intent = getIntent();
if (intent != null) {
final int subId = intent.getIntExtra(Settings.EXTRA_SUB_ID, SUB_ID_NULL);
if (subId != SUB_ID_NULL && mSubscriptionManager.isActiveSubscriptionId(subId)) {
return subId;
if (subId != SUB_ID_NULL) {
for (SubscriptionInfo subscription :
mSubscriptionManager.getAvailableSubscriptionInfoList()) {
if (subscription.getSubscriptionId() == subId) {
return subscription;
}
}
}
}
if (CollectionUtils.isEmpty(mSubscriptionInfos)) {
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
return null;
}
return mSubscriptionInfos.get(0);
}
return mSubscriptionInfos.get(0).getSubscriptionId();
/**
* Get the current subId to display.
*/
@VisibleForTesting
int getSubscriptionId() {
final SubscriptionInfo subscription = getSubscription();
if (subscription != null) {
return subscription.getSubscriptionId();
}
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
@VisibleForTesting

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.notification;
import android.app.AutomaticZenRule;
import android.content.Context;
import android.os.Bundle;
import androidx.preference.Preference;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle;
abstract class AbstractZenCustomRulePreferenceController extends
AbstractZenModePreferenceController implements PreferenceControllerMixin {
String mId;
AutomaticZenRule mRule;
AbstractZenCustomRulePreferenceController(Context context, String key,
Lifecycle lifecycle) {
super(context, key, lifecycle);
}
@Override
public void updateState(Preference preference) {
if (mId != null) {
mRule = mBackend.getAutomaticZenRule(mId);
}
}
@Override
public boolean isAvailable() {
return mRule != null;
}
public void onResume(AutomaticZenRule rule, String id) {
mId = id;
mRule = rule;
}
Bundle createBundle() {
Bundle bundle = new Bundle();
bundle.putString(ZenCustomRuleSettings.RULE_ID, mId);
return bundle;
}
}

View File

@@ -50,7 +50,7 @@ abstract public class AbstractZenModePreferenceController extends
@VisibleForTesting
protected SettingObserver mSettingObserver;
private final String KEY;
final String KEY;
final private NotificationManager mNotificationManager;
protected static ZenModeConfigWrapper mZenModeConfigWrapper;
protected MetricsFeatureProvider mMetricsFeatureProvider;

View File

@@ -80,6 +80,11 @@ public class VolumeSeekBarPreference extends SeekBarPreference {
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
}
@Override
public boolean isSelectable() {
return false;
}
public void setStream(int stream) {
mStream = stream;
setMax(mAudioManager.getStreamMaxVolume(mStream));

View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.notification;
import android.content.Context;
import android.os.Bundle;
import android.service.notification.ZenPolicy;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.List;
public class ZenCustomRuleBlockedEffectsSettings extends ZenCustomRuleSettingsBase {
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
mFooterPreferenceMixin.createFooterPreference().setTitle(
R.string.zen_mode_blocked_effects_footer);
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.zen_mode_block_settings;
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mControllers = new ArrayList<>();
mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
"zen_effect_intent", ZenPolicy.VISUAL_EFFECT_FULL_SCREEN_INTENT,
MetricsEvent.ACTION_ZEN_BLOCK_FULL_SCREEN_INTENTS, null));
mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
"zen_effect_light", ZenPolicy.VISUAL_EFFECT_LIGHTS,
MetricsEvent.ACTION_ZEN_BLOCK_LIGHT, null));
mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
"zen_effect_peek", ZenPolicy.VISUAL_EFFECT_PEEK,
MetricsEvent.ACTION_ZEN_BLOCK_PEEK, null));
mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
"zen_effect_status", ZenPolicy.VISUAL_EFFECT_STATUS_BAR,
MetricsEvent.ACTION_ZEN_BLOCK_STATUS,
new int[] {ZenPolicy.VISUAL_EFFECT_NOTIFICATION_LIST}));
mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
"zen_effect_badge", ZenPolicy.VISUAL_EFFECT_BADGE,
MetricsEvent.ACTION_ZEN_BLOCK_BADGE, null));
mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
"zen_effect_ambient", ZenPolicy.VISUAL_EFFECT_AMBIENT,
MetricsEvent.ACTION_ZEN_BLOCK_AMBIENT, null));
mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
"zen_effect_list", ZenPolicy.VISUAL_EFFECT_NOTIFICATION_LIST,
MetricsEvent.ACTION_ZEN_BLOCK_NOTIFICATION_LIST, null));
return mControllers;
}
@Override
String getPreferenceCategoryKey() {
return null;
}
@Override
public int getMetricsCategory() {
return MetricsEvent.ZEN_CUSTOM_RULE_VIS_EFFECTS;
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.notification;
import android.content.Context;
import android.os.Bundle;
import android.service.notification.ZenPolicy;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.widget.FooterPreference;
import java.util.ArrayList;
import java.util.List;
public class ZenCustomRuleCallsSettings extends ZenCustomRuleSettingsBase {
private static final String CALLS_KEY = "zen_mode_calls";
private static final String REPEAT_CALLERS_KEY = "zen_mode_repeat_callers";
private static final String STARRED_CONTACTS_KEY = "zen_mode_starred_contacts_callers";
private static final String PREFERENCE_CATEGORY_KEY = "zen_mode_settings_category_calls";
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
}
@Override
protected int getPreferenceScreenResId() {
return com.android.settings.R.xml.zen_mode_calls_settings;
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.ZEN_CUSTOM_RULE_CALLS;
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mControllers = new ArrayList<>();
mControllers.add(new ZenRuleCallsPreferenceController(context, CALLS_KEY,
getSettingsLifecycle()));
mControllers.add(new ZenRuleRepeatCallersPreferenceController(context,
REPEAT_CALLERS_KEY, getSettingsLifecycle(), context.getResources()
.getInteger(com.android.internal.R.integer.config_zen_repeat_callers_threshold)));
mControllers.add(new ZenRuleStarredContactsPreferenceController(context,
getSettingsLifecycle(), ZenPolicy.PRIORITY_CATEGORY_CALLS, STARRED_CONTACTS_KEY));
return mControllers;
}
@Override
String getPreferenceCategoryKey() {
return PREFERENCE_CATEGORY_KEY;
}
@Override
public void updatePreferences() {
super.updatePreferences();
PreferenceScreen screen = getPreferenceScreen();
Preference footerPreference = screen.findPreference(FooterPreference.KEY_FOOTER);
footerPreference.setTitle(mContext.getResources().getString(
R.string.zen_mode_custom_calls_footer, mRule.getName()));
}
}

View File

@@ -0,0 +1,160 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.notification;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Bundle;
import android.service.notification.ZenPolicy;
import androidx.preference.Preference;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.List;
public class ZenCustomRuleConfigSettings extends ZenCustomRuleSettingsBase {
private static final String CALLS_KEY = "zen_rule_calls_settings";
private static final String MESSAGES_KEY = "zen_rule_messages_settings";
private static final String ALARMS_KEY = "zen_rule_alarms";
private static final String MEDIA_KEY = "zen_rule_media";
private static final String SYSTEM_KEY = "zen_rule_system";
private static final String REMINDERS_KEY = "zen_rule_reminders";
private static final String EVENTS_KEY = "zen_rule_events";
private static final String NOTIFICATIONS_KEY = "zen_rule_notifications";
private static final String PREFERENCE_CATEGORY_KEY = "zen_custom_rule_configuration_category";
private Preference mCallsPreference;
private Preference mMessagesPreference;
private Preference mNotificationsPreference;
private ZenModeSettings.SummaryBuilder mSummaryBuilder;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mSummaryBuilder = new ZenModeSettings.SummaryBuilder(mContext);
mCallsPreference = getPreferenceScreen().findPreference(CALLS_KEY);
mCallsPreference.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
new SubSettingLauncher(mContext)
.setDestination(ZenCustomRuleCallsSettings.class.getName())
.setArguments(createZenRuleBundle())
.setSourceMetricsCategory(MetricsEvent.ZEN_CUSTOM_RULE_CALLS)
.launch();
return true;
}
});
mMessagesPreference = getPreferenceScreen().findPreference(MESSAGES_KEY);
mMessagesPreference.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
new SubSettingLauncher(mContext)
.setDestination(ZenCustomRuleMessagesSettings.class.getName())
.setArguments(createZenRuleBundle())
.setSourceMetricsCategory(MetricsEvent.ZEN_CUSTOM_RULE_MESSAGES)
.launch();
return true;
}
});
mNotificationsPreference = getPreferenceScreen().findPreference(NOTIFICATIONS_KEY);
mNotificationsPreference.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
new SubSettingLauncher(mContext)
.setDestination(ZenCustomRuleNotificationsSettings.class.getName())
.setArguments(createZenRuleBundle())
.setSourceMetricsCategory
(MetricsEvent.ZEN_CUSTOM_RULE_NOTIFICATION_RESTRICTIONS)
.launch();
return true;
}
});
updateSummaries();
}
@Override
public void onZenModeConfigChanged() {
super.onZenModeConfigChanged();
updateSummaries();
}
/**
* Updates summaries of preferences without preference controllers
*/
private void updateSummaries() {
NotificationManager.Policy noManPolicy = mBackend.toNotificationPolicy(
mRule.getZenPolicy());
mCallsPreference.setSummary(mSummaryBuilder.getCallsSettingSummary(noManPolicy));
mMessagesPreference.setSummary(mSummaryBuilder.getMessagesSettingSummary(noManPolicy));
mNotificationsPreference.setSummary(mSummaryBuilder.getBlockedEffectsSummary(noManPolicy));
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.zen_mode_custom_rule_configuration;
}
@Override
public int getMetricsCategory() {
return MetricsEvent.ZEN_CUSTOM_RULE_SOUND_SETTINGS;
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mControllers = new ArrayList<>();
mControllers.add(new ZenRuleCustomSwitchPreferenceController(context,
getSettingsLifecycle(), ALARMS_KEY, ZenPolicy.PRIORITY_CATEGORY_ALARMS,
MetricsEvent.ACTION_ZEN_ALLOW_ALARMS));
mControllers.add(new ZenRuleCustomSwitchPreferenceController(context,
getSettingsLifecycle(), MEDIA_KEY, ZenPolicy.PRIORITY_CATEGORY_MEDIA,
MetricsEvent.ACTION_ZEN_ALLOW_MEDIA));
mControllers.add(new ZenRuleCustomSwitchPreferenceController(context,
getSettingsLifecycle(), SYSTEM_KEY, ZenPolicy.PRIORITY_CATEGORY_SYSTEM,
MetricsEvent.ACTION_ZEN_ALLOW_SYSTEM));
mControllers.add(new ZenRuleCustomSwitchPreferenceController(context,
getSettingsLifecycle(), REMINDERS_KEY, ZenPolicy.PRIORITY_CATEGORY_REMINDERS,
MetricsEvent.ACTION_ZEN_ALLOW_REMINDERS));
mControllers.add(new ZenRuleCustomSwitchPreferenceController(context,
getSettingsLifecycle(), EVENTS_KEY, ZenPolicy.PRIORITY_CATEGORY_EVENTS,
MetricsEvent.ACTION_ZEN_ALLOW_EVENTS));
return mControllers;
}
@Override
String getPreferenceCategoryKey() {
return PREFERENCE_CATEGORY_KEY;
}
@Override
public void onResume() {
super.onResume();
updateSummaries();
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.notification;
import android.content.Context;
import android.service.notification.ZenPolicy;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.widget.FooterPreference;
import java.util.ArrayList;
import java.util.List;
public class ZenCustomRuleMessagesSettings extends ZenCustomRuleSettingsBase {
private static final String MESSAGES_KEY = "zen_mode_messages";
private static final String STARRED_CONTACTS_KEY = "zen_mode_starred_contacts_messages";
private static final String PREFERENCE_CATEGORY_KEY = "zen_mode_settings_category_messages";
@Override
protected int getPreferenceScreenResId() {
return com.android.settings.R.xml.zen_mode_messages_settings;
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.ZEN_CUSTOM_RULE_MESSAGES;
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mControllers = new ArrayList<>();
mControllers.add(new ZenRuleMessagesPreferenceController(context, MESSAGES_KEY,
getSettingsLifecycle()));
mControllers.add(new ZenRuleStarredContactsPreferenceController(context,
getSettingsLifecycle(), ZenPolicy.PRIORITY_CATEGORY_MESSAGES,
STARRED_CONTACTS_KEY));
return mControllers;
}
@Override
String getPreferenceCategoryKey() {
return PREFERENCE_CATEGORY_KEY;
}
@Override
public void updatePreferences() {
super.updatePreferences();
PreferenceScreen screen = getPreferenceScreen();
Preference footerPreference = screen.findPreference(FooterPreference.KEY_FOOTER);
footerPreference.setTitle(mContext.getResources().getString(
R.string.zen_mode_custom_messages_footer, mRule.getName()));
}
}

Some files were not shown because too many files have changed in this diff Show More