Snap for 5110273 from c9b56254a6 to qt-release
Change-Id: I1000a110e95b1216ab1d4dfe01f8a97b647fd566
@@ -59,6 +59,7 @@
|
||||
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.STATUS_BAR" />
|
||||
<uses-permission android:name="android.permission.MANAGE_USB" />
|
||||
<uses-permission android:name="android.permission.MANAGE_DEBUGGING" />
|
||||
<uses-permission android:name="android.permission.SET_POINTER_SPEED" />
|
||||
<uses-permission android:name="android.permission.SET_KEYBOARD_LAYOUT" />
|
||||
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
|
||||
@@ -80,6 +81,8 @@
|
||||
<uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.MANAGE_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC_INTERNAL" />
|
||||
<uses-permission android:name="android.permission.USER_ACTIVITY" />
|
||||
<uses-permission android:name="android.permission.CHANGE_APP_IDLE_STATE" />
|
||||
<uses-permission android:name="android.permission.PEERS_MAC_ADDRESS"/>
|
||||
@@ -1451,7 +1454,7 @@
|
||||
<!-- Lock screen settings -->
|
||||
<activity android:name=".password.ConfirmDeviceCredentialActivity"
|
||||
android:exported="true"
|
||||
android:theme="@android:style/Theme.NoDisplay">
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar">
|
||||
<intent-filter android:priority="1">
|
||||
<action android:name="android.app.action.CONFIRM_DEVICE_CREDENTIAL" />
|
||||
<action android:name="android.app.action.CONFIRM_FRP_CREDENTIAL" />
|
||||
@@ -1524,6 +1527,15 @@
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait"/>
|
||||
|
||||
<activity android:name=".biometrics.BiometricEnrollActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/GlifTheme.Light">
|
||||
<intent-filter>
|
||||
<action android:name="android.settings.BIOMETRIC_ENROLL" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".biometrics.fingerprint.FingerprintSettings" android:exported="false"/>
|
||||
<activity android:name=".biometrics.fingerprint.FingerprintEnrollFindSensor" android:exported="false"/>
|
||||
<activity android:name=".biometrics.fingerprint.FingerprintEnrollEnrolling" android:exported="false"/>
|
||||
|
||||
24
res/anim/confirm_credential_biometric_transition_enter.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?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
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shareInterpolator="false"
|
||||
android:zAdjustment="top">
|
||||
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
|
||||
android:interpolator="@android:interpolator/linear_out_slow_in"
|
||||
android:duration="350"/>
|
||||
</set>
|
||||
24
res/anim/confirm_credential_biometric_transition_exit.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?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
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shareInterpolator="false"
|
||||
android:zAdjustment="top">
|
||||
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
|
||||
android:interpolator="@android:interpolator/linear_out_slow_in"
|
||||
android:duration="350" />
|
||||
</set>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
@@ -1,30 +0,0 @@
|
||||
<!--
|
||||
~ 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
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="32.0"
|
||||
android:viewportHeight="32.0">
|
||||
<path
|
||||
android:fillColor="?android:attr/colorError"
|
||||
android:pathData="M15.99,2.5C8.53,2.5 2.5,8.54 2.5,16.0s6.03,13.5 13.49,13.5S29.5,23.46 29.5,16.0S23.45,2.5 15.99,2.5zM16.0,26.8c-5.97,0.0 -10.8,-4.83 -10.8,-10.8S10.03,5.2 16.0,5.2S26.8,10.03 26.8,16.0S21.97,26.8 16.0,26.8z"/>
|
||||
<path
|
||||
android:fillColor="?android:attr/colorError"
|
||||
android:pathData="M14.65,20.05l2.7,0.0l0.0,2.7l-2.7,0.0z"/>
|
||||
<path
|
||||
android:fillColor="?android:attr/colorError"
|
||||
android:pathData="M14.65,9.25l2.7,0.0l0.0,8.1l-2.7,0.0z"/>
|
||||
</vector>
|
||||
@@ -87,14 +87,6 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fingerprintIcon"
|
||||
android:layout_gravity="end|bottom"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="28dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:visibility="gone"/>
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -108,14 +108,6 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fingerprintIcon"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
|
||||
</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
|
||||
|
||||
@@ -85,14 +85,6 @@
|
||||
android:layout_marginEnd="?attr/suwMarginSides"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:gravity="center_vertical"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fingerprintIcon"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/confirm_fingerprint_icon_content_description"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
@@ -89,19 +89,5 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fingerprintIcon"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:contentDescription="@string/confirm_fingerprint_icon_content_description"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
|
||||
</FrameLayout>
|
||||
|
||||
@@ -70,16 +70,6 @@
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fingerprintIcon"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:contentDescription="@string/confirm_fingerprint_icon_content_description"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/cancelButton"
|
||||
style="@style/SuwGlifButton.Secondary"
|
||||
|
||||
@@ -97,15 +97,6 @@
|
||||
android:layout_marginEnd="12dp"
|
||||
android:gravity="center_vertical"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fingerprintIcon"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:contentDescription="@string/confirm_fingerprint_icon_content_description"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
|
||||
</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
|
||||
|
||||
@@ -90,16 +90,6 @@
|
||||
android:layout_marginTop="12dp"
|
||||
android:gravity="center_vertical"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fingerprintIcon"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="?attr/suwMarginSides"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:contentDescription="@string/confirm_fingerprint_icon_content_description"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/cancelButton"
|
||||
style="@style/SuwGlifButton.Secondary"
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/ContextualCardStyle">
|
||||
@@ -25,10 +24,10 @@
|
||||
<androidx.slice.widget.SliceView
|
||||
android:id="@+id/slice_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/homepage_slice_card_max_height"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/homepage_card_vertical_margin"
|
||||
android:layout_marginTop="@dimen/homepage_card_vertical_margin"
|
||||
android:paddingStart="@dimen/homepage_card_padding_start"
|
||||
android:paddingEnd="@dimen/homepage_card_padding_end"
|
||||
android:paddingTop="@dimen/homepage_card_padding_top"
|
||||
android:paddingBottom="@dimen/homepage_card_padding_bottom"/>
|
||||
android:paddingEnd="@dimen/homepage_card_padding_end"/>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
44
res/layout/network_request_dialog_title.xml
Normal file
@@ -0,0 +1,44 @@
|
||||
<?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:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingEnd="?android:attr/dialogPreferredPadding"
|
||||
android:orientation="horizontal"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:minHeight="?android:attr/listPreferredItemHeightSmall">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/network_request_title_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="16dip"
|
||||
android:layout_weight="1"
|
||||
android:textSize="18sp"
|
||||
android:gravity="center_vertical"
|
||||
style="@style/info_label"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/network_request_title_progress"
|
||||
style="?android:attr/progressBarStyleSmallTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="16dip"
|
||||
android:minWidth="32dp"
|
||||
android:text="@string/progress_scanning"/>
|
||||
</LinearLayout>
|
||||
@@ -327,17 +327,10 @@
|
||||
<!-- Homepage cards size and padding -->
|
||||
<dimen name="homepage_card_corner_radius">8dp</dimen>
|
||||
<dimen name="homepage_card_elevation">2dp</dimen>
|
||||
<dimen name="homepage_card_top_margin">6dp</dimen>
|
||||
<dimen name="homepage_card_bottom_margin">6dp</dimen>
|
||||
<dimen name="homepage_card_vertical_margin">6dp</dimen>
|
||||
<dimen name="homepage_card_side_margin">16dp</dimen>
|
||||
<dimen name="homepage_card_padding_start">16dp</dimen>
|
||||
<dimen name="homepage_card_padding_end">16dp</dimen>
|
||||
<dimen name="homepage_card_padding_top">6dp</dimen>
|
||||
<dimen name="homepage_card_padding_bottom">6dp</dimen>
|
||||
|
||||
<!-- Slice cards maximum height (4 rows + show more)
|
||||
MODE_LARGE height(3 rows + show more) 240dp + one line text(1 row) 48dp = 288dp -->
|
||||
<dimen name="homepage_slice_card_max_height">288dp</dimen>
|
||||
|
||||
<!-- Signal icon in NetworkSelectSetting -->
|
||||
<dimen name="signal_strength_icon_size">24dp</dimen>
|
||||
|
||||
@@ -1051,9 +1051,6 @@
|
||||
<!-- Button to confirm the last removing the last fingerprint. [CHAR LIMIT=20]-->
|
||||
<string name="fingerprint_last_delete_confirm">Yes, remove</string>
|
||||
|
||||
<!-- Content description for the fingerprint icon when the user is prompted to enter his credentials. Not shown on the screen. [CHAR LIMIT=NONE] -->
|
||||
<string name="confirm_fingerprint_icon_content_description">Use your fingerprint to continue.</string>
|
||||
|
||||
<!-- Title of the preferences category for preference items to control encryption -->
|
||||
<string name="crypt_keeper_settings_title">Encryption</string>
|
||||
|
||||
@@ -3709,6 +3706,10 @@
|
||||
<!-- About phone settings screen, Safety Legal dialog title until the link is fully loaded -->
|
||||
<string name="settings_safetylegal_activity_loading">Loading\u2026</string>
|
||||
|
||||
<!-- ConfirmDeviceCredential settings-->
|
||||
<!-- Button text shown on BiometricPrompt (system dialog that asks for biometric authentication) giving the user the option to use an alternate form of authentication (Pin/Pattern/Pass) [CHAR LIMIT=30] -->
|
||||
<string name="confirm_device_credential_use_alternate_method">Use alternate method</string>
|
||||
|
||||
<!-- Lock Pattern settings -->
|
||||
<!-- Header on first screen of choose password/PIN flow [CHAR LIMIT=40] -->
|
||||
<string name="lockpassword_choose_your_screen_lock_header">Set screen lock</string>
|
||||
@@ -3771,8 +3772,8 @@
|
||||
<string name="lockpassword_confirm_your_password_generic_profile">Enter your work password to continue</string>
|
||||
|
||||
<!-- This string shows up on a screen where a user can enter a pattern that
|
||||
unlocks their device. This is an extra security measure that's required for them to
|
||||
continue. [CHAR LIMIT=100] -->
|
||||
unlocks their device. This is an extra security measure that's required for them to
|
||||
continue. [CHAR LIMIT=100] -->
|
||||
<string name="lockpassword_strong_auth_required_device_pattern">For added security, use your device pattern</string>
|
||||
<!-- This string shows up on a screen where a user can enter a PIN that unlocks their device.
|
||||
This is an extra security measure that's required for them to continue. [CHAR LIMIT=100]
|
||||
@@ -5654,12 +5655,18 @@
|
||||
<string name="remove_and_uninstall_device_admin">Deactivate & uninstall</string>
|
||||
<!-- Label for screen showing to select device admin apps -->
|
||||
<string name="select_device_admin_msg">Device admin apps</string>
|
||||
|
||||
<!-- Message when there are no available device admin apps to display -->
|
||||
<string name="no_device_admins">No device admin apps available</string>
|
||||
<!-- Title for personal device admin apps on the list [CHAR_LIMIT=25] -->
|
||||
<string name="personal_device_admin_title">Personal</string>
|
||||
<!-- Title for managed device admin apps on the list [CHAR_LIMIT=25] -->
|
||||
<string name="managed_device_admin_title">Work</string>
|
||||
<!-- Title for whether to enable SMS access restriction [CHAR LIMIT=50]-->
|
||||
<string name="sms_access_restriction_enabled">Restrict SMS & call log access</string>
|
||||
<!-- Summary for whether to enable SMS access restriction [CHAR LIMIT=NONE]-->
|
||||
<string name="sms_access_restriction_enabled_summary">Only default phone and messaging apps have SMS & call log permissions</string>
|
||||
|
||||
|
||||
<!-- Message when there are no available trust agents to display -->
|
||||
<string name="no_trust_agents">No available trust agents</string>
|
||||
@@ -7185,20 +7192,26 @@
|
||||
<string name="zen_mode_behavior_alarms_only">No sound except alarms and media</string>
|
||||
|
||||
<!-- Do not disturb: Title for the zen mode automation option in Settings. [CHAR LIMIT=40] -->
|
||||
<string name="zen_mode_automation_settings_title">Turn on automatically</string>
|
||||
<string name="zen_mode_automation_settings_title">Schedules</string>
|
||||
|
||||
<!-- Do not disturb: Title for the zen mode automatic rules page in settings. [CHAR LIMIT=30] -->
|
||||
<string name="zen_mode_automation_settings_page_title">Automatic rules</string>
|
||||
<string name="zen_mode_automation_settings_page_title">Do Not Disturb</string>
|
||||
|
||||
<!-- Do not disturb: Title for a specific zen mode automatic rule in settings. [CHAR LIMIT=30] -->
|
||||
<string name="zen_mode_automatic_rule_settings_page_title">Automatic rule</string>
|
||||
|
||||
<!-- Do not disturb: Title do not disturb settings representing automatic (scheduled) do not disturb rules. [CHAR LIMIT=30] -->
|
||||
<string name="zen_mode_schedule_category_title">Schedule</string>
|
||||
|
||||
<!-- Do not disturb: Title for the zen mode automation option Suggestion. [CHAR LIMIT=46] -->
|
||||
<string name="zen_mode_automation_suggestion_title">Silence phone at certain times</string>
|
||||
|
||||
<!-- Do not disturb: Summary for the zen mode automation option Suggestion. [CHAR LIMIT=55] -->
|
||||
<string name="zen_mode_automation_suggestion_summary">Set Do Not Disturb rules</string>
|
||||
|
||||
<!-- Do not disturb: Header for the Do Not Disturb automatic rules. [CHAR LIMIT=55] -->
|
||||
<string name="zen_mode_schedule_title">Schedule</string>
|
||||
|
||||
<!-- Do not disturb: Switch toggle to toggle whether to use an automatic dnd rule or not [CHAR LIMIT=40] -->
|
||||
<string name="zen_mode_use_automatic_rule">Use rule</string>
|
||||
|
||||
@@ -7221,10 +7234,10 @@
|
||||
<string name="zen_mode_visual_signals_settings_subtitle">Allow visual signals</string>
|
||||
|
||||
<!-- Do not disturb: zen settings screens category title [CHAR LIMIT=100] -->
|
||||
<string name="zen_mode_settings_category">When Do Not Disturb is turned on</string>
|
||||
<string name="zen_mode_settings_category">When Do Not Disturb is on</string>
|
||||
|
||||
<!-- Do not disturb: restrict notifications title [CHAR LIMIT=60] -->
|
||||
<string name="zen_mode_restrict_notifications_title">Notifications</string>
|
||||
<!-- Do not disturb: restrict notifications title [CHAR LIMIT=80] -->
|
||||
<string name="zen_mode_restrict_notifications_title">Notification restrictions</string>
|
||||
<!-- Do not disturb: Mute notifications option [CHAR LIMIT=60] -->
|
||||
<string name="zen_mode_restrict_notifications_mute">No sound from notifications</string>
|
||||
<!-- Do not disturb:Mute notifications summary [CHAR LIMIT=NONE] -->
|
||||
@@ -7356,15 +7369,15 @@
|
||||
<item quantity="other"><xliff:g id="on_count" example="3">%d</xliff:g> rules can turn on automatically</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Do not disturb settings, category header [CHAR LIMIT=100]-->
|
||||
<string name="zen_category_behavior">Behavior</string>
|
||||
<!-- Do not disturb settings, category header [CHAR LIMIT=100]-->
|
||||
<!-- Do not disturb settings, category header [CHAR LIMIT=120]-->
|
||||
<string name="zen_category_behavior">Mute phone, but allow exceptions</string>
|
||||
<!-- Do not disturb settings, exceptions to dnd title [CHAR LIMIT=100]-->
|
||||
<string name="zen_category_exceptions">Exceptions</string>
|
||||
<!-- Do not disturb settings, category header [CHAR LIMIT=100]-->
|
||||
<string name="zen_category_schedule">Schedule</string>
|
||||
|
||||
<!-- Do not disturb settings, sound and vibrations title [CHAR LIMIT=100]-->
|
||||
<string name="zen_sound_title">Sound & vibration</string>
|
||||
<!-- Do not disturb settings, sound and vibrations exceptions title [CHAR LIMIT=100]-->
|
||||
<string name="zen_sound_title">See all exceptions</string>
|
||||
<!-- Do not disturb settings, sound and vibrations screen footer [CHAR LIMIT=NONE]-->
|
||||
<string name="zen_sound_footer">When Do Not Disturb is on, sound and vibration will be muted, except for the items you allow above.</string>
|
||||
<!-- Do not disturb settings, sound and vibrations screen category [CHAR LIMIT=100]-->
|
||||
@@ -7816,8 +7829,8 @@
|
||||
<!-- [CHAR LIMIT=100] Zen mode settings: Warning text for invalid zen rule names -->
|
||||
<string name="zen_mode_rule_name_warning">Rule name already in use</string>
|
||||
|
||||
<!-- [CHAR LIMIT=40] Zen mode settings: Add rule menu option name -->
|
||||
<string name="zen_mode_add_rule">Add rule</string>
|
||||
<!-- [CHAR LIMIT=40] Zen mode settings: Add another automatic zen rule option name-->
|
||||
<string name="zen_mode_add_rule">Add more</string>
|
||||
|
||||
<!-- [CHAR LIMIT=40] Zen mode settings: Add event-based rule, set rule name title -->
|
||||
<string name="zen_mode_add_event_rule">Add event rule</string>
|
||||
@@ -7942,6 +7955,9 @@
|
||||
<!-- [CHAR LIMIT=20] Zen mode settings: Messages option -->
|
||||
<string name="zen_mode_messages">Messages</string>
|
||||
|
||||
<!-- 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=40] Zen mode settings: Allow messages toggle title -->
|
||||
<string name="zen_mode_messages_title">Allow messages</string>
|
||||
|
||||
@@ -7978,42 +7994,36 @@
|
||||
<!-- [CHAR LIMIT=40] Zen mode settings: Calls or messages option value: None -->
|
||||
<string name="zen_mode_from_none">None</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: Alarms option -->
|
||||
<string name="zen_mode_alarms">Alarms</string>
|
||||
<!-- [CHAR LIMIT=80] Zen mode settings: Allow alarms option -->
|
||||
<string name="zen_mode_alarms">Allow alarms</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: Alarms option (ie: sound from alarm clock) -->
|
||||
<string name="zen_mode_alarms_list">alarms</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: Media option -->
|
||||
<string name="zen_mode_media">Media</string>
|
||||
<!-- [CHAR LIMIT=80] Zen mode settings: Allow media (sound from video) to bypass dnd -->
|
||||
<string name="zen_mode_media">Allow media</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: Media (ie: sound from video) -->
|
||||
<string name="zen_mode_media_list">media</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: System option which includes sounds such as touch sounds -->
|
||||
<string name="zen_mode_system">Touch sounds</string>
|
||||
<!-- [CHAR LIMIT=80] Zen mode settings: allow touch sounds to bypass DND -->
|
||||
<string name="zen_mode_system">Allow touch sounds</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: System sounds (ie: touch sounds) -->
|
||||
<string name="zen_mode_system_list">touch sounds</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: Reminders option -->
|
||||
<string name="zen_mode_reminders">Reminders</string>
|
||||
<!-- [CHAR LIMIT=80] Zen mode settings: Allow reminder notifications/sounds to bypass DND -->
|
||||
<string name="zen_mode_reminders">Allow reminders</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: Reminders (ie: calendar reminders are allowed to bypass dnd) -->
|
||||
<string name="zen_mode_reminders_list">reminders</string>
|
||||
|
||||
<!-- [CHAR LIMIT=70] Zen mode settings: Allow reminders toggle title -->
|
||||
<string name="zen_mode_reminders_title">Allow reminders</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: Events option -->
|
||||
<string name="zen_mode_events">Events</string>
|
||||
<!-- [CHAR LIMIT=80] Zen mode settings: Allow event notifications/sounds to bypass DND -->
|
||||
<string name="zen_mode_events">Allow events</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: Events (ie: calendar events) -->
|
||||
<string name="zen_mode_events_list">events</string>
|
||||
|
||||
<!-- [CHAR LIMIT=70] Zen mode settings: Allow events toggle title -->
|
||||
<string name="zen_mode_events_title">Allow events</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: All callers summary -->
|
||||
<string name="zen_mode_all_callers">anyone</string>
|
||||
|
||||
@@ -8371,9 +8381,6 @@
|
||||
<!-- Explanation that the app that will NEVER be launched to open web links to domains that it understands -->
|
||||
<string name="app_link_open_never">Don’t open in this app</string>
|
||||
|
||||
<!-- Fingerprint hint message when finger was not recognized.-->
|
||||
<string name="fingerprint_not_recognized">Not recognized</string>
|
||||
|
||||
<!-- Title for Default Apps settings [CHAR LIMIT=30] -->
|
||||
<string name="default_apps_title">Default</string>
|
||||
|
||||
@@ -10269,7 +10276,9 @@
|
||||
<!-- See less items in contextual homepage [CHAR LIMIT=30]-->
|
||||
<string name="see_less">See less</string>
|
||||
|
||||
<!-- Summary for connected devices count in connected device slice. [CHAR LIMIT=NONE] -->
|
||||
<!-- Title for Network connection request Dialog [CHAR LIMIT=30] -->
|
||||
<string name="network_connection_request_dialog_title">Choose device</string>
|
||||
|
||||
<plurals name="show_connected_devices">
|
||||
<item quantity="one"><xliff:g id="number_device_count">%1$d</xliff:g> device connected</item>
|
||||
<item quantity="other"><xliff:g id="number_device_count">%1$d</xliff:g> devices connected</item>
|
||||
|
||||
@@ -455,8 +455,8 @@
|
||||
</style>
|
||||
|
||||
<style name="ContextualCardStyle">
|
||||
<item name="android:layout_marginTop">@dimen/homepage_card_top_margin</item>
|
||||
<item name="android:layout_marginBottom">@dimen/homepage_card_bottom_margin</item>
|
||||
<item name="android:layout_marginTop">@dimen/homepage_card_vertical_margin</item>
|
||||
<item name="android:layout_marginBottom">@dimen/homepage_card_vertical_margin</item>
|
||||
<item name="android:layout_marginStart">@dimen/homepage_card_side_margin</item>
|
||||
<item name="android:layout_marginEnd">@dimen/homepage_card_side_margin</item>
|
||||
<item name="cardCornerRadius">@dimen/homepage_card_corner_radius</item>
|
||||
|
||||
@@ -513,6 +513,11 @@
|
||||
<Preference
|
||||
android:key="reset_shortcut_manager_throttling"
|
||||
android:title="@string/reset_shortcut_manager_throttling" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="sms_access_restriction_enabled"
|
||||
android:title="@string/sms_access_restriction_enabled"
|
||||
android:summary="@string/sms_access_restriction_enabled_summary" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<com.android.settings.development.autofill.AutofillPreferenceCategory
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2016 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"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:key="installed_app_detail_settings_screen"
|
||||
app:initialExpandedChildrenCount="6">
|
||||
|
||||
<com.android.settings.applications.LayoutPreference
|
||||
android:key="header_view"
|
||||
android:layout="@layout/settings_entity_header"
|
||||
android:selectable="false"
|
||||
android:order="-10000"/>
|
||||
|
||||
<com.android.settings.applications.LayoutPreference
|
||||
android:key="instant_app_buttons"
|
||||
android:layout="@layout/instant_app_buttons"
|
||||
android:selectable="false"
|
||||
android:order="-9999"/>
|
||||
|
||||
<com.android.settings.widget.ActionButtonPreference
|
||||
android:key="action_buttons"
|
||||
android:order="-9998" />
|
||||
|
||||
<Preference
|
||||
android:key="notification_settings"
|
||||
android:title="@string/notifications_label"
|
||||
android:selectable="true"/>
|
||||
|
||||
<com.android.settings.widget.FixedLineSummaryPreference
|
||||
android:key="permission_settings"
|
||||
android:title="@string/permissions_label"
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:selectable="true"
|
||||
app:summaryLineCount="1" />
|
||||
|
||||
<Preference
|
||||
android:key="storage_settings"
|
||||
android:title="@string/storage_settings"
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:selectable="true"/>
|
||||
|
||||
<com.android.settings.applications.AppDomainsPreference
|
||||
android:key="instant_app_launch_supported_domain_urls"
|
||||
android:title="@string/app_launch_supported_domain_urls_title"
|
||||
android:selectable="true" />
|
||||
|
||||
<Preference
|
||||
android:key="data_settings"
|
||||
android:title="@string/data_usage_summary_title"
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:selectable="true"/>
|
||||
|
||||
<Preference
|
||||
android:key="battery"
|
||||
android:title="@string/power_usage_summary_title"
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:selectable="true"/>
|
||||
|
||||
<Preference
|
||||
android:key="preferred_settings"
|
||||
android:title="@string/launch_by_default"
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:selectable="true"/>
|
||||
|
||||
<Preference
|
||||
android:key="memory"
|
||||
android:title="@string/memory_settings_title"
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:enabled="false"
|
||||
android:selectable="true"/>
|
||||
|
||||
<Preference
|
||||
android:key="app_version"
|
||||
android:selectable="false"
|
||||
android:order="9999"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -113,7 +113,7 @@
|
||||
android:title="@string/header_category_system"
|
||||
android:summary="@string/system_dashboard_summary"
|
||||
android:icon="@drawable/ic_homepage_system_dashboard"
|
||||
android:order="-10"
|
||||
android:order="10"
|
||||
android:fragment="com.android.settings.system.SystemDashboardFragment"/>
|
||||
|
||||
<Preference
|
||||
|
||||
@@ -36,9 +36,4 @@
|
||||
<PreferenceCategory
|
||||
android:key="usb_details_power_role"/>
|
||||
|
||||
<!-- Empty category for spacing -->
|
||||
<PreferenceCategory
|
||||
android:key="usb_details_space"
|
||||
settings:allowDividerAbove="false"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
<PreferenceCategory
|
||||
android:key="user_list"
|
||||
android:title="@string/user_list_title"
|
||||
android:order="10">
|
||||
android:order="10"
|
||||
settings:searchable="false">
|
||||
</PreferenceCategory>
|
||||
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
android:key="zen_mode_automation_settings_page"
|
||||
android:title="@string/zen_mode_automation_settings_page_title" >
|
||||
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="zen_mode_automatic_rules">
|
||||
android:key="zen_mode_automatic_rules"
|
||||
android:title="@string/zen_mode_schedule_title">
|
||||
<!-- Rules added at runtime -->
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="zen_mode_calls_settings_page"
|
||||
android:title="@string/zen_mode_calls" >
|
||||
|
||||
|
||||
40
res/xml/zen_mode_messages_settings.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<?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_mode_messages_settings_page"
|
||||
android:title="@string/zen_mode_messages" >
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/zen_mode_settings_category"
|
||||
android:key="zen_mode_settings_category_messages">
|
||||
<!-- Messages -->
|
||||
<ListPreference
|
||||
android:key="zen_mode_messages"
|
||||
android:title="@string/zen_mode_messages_title"
|
||||
android:entries="@array/zen_mode_contacts_entries"
|
||||
android:entryValues="@array/zen_mode_contacts_values"/>
|
||||
|
||||
<Preference
|
||||
android:key="zen_mode_starred_contacts_messages"
|
||||
android:title="@string/zen_mode_starred_contacts_title"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<com.android.settingslib.widget.FooterPreference/>
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -1,50 +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.
|
||||
-->
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:key="zen_mode_msg_event_reminder_settings_page"
|
||||
android:title="@string/zen_msg_event_reminder_title" >
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/zen_mode_settings_category"
|
||||
android:key="zen_mode_settings_category_msg_event_reminder">
|
||||
<!-- Messages -->
|
||||
<ListPreference
|
||||
android:key="zen_mode_messages"
|
||||
android:title="@string/zen_mode_messages_title"
|
||||
android:entries="@array/zen_mode_contacts_entries"
|
||||
android:entryValues="@array/zen_mode_contacts_values"/>
|
||||
|
||||
<Preference
|
||||
android:key="zen_mode_starred_contacts_messages"
|
||||
android:title="@string/zen_mode_starred_contacts_title"/>
|
||||
|
||||
<!-- Reminders -->
|
||||
<SwitchPreference
|
||||
android:key="zen_mode_reminders"
|
||||
android:title="@string/zen_mode_reminders_title"/>
|
||||
|
||||
<!-- Events -->
|
||||
<SwitchPreference
|
||||
android:key="zen_mode_events"
|
||||
android:title="@string/zen_mode_events_title"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<com.android.settingslib.widget.FooterPreference />
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -25,62 +25,59 @@
|
||||
<PreferenceCategory
|
||||
android:key="zen_mode_settings_category_behavior"
|
||||
android:title="@string/zen_category_behavior">
|
||||
<!-- sound vibration -->
|
||||
<!-- Calls -->
|
||||
<Preference
|
||||
android:key="zen_mode_behavior_calls"
|
||||
android:title="@string/zen_mode_calls_title"
|
||||
android:fragment="com.android.settings.notification.ZenModeCallsSettings" />
|
||||
|
||||
<!-- Messages -->
|
||||
<Preference
|
||||
android:key="zen_mode_behavior_messages"
|
||||
android:title="@string/zen_mode_messages_title"
|
||||
android:fragment="com.android.settings.notification.ZenModeMessagesSettings" />
|
||||
|
||||
<!-- Alarms -->
|
||||
<SwitchPreference
|
||||
android:key="zen_mode_behavior_alarms"
|
||||
android:title="@string/zen_mode_alarms"/>
|
||||
|
||||
<!-- All sounds -->
|
||||
<Preference
|
||||
android:key="zen_sound_vibration_settings"
|
||||
android:title="@string/zen_sound_title"
|
||||
android:fragment="com.android.settings.notification.ZenModeSoundVibrationSettings"/>
|
||||
|
||||
<!-- What to block (effects) -->
|
||||
<Preference
|
||||
android:key="zen_mode_block_effects_settings"
|
||||
android:title="@string/zen_mode_restrict_notifications_title"
|
||||
android:fragment="com.android.settings.notification.ZenModeRestrictNotificationsSettings" />
|
||||
android:fragment="com.android.settings.notification.ZenModeSoundVibrationSettings"
|
||||
android:icon="@drawable/ic_chevron_right_24dp"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="zen_mode_settings_category_exceptions"
|
||||
android:title="@string/zen_category_exceptions">
|
||||
<Preference
|
||||
android:key="zen_mode_calls_settings"
|
||||
android:title="@string/zen_mode_calls"
|
||||
android:fragment="com.android.settings.notification.ZenModeCallsSettings" />
|
||||
<Preference
|
||||
android:key="zen_mode_msg_event_reminder_settings"
|
||||
android:title="@string/zen_msg_event_reminder_title"
|
||||
android:fragment="com.android.settings.notification.ZenModeMsgEventReminderSettings" />
|
||||
<!-- What to block (effects) -->
|
||||
<Preference
|
||||
android:key="zen_mode_block_effects_settings"
|
||||
android:title="@string/zen_mode_restrict_notifications_title"
|
||||
android:fragment="com.android.settings.notification.ZenModeRestrictNotificationsSettings"
|
||||
settings:allowDividerAbove="true"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
<!-- DND duration settings -->
|
||||
<com.android.settings.notification.ZenDurationDialogPreference
|
||||
android:key="zen_mode_duration_settings"
|
||||
android:title="@string/zen_mode_duration_settings_title"
|
||||
android:widgetLayout="@null"/>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="zen_mode_settings_category_schedule"
|
||||
android:title="@string/zen_category_schedule">
|
||||
<!-- DND duration settings -->
|
||||
<com.android.settings.notification.ZenDurationDialogPreference
|
||||
android:key="zen_mode_duration_settings"
|
||||
android:title="@string/zen_mode_duration_settings_title"
|
||||
android:widgetLayout="@null"/>
|
||||
|
||||
<!-- Automatic rules -->
|
||||
<Preference
|
||||
android:key="zen_mode_automation_settings"
|
||||
android:title="@string/zen_mode_automation_settings_title"
|
||||
android:fragment="com.android.settings.notification.ZenModeAutomationSettings" />
|
||||
</PreferenceCategory>
|
||||
<!-- Automatic rules -->
|
||||
<Preference
|
||||
android:key="zen_mode_automation_settings"
|
||||
android:title="@string/zen_mode_automation_settings_title"
|
||||
android:fragment="com.android.settings.notification.ZenModeAutomationSettings"/>
|
||||
|
||||
<!-- Turn on DND button -->
|
||||
<!-- Layout preference doesn't obey allowDividerAbove, so put it in a PreferenceCategory -->
|
||||
<PreferenceCategory
|
||||
android:key="zen_mode_settings_button_category">
|
||||
<com.android.settings.applications.LayoutPreference
|
||||
android:key="zen_mode_settings_button_container"
|
||||
android:selectable="false"
|
||||
android:layout="@layout/zen_mode_settings_button" />
|
||||
</PreferenceCategory>
|
||||
<com.android.settings.applications.LayoutPreference
|
||||
android:key="zen_mode_settings_button_container"
|
||||
android:selectable="false"
|
||||
android:layout="@layout/zen_mode_settings_button"
|
||||
settings:allowDividerAbove="true"
|
||||
settings:allowDividerBelow="true"/>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="zen_mode_footer_container">
|
||||
<com.android.settingslib.widget.FooterPreference />
|
||||
</PreferenceCategory>
|
||||
<!-- Footer that shows if user is put into alarms only or total silence mode by an app -->
|
||||
<com.android.settingslib.widget.FooterPreference/>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -18,11 +18,24 @@
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:key="zen_mode_sound_vibration_settings_page"
|
||||
android:title="@string/zen_sound_title" >
|
||||
android:title="@string/zen_category_exceptions" >
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/zen_mode_settings_category"
|
||||
android:key="zen_mode_settings_category_sound_vibration">
|
||||
|
||||
<!-- Calls -->
|
||||
<Preference
|
||||
android:key="zen_mode_calls_settings"
|
||||
android:title="@string/zen_mode_calls_title"
|
||||
android:fragment="com.android.settings.notification.ZenModeCallsSettings" />
|
||||
|
||||
<!-- Messages -->
|
||||
<Preference
|
||||
android:key="zen_mode_messages_settings"
|
||||
android:title="@string/zen_mode_messages_title"
|
||||
android:fragment="com.android.settings.notification.ZenModeMessagesSettings" />
|
||||
|
||||
<!-- Alarms -->
|
||||
<SwitchPreference
|
||||
android:key="zen_mode_alarms"
|
||||
@@ -37,6 +50,18 @@
|
||||
<SwitchPreference
|
||||
android:key="zen_mode_system"
|
||||
android:title="@string/zen_mode_system"/>
|
||||
|
||||
<!-- Reminders -->
|
||||
<SwitchPreference
|
||||
android:key="zen_mode_reminders"
|
||||
android:title="@string/zen_mode_reminders"/>
|
||||
|
||||
<!-- Events -->
|
||||
<SwitchPreference
|
||||
android:key="zen_mode_events"
|
||||
android:title="@string/zen_mode_events"/>
|
||||
|
||||
<!-- TODO: beverlyt, add "Allow apps to override" -->
|
||||
</PreferenceCategory>
|
||||
|
||||
<com.android.settingslib.widget.FooterPreference/>
|
||||
|
||||
@@ -550,7 +550,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
|
||||
|
||||
Drawable icon;
|
||||
if (resolveInfo.getIconResource() == 0) {
|
||||
icon = ContextCompat.getDrawable(getContext(), R.mipmap.ic_accessibility_generic);
|
||||
icon = ContextCompat.getDrawable(getContext(), R.drawable.ic_accessibility_generic);
|
||||
} else {
|
||||
icon = resolveInfo.loadIcon(getPackageManager());
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ public class ShortcutServicePickerFragment extends RadioButtonPickerFragment {
|
||||
public Drawable loadIcon() {
|
||||
final ResolveInfo resolveInfo = mServiceInfo.getResolveInfo();
|
||||
return (resolveInfo.getIconResource() == 0)
|
||||
? getContext().getDrawable(R.mipmap.ic_accessibility_generic)
|
||||
? getContext().getDrawable(R.drawable.ic_accessibility_generic)
|
||||
: resolveInfo.loadIcon(getContext().getPackageManager());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.settings.biometrics.face.FaceEnrollIntroduction;
|
||||
import com.android.settings.biometrics.fingerprint.FingerprintEnrollIntroduction;
|
||||
import com.android.settings.core.InstrumentedActivity;
|
||||
|
||||
/**
|
||||
* Trampoline activity launched by the {@code android.settings.BIOMETRIC_ENROLL} action which
|
||||
* shows the user an appropriate enrollment flow depending on the device's biometric hardware.
|
||||
* This activity must only allow enrollment of biometrics that can be used by
|
||||
* {@link android.hardware.biometrics.BiometricPrompt}.
|
||||
*/
|
||||
public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
|
||||
private static final String SETTINGS_PACKAGE = "com.android.settings";
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
final PackageManager pm = getApplicationContext().getPackageManager();
|
||||
final Intent intent = new Intent();
|
||||
|
||||
// This logic may have to be modified on devices with multiple biometrics.
|
||||
if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
|
||||
intent.setClassName(SETTINGS_PACKAGE, FingerprintEnrollIntroduction.class.getName());
|
||||
} else if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
|
||||
intent.setClassName(SETTINGS_PACKAGE, FaceEnrollIntroduction.class.getName());
|
||||
}
|
||||
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.BIOMETRIC_ENROLL_ACTIVITY;
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
package com.android.settings.biometrics.fingerprint;
|
||||
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.CancellationSignal;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
|
||||
/**
|
||||
* Small helper class to manage text/icon around fingerprint authentication UI.
|
||||
*/
|
||||
public class FingerprintUiHelper extends FingerprintManager.AuthenticationCallback {
|
||||
|
||||
private static final long ERROR_TIMEOUT = 1300;
|
||||
|
||||
private ImageView mIcon;
|
||||
private TextView mErrorTextView;
|
||||
private CancellationSignal mCancellationSignal;
|
||||
private int mUserId;
|
||||
|
||||
private Callback mCallback;
|
||||
private FingerprintManager mFingerprintManager;
|
||||
|
||||
public FingerprintUiHelper(ImageView icon, TextView errorTextView, Callback callback,
|
||||
int userId) {
|
||||
mFingerprintManager = Utils.getFingerprintManagerOrNull(icon.getContext());
|
||||
mIcon = icon;
|
||||
mErrorTextView = errorTextView;
|
||||
mCallback = callback;
|
||||
mUserId = userId;
|
||||
}
|
||||
|
||||
public void startListening() {
|
||||
if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()
|
||||
&& mFingerprintManager.getEnrolledFingerprints(mUserId).size() > 0) {
|
||||
mCancellationSignal = new CancellationSignal();
|
||||
mFingerprintManager.setActiveUser(mUserId);
|
||||
mFingerprintManager.authenticate(
|
||||
null, mCancellationSignal, 0 /* flags */, this, null, mUserId);
|
||||
setFingerprintIconVisibility(true);
|
||||
mIcon.setImageResource(R.drawable.ic_fingerprint);
|
||||
}
|
||||
}
|
||||
|
||||
public void stopListening() {
|
||||
if (mCancellationSignal != null) {
|
||||
mCancellationSignal.cancel();
|
||||
mCancellationSignal = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isListening() {
|
||||
return mCancellationSignal != null && !mCancellationSignal.isCanceled();
|
||||
}
|
||||
|
||||
private void setFingerprintIconVisibility(boolean visible) {
|
||||
mIcon.setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||
mCallback.onFingerprintIconVisibilityChanged(visible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationError(int errMsgId, CharSequence errString) {
|
||||
if (errMsgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
|
||||
// Only happens if we get preempted by another activity. Ignored.
|
||||
return;
|
||||
}
|
||||
showError(errString);
|
||||
setFingerprintIconVisibility(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
|
||||
showError(helpString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationFailed() {
|
||||
showError(mIcon.getResources().getString(
|
||||
R.string.fingerprint_not_recognized));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
|
||||
mIcon.setImageResource(R.drawable.ic_fingerprint_success);
|
||||
mCallback.onAuthenticated();
|
||||
}
|
||||
|
||||
private void showError(CharSequence error) {
|
||||
if (!isListening()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mIcon.setImageResource(R.drawable.ic_fingerprint_error);
|
||||
mErrorTextView.setText(error);
|
||||
mErrorTextView.removeCallbacks(mResetErrorTextRunnable);
|
||||
mErrorTextView.postDelayed(mResetErrorTextRunnable, ERROR_TIMEOUT);
|
||||
}
|
||||
|
||||
private Runnable mResetErrorTextRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mErrorTextView.setText("");
|
||||
mIcon.setImageResource(R.drawable.ic_fingerprint);
|
||||
}
|
||||
};
|
||||
|
||||
public interface Callback {
|
||||
void onAuthenticated();
|
||||
void onFingerprintIconVisibilityChanged(boolean visible);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
package com.android.settings.development;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.IUsbManager;
|
||||
import android.debug.IAdbManager;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemProperties;
|
||||
@@ -42,7 +42,7 @@ public class ClearAdbKeysPreferenceController extends DeveloperOptionsPreference
|
||||
@VisibleForTesting
|
||||
static final String RO_ADB_SECURE_PROPERTY_KEY = "ro.adb.secure";
|
||||
|
||||
private final IUsbManager mUsbManager;
|
||||
private final IAdbManager mAdbManager;
|
||||
private final DevelopmentSettingsDashboardFragment mFragment;
|
||||
|
||||
public ClearAdbKeysPreferenceController(Context context,
|
||||
@@ -50,7 +50,7 @@ public class ClearAdbKeysPreferenceController extends DeveloperOptionsPreference
|
||||
super(context);
|
||||
|
||||
mFragment = fragment;
|
||||
mUsbManager = IUsbManager.Stub.asInterface(ServiceManager.getService(Context.USB_SERVICE));
|
||||
mAdbManager = IAdbManager.Stub.asInterface(ServiceManager.getService(Context.ADB_SERVICE));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -94,7 +94,7 @@ public class ClearAdbKeysPreferenceController extends DeveloperOptionsPreference
|
||||
|
||||
public void onClearAdbKeysConfirmed() {
|
||||
try {
|
||||
mUsbManager.clearUsbDebuggingKeys();
|
||||
mAdbManager.clearDebuggingKeys();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Unable to clear adb keys", e);
|
||||
}
|
||||
|
||||
@@ -458,6 +458,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
controllers.add(new AllowAppsOnExternalPreferenceController(context));
|
||||
controllers.add(new ResizableActivityPreferenceController(context));
|
||||
controllers.add(new FreeformWindowsPreferenceController(context));
|
||||
controllers.add(new SmsAccessRestrictionPreferenceController(context));
|
||||
controllers.add(new ShortcutManagerThrottlingPreferenceController(context));
|
||||
controllers.add(new EnableGnssRawMeasFullTrackingPreferenceController(context));
|
||||
controllers.add(new CbrsDataSwitchPreferenceController(context));
|
||||
@@ -470,7 +471,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
controllers.add(new DefaultLaunchPreferenceController(context, "density"));
|
||||
controllers.add(new DefaultLaunchPreferenceController(context, "background_check"));
|
||||
controllers.add(new DefaultLaunchPreferenceController(context, "inactive_apps"));
|
||||
controllers.add(new AutofillLoggingLevelPreferenceController(context));
|
||||
controllers.add(new AutofillLoggingLevelPreferenceController(context, lifecycle));
|
||||
controllers.add(new AutofillResetOptionsPreferenceController(context));
|
||||
return controllers;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.development;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
// STOPSHIP b/118694572: remove the kill switch once the feature is tested and stable
|
||||
public class SmsAccessRestrictionPreferenceController extends DeveloperOptionsPreferenceController
|
||||
implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
|
||||
|
||||
private static final String SMS_ACCESS_RESTRICTION_ENABLED_KEY
|
||||
= "sms_access_restriction_enabled";
|
||||
|
||||
public SmsAccessRestrictionPreferenceController(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return SMS_ACCESS_RESTRICTION_ENABLED_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
writeSetting((boolean) newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void writeSetting(boolean isEnabled) {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED,
|
||||
isEnabled ? 1 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
final int mode = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, 0);
|
||||
((SwitchPreference) mPreference).setChecked(mode != 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeveloperOptionsSwitchDisabled() {
|
||||
super.onDeveloperOptionsSwitchDisabled();
|
||||
writeSetting(false);
|
||||
((SwitchPreference) mPreference).setChecked(false);
|
||||
}
|
||||
}
|
||||
@@ -27,11 +27,15 @@ import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnDestroy;
|
||||
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
|
||||
|
||||
public final class AutofillLoggingLevelPreferenceController
|
||||
extends DeveloperOptionsPreferenceController
|
||||
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
|
||||
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
|
||||
LifecycleObserver, OnDestroy {
|
||||
|
||||
private static final String TAG = "AutofillLoggingLevelPreferenceController";
|
||||
private static final String AUTOFILL_LOGGING_LEVEL_KEY = "autofill_logging_level";
|
||||
@@ -40,7 +44,7 @@ public final class AutofillLoggingLevelPreferenceController
|
||||
private final String[] mListSummaries;
|
||||
private final AutofillDeveloperSettingsObserver mObserver;
|
||||
|
||||
public AutofillLoggingLevelPreferenceController(Context context) {
|
||||
public AutofillLoggingLevelPreferenceController(Context context, Lifecycle lifecycle) {
|
||||
super(context);
|
||||
|
||||
Resources resources = context.getResources();
|
||||
@@ -48,7 +52,15 @@ public final class AutofillLoggingLevelPreferenceController
|
||||
mListSummaries = resources.getStringArray(R.array.autofill_logging_level_entries);
|
||||
mObserver = new AutofillDeveloperSettingsObserver(mContext, () -> updateOptions());
|
||||
mObserver.register();
|
||||
// TODO: there should be a hook on AbstractPreferenceController where we could unregister it
|
||||
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
mObserver.unregister();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -30,7 +30,7 @@ import androidx.annotation.VisibleForTesting;
|
||||
public class CardDatabaseHelper extends SQLiteOpenHelper {
|
||||
private static final String TAG = "CardDatabaseHelper";
|
||||
private static final String DATABASE_NAME = "homepage_cards.db";
|
||||
private static final int DATABASE_VERSION = 3;
|
||||
private static final int DATABASE_VERSION = 4;
|
||||
|
||||
public static final String CARD_TABLE = "cards";
|
||||
|
||||
@@ -56,7 +56,7 @@ public class CardDatabaseHelper extends SQLiteOpenHelper {
|
||||
String SLICE_URI = "slice_uri";
|
||||
|
||||
/**
|
||||
* Category of the card. The value is between 0 to 3.
|
||||
* Category of the card.
|
||||
*/
|
||||
String CATEGORY = "category";
|
||||
|
||||
@@ -133,11 +133,7 @@ public class CardDatabaseHelper extends SQLiteOpenHelper {
|
||||
CardColumns.SLICE_URI +
|
||||
" TEXT, " +
|
||||
CardColumns.CATEGORY +
|
||||
" INTEGER DEFAULT 0 CHECK (" +
|
||||
CardColumns.CATEGORY +
|
||||
" >= 0 AND " +
|
||||
CardColumns.CATEGORY +
|
||||
" <= 3), " +
|
||||
" INTEGER DEFAULT 0, " +
|
||||
CardColumns.LOCALIZED_TO_LOCALE +
|
||||
" TEXT, " +
|
||||
CardColumns.PACKAGE_NAME +
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.android.settings.intelligence.ContextualCardProto.ContextualCard;
|
||||
import com.android.settings.intelligence.ContextualCardProto.ContextualCardList;
|
||||
import com.android.settings.wifi.WifiSlice;
|
||||
|
||||
import com.google.android.settings.intelligence.libs.contextualcards.ContextualCardCategory;
|
||||
import com.google.android.settings.intelligence.libs.contextualcards.ContextualCardProvider;
|
||||
|
||||
/** Provides dynamic card for SettingsIntelligence. */
|
||||
@@ -40,16 +41,19 @@ public class SettingsContextualCardProvider extends ContextualCardProvider {
|
||||
ContextualCard.newBuilder()
|
||||
.setSliceUri(WifiSlice.WIFI_URI.toString())
|
||||
.setCardName(KEY_WIFI)
|
||||
.setCategory(ContextualCardCategory.IMPORTANT)
|
||||
.build();
|
||||
final ContextualCard batteryInfoCard =
|
||||
ContextualCard.newBuilder()
|
||||
.setSliceUri(BatterySlice.BATTERY_CARD_URI.toSafeString())
|
||||
.setSliceUri(BatterySlice.BATTERY_CARD_URI.toString())
|
||||
.setCardName(BatterySlice.PATH_BATTERY_INFO)
|
||||
.setCategory(ContextualCardCategory.DEFAULT)
|
||||
.build();
|
||||
final ContextualCard connectedDeviceCard =
|
||||
ContextualCard.newBuilder()
|
||||
.setSliceUri(ConnectedDeviceSlice.CONNECTED_DEVICE_URI.toString())
|
||||
.setCardName(ConnectedDeviceSlice.PATH_CONNECTED_DEVICE)
|
||||
.setCategory(ContextualCardCategory.IMPORTANT)
|
||||
.build();
|
||||
final ContextualCardList cards = ContextualCardList.newBuilder()
|
||||
.addCard(wifiCard)
|
||||
|
||||
@@ -1,62 +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.homepage.contextualcards.conditional;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
|
||||
public class AirplaneModeConditionCard implements ConditionalCard {
|
||||
|
||||
private final Context mAppContext;
|
||||
|
||||
public AirplaneModeConditionCard(Context appContext) {
|
||||
mAppContext = appContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return AirplaneModeConditionController.ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getActionText() {
|
||||
return mAppContext.getText(R.string.condition_turn_off);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsConstant() {
|
||||
return MetricsProto.MetricsEvent.SETTINGS_CONDITION_AIRPLANE_MODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIcon() {
|
||||
return mAppContext.getDrawable(R.drawable.ic_airplanemode_active);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTitle() {
|
||||
return mAppContext.getText(R.string.condition_airplane_title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
return mAppContext.getText(R.string.condition_airplane_summary);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,9 @@ import android.content.IntentFilter;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
import com.android.settingslib.WirelessUtils;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -65,6 +68,20 @@ public class AirplaneModeConditionController implements ConditionalCardControlle
|
||||
ConnectivityManager.from(mAppContext).setAirplaneMode(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextualCard buildContextualCard() {
|
||||
return new ConditionalContextualCard.Builder()
|
||||
.setConditionId(ID)
|
||||
.setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_AIRPLANE_MODE)
|
||||
.setActionText(mAppContext.getText(R.string.condition_turn_off))
|
||||
.setName(mAppContext.getPackageName() + "/"
|
||||
+ mAppContext.getText(R.string.condition_airplane_title))
|
||||
.setTitleText(mAppContext.getText(R.string.condition_airplane_title).toString())
|
||||
.setSummaryText(mAppContext.getText(R.string.condition_airplane_summary).toString())
|
||||
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_airplanemode_active))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startMonitoringStateChange() {
|
||||
mAppContext.registerReceiver(mReceiver, AIRPLANE_MODE_FILTER);
|
||||
|
||||
@@ -1,62 +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.homepage.contextualcards.conditional;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
|
||||
public class BackgroundDataConditionCard implements ConditionalCard {
|
||||
|
||||
private final Context mAppContext;
|
||||
|
||||
public BackgroundDataConditionCard(Context appContext) {
|
||||
mAppContext = appContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return BackgroundDataConditionController.ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getActionText() {
|
||||
return mAppContext.getText(R.string.condition_turn_off);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsConstant() {
|
||||
return MetricsProto.MetricsEvent.SETTINGS_CONDITION_BACKGROUND_DATA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIcon() {
|
||||
return mAppContext.getDrawable(R.drawable.ic_data_saver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTitle() {
|
||||
return mAppContext.getText(R.string.condition_bg_data_title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
return mAppContext.getText(R.string.condition_bg_data_summary);
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,10 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.NetworkPolicyManager;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Settings;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -59,6 +62,20 @@ public class BackgroundDataConditionController implements ConditionalCardControl
|
||||
mConditionManager.onConditionChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextualCard buildContextualCard() {
|
||||
return new ConditionalContextualCard.Builder()
|
||||
.setConditionId(ID)
|
||||
.setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_BACKGROUND_DATA)
|
||||
.setActionText(mAppContext.getText(R.string.condition_turn_off))
|
||||
.setName(mAppContext.getPackageName() + "/"
|
||||
+ mAppContext.getText(R.string.condition_bg_data_title))
|
||||
.setTitleText(mAppContext.getText(R.string.condition_bg_data_title).toString())
|
||||
.setSummaryText(mAppContext.getText(R.string.condition_bg_data_summary).toString())
|
||||
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_data_saver))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startMonitoringStateChange() {
|
||||
|
||||
|
||||
@@ -1,62 +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.homepage.contextualcards.conditional;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
|
||||
public class BatterySaverConditionCard implements ConditionalCard {
|
||||
|
||||
private final Context mAppContext;
|
||||
|
||||
public BatterySaverConditionCard(Context appContext) {
|
||||
mAppContext = appContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return BatterySaverConditionController.ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getActionText() {
|
||||
return mAppContext.getText(R.string.condition_turn_off);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsConstant() {
|
||||
return MetricsProto.MetricsEvent.SETTINGS_CONDITION_BATTERY_SAVER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIcon() {
|
||||
return mAppContext.getDrawable(R.drawable.ic_battery_saver_accent_24dp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTitle() {
|
||||
return mAppContext.getText(R.string.condition_battery_title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
return mAppContext.getText(R.string.condition_battery_summary);
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.fuelgauge.BatterySaverReceiver;
|
||||
import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
import com.android.settingslib.fuelgauge.BatterySaverUtils;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -70,6 +71,20 @@ public class BatterySaverConditionController implements ConditionalCardControlle
|
||||
/*needFirstTimeWarning*/ false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextualCard buildContextualCard() {
|
||||
return new ConditionalContextualCard.Builder()
|
||||
.setConditionId(ID)
|
||||
.setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_BATTERY_SAVER)
|
||||
.setActionText(mAppContext.getText(R.string.condition_turn_off))
|
||||
.setName(mAppContext.getPackageName() + "/"
|
||||
+ mAppContext.getText(R.string.condition_battery_title))
|
||||
.setTitleText(mAppContext.getText(R.string.condition_battery_title).toString())
|
||||
.setSummaryText(mAppContext.getText(R.string.condition_battery_summary).toString())
|
||||
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_battery_saver_accent_24dp))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startMonitoringStateChange() {
|
||||
mReceiver.setListening(true);
|
||||
|
||||
@@ -1,62 +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.homepage.contextualcards.conditional;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
|
||||
public class CellularDataConditionCard implements ConditionalCard {
|
||||
|
||||
private final Context mAppContext;
|
||||
|
||||
public CellularDataConditionCard(Context appContext) {
|
||||
mAppContext = appContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return CellularDataConditionController.ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getActionText() {
|
||||
return mAppContext.getText(R.string.condition_turn_on);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsConstant() {
|
||||
return MetricsProto.MetricsEvent.SETTINGS_CONDITION_CELLULAR_DATA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIcon() {
|
||||
return mAppContext.getDrawable(R.drawable.ic_cellular_off);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTitle() {
|
||||
return mAppContext.getText(R.string.condition_cellular_title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
return mAppContext.getText(R.string.condition_cellular_summary);
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,11 @@ import android.content.IntentFilter;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.internal.telephony.TelephonyIntents;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Settings;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -75,6 +78,20 @@ public class CellularDataConditionController implements ConditionalCardControlle
|
||||
mTelephonyManager.setDataEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextualCard buildContextualCard() {
|
||||
return new ConditionalContextualCard.Builder()
|
||||
.setConditionId(ID)
|
||||
.setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_CELLULAR_DATA)
|
||||
.setActionText(mAppContext.getText(R.string.condition_turn_on))
|
||||
.setName(mAppContext.getPackageName() + "/"
|
||||
+ mAppContext.getText(R.string.condition_cellular_title))
|
||||
.setTitleText(mAppContext.getText(R.string.condition_cellular_title).toString())
|
||||
.setSummaryText(mAppContext.getText(R.string.condition_cellular_summary).toString())
|
||||
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_cellular_off))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startMonitoringStateChange() {
|
||||
mAppContext.registerReceiver(mReceiver, DATA_CONNECTION_FILTER);
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -84,24 +83,7 @@ public class ConditionContextualCardController implements ContextualCardControll
|
||||
|
||||
@Override
|
||||
public void onConditionsChanged() {
|
||||
final List<ContextualCard> conditionCards = new ArrayList<>();
|
||||
final List<ConditionalCard> conditionList = mConditionManager.getDisplayableCards();
|
||||
|
||||
for (ConditionalCard condition : conditionList) {
|
||||
final ContextualCard conditionCard =
|
||||
new ConditionalContextualCard.Builder()
|
||||
.setConditionId(condition.getId())
|
||||
.setMetricsConstant(condition.getMetricsConstant())
|
||||
.setActionText(condition.getActionText())
|
||||
.setName(mContext.getPackageName() + "/"
|
||||
+ condition.getTitle().toString())
|
||||
.setTitleText(condition.getTitle().toString())
|
||||
.setSummaryText(condition.getSummary().toString())
|
||||
.setIconDrawable(condition.getIcon())
|
||||
.build();
|
||||
|
||||
conditionCards.add(conditionCard);
|
||||
}
|
||||
final List<ContextualCard> conditionCards = mConditionManager.getDisplayableCards();
|
||||
|
||||
if (mListener != null) {
|
||||
final Map<Integer, List<ContextualCard>> conditionalCards = new ArrayMap<>();
|
||||
|
||||
@@ -22,6 +22,8 @@ import android.util.Log;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -35,8 +37,6 @@ import java.util.concurrent.TimeoutException;
|
||||
public class ConditionManager {
|
||||
private static final String TAG = "ConditionManager";
|
||||
|
||||
@VisibleForTesting
|
||||
final List<ConditionalCard> mCandidates;
|
||||
@VisibleForTesting
|
||||
final List<ConditionalCardController> mCardControllers;
|
||||
|
||||
@@ -51,29 +51,27 @@ public class ConditionManager {
|
||||
public ConditionManager(Context context, ConditionListener listener) {
|
||||
mAppContext = context.getApplicationContext();
|
||||
mExecutorService = Executors.newCachedThreadPool();
|
||||
mCandidates = new ArrayList<>();
|
||||
mCardControllers = new ArrayList<>();
|
||||
mListener = listener;
|
||||
initCandidates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of {@link ConditionalCard}s eligible for display.
|
||||
* Returns a list of {@link ContextualCard}s eligible for display.
|
||||
*/
|
||||
public List<ConditionalCard> getDisplayableCards() {
|
||||
final List<ConditionalCard> cards = new ArrayList<>();
|
||||
final List<Future<ConditionalCard>> displayableCards = new ArrayList<>();
|
||||
public List<ContextualCard> getDisplayableCards() {
|
||||
final List<ContextualCard> cards = new ArrayList<>();
|
||||
final List<Future<ContextualCard>> displayableCards = new ArrayList<>();
|
||||
// Check displayable future
|
||||
for (ConditionalCard card : mCandidates) {
|
||||
final DisplayableChecker future = new DisplayableChecker(
|
||||
card, getController(card.getId()));
|
||||
for (ConditionalCardController card : mCardControllers) {
|
||||
final DisplayableChecker future = new DisplayableChecker(getController(card.getId()));
|
||||
displayableCards.add(mExecutorService.submit(future));
|
||||
}
|
||||
// Collect future and add displayable cards
|
||||
for (Future<ConditionalCard> cardFuture : displayableCards) {
|
||||
for (Future<ContextualCard> cardFuture : displayableCards) {
|
||||
try {
|
||||
final ConditionalCard card = cardFuture.get(DISPLAYABLE_CHECKER_TIMEOUT_MS,
|
||||
TimeUnit.MILLISECONDS);
|
||||
final ContextualCard card = cardFuture.get(
|
||||
DISPLAYABLE_CHECKER_TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||
if (card != null) {
|
||||
cards.add(card);
|
||||
}
|
||||
@@ -142,7 +140,7 @@ public class ConditionManager {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
<T extends ConditionalCardController> T getController(long id) {
|
||||
private <T extends ConditionalCardController> T getController(long id) {
|
||||
for (ConditionalCardController controller : mCardControllers) {
|
||||
if (controller.getId() == id) {
|
||||
return (T) controller;
|
||||
@@ -164,36 +162,22 @@ public class ConditionManager {
|
||||
mCardControllers.add(new RingerVibrateConditionController(mAppContext, this /* manager */));
|
||||
mCardControllers.add(new RingerMutedConditionController(mAppContext, this /* manager */));
|
||||
mCardControllers.add(new WorkModeConditionController(mAppContext, this /* manager */));
|
||||
|
||||
// Initialize ui model later. UI model depends on controller.
|
||||
mCandidates.add(new AirplaneModeConditionCard(mAppContext));
|
||||
mCandidates.add(new BackgroundDataConditionCard(mAppContext));
|
||||
mCandidates.add(new BatterySaverConditionCard(mAppContext));
|
||||
mCandidates.add(new CellularDataConditionCard(mAppContext));
|
||||
mCandidates.add(new DndConditionCard(mAppContext, this /* manager */));
|
||||
mCandidates.add(new HotspotConditionCard(mAppContext, this /* manager */));
|
||||
mCandidates.add(new NightDisplayConditionCard(mAppContext));
|
||||
mCandidates.add(new RingerMutedConditionCard(mAppContext));
|
||||
mCandidates.add(new RingerVibrateConditionCard(mAppContext));
|
||||
mCandidates.add(new WorkModeConditionCard(mAppContext));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns card if controller says it's displayable. Otherwise returns null.
|
||||
*/
|
||||
public static class DisplayableChecker implements Callable<ConditionalCard> {
|
||||
public static class DisplayableChecker implements Callable<ContextualCard> {
|
||||
|
||||
private final ConditionalCard mCard;
|
||||
private final ConditionalCardController mController;
|
||||
|
||||
private DisplayableChecker(ConditionalCard card, ConditionalCardController controller) {
|
||||
mCard = card;
|
||||
private DisplayableChecker(ConditionalCardController controller) {
|
||||
mController = controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConditionalCard call() throws Exception {
|
||||
return mController.isDisplayable() ? mCard : null;
|
||||
public ContextualCard call() throws Exception {
|
||||
return mController.isDisplayable() ? mController.buildContextualCard() : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,48 +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.homepage.contextualcards.conditional;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
/**
|
||||
* UI Model for a conditional card displayed on homepage.
|
||||
*/
|
||||
public interface ConditionalCard {
|
||||
|
||||
/**
|
||||
* A stable ID for this card.
|
||||
*
|
||||
* @see {@link ConditionalCardController#getId()}
|
||||
*/
|
||||
long getId();
|
||||
|
||||
/**
|
||||
* The text display on the card for click action.
|
||||
*/
|
||||
CharSequence getActionText();
|
||||
|
||||
/**
|
||||
* Metrics constant used for logging user interaction.
|
||||
*/
|
||||
int getMetricsConstant();
|
||||
|
||||
Drawable getIcon();
|
||||
|
||||
CharSequence getTitle();
|
||||
|
||||
CharSequence getSummary();
|
||||
}
|
||||
@@ -18,15 +18,15 @@ package com.android.settings.homepage.contextualcards.conditional;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
|
||||
/**
|
||||
* Data controller for a {@link ConditionalCard}.
|
||||
* Data controller for a {@link ConditionalContextualCard}.
|
||||
*/
|
||||
public interface ConditionalCardController {
|
||||
|
||||
/**
|
||||
* A stable ID for this card.
|
||||
*
|
||||
* @see {@link ConditionalCard#getId()}
|
||||
*/
|
||||
long getId();
|
||||
|
||||
@@ -45,6 +45,11 @@ public interface ConditionalCardController {
|
||||
*/
|
||||
void onActionClick();
|
||||
|
||||
/**
|
||||
* Creates a UI model suitable for display, controlled by this controller.
|
||||
*/
|
||||
ContextualCard buildContextualCard();
|
||||
|
||||
void startMonitoringStateChange();
|
||||
|
||||
void stopMonitoringStateChange();
|
||||
|
||||
@@ -22,7 +22,7 @@ import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
* Data class representing a conditional {@link ContextualCard}.
|
||||
*
|
||||
* Use this class to store additional attributes on top of {@link ContextualCard} for
|
||||
* {@link ConditionalCard}.
|
||||
* {@link ConditionalCardController}.
|
||||
*/
|
||||
public class ConditionalContextualCard extends ContextualCard {
|
||||
|
||||
|
||||
@@ -1,64 +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.homepage.contextualcards.conditional;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
|
||||
public class DndConditionCard implements ConditionalCard {
|
||||
|
||||
private final Context mAppContext;
|
||||
private final DndConditionCardController mController;
|
||||
|
||||
public DndConditionCard(Context appContext, ConditionManager manager) {
|
||||
mAppContext = appContext;
|
||||
mController = manager.getController(getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return DndConditionCardController.ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIcon() {
|
||||
return mAppContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTitle() {
|
||||
return mAppContext.getText(R.string.condition_zen_title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
return mController.getSummary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getActionText() {
|
||||
return mAppContext.getText(R.string.condition_turn_off);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsConstant() {
|
||||
return MetricsProto.MetricsEvent.SETTINGS_CONDITION_DND;
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import androidx.annotation.VisibleForTesting;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
import com.android.settings.notification.ZenModeSettings;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -88,6 +89,20 @@ public class DndConditionCardController implements ConditionalCardController {
|
||||
mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextualCard buildContextualCard() {
|
||||
return new ConditionalContextualCard.Builder()
|
||||
.setConditionId(ID)
|
||||
.setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_DND)
|
||||
.setActionText(mAppContext.getText(R.string.condition_turn_off))
|
||||
.setName(mAppContext.getPackageName() + "/"
|
||||
+ mAppContext.getText(R.string.condition_zen_title))
|
||||
.setTitleText(mAppContext.getText(R.string.condition_zen_title).toString())
|
||||
.setSummaryText(getSummary().toString())
|
||||
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
|
||||
.build();
|
||||
}
|
||||
|
||||
public CharSequence getSummary() {
|
||||
final int zen = mNotificationManager.getZenMode();
|
||||
final ZenModeConfig config;
|
||||
|
||||
@@ -1,72 +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.homepage.contextualcards.conditional;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
|
||||
public class HotspotConditionCard implements ConditionalCard {
|
||||
|
||||
private final Context mAppContext;
|
||||
private final ConditionManager mConditionManager;
|
||||
|
||||
public HotspotConditionCard(Context appContext, ConditionManager manager) {
|
||||
mAppContext = appContext;
|
||||
mConditionManager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return HotspotConditionController.ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getActionText() {
|
||||
if (RestrictedLockUtilsInternal.hasBaseUserRestriction(mAppContext,
|
||||
UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.myUserId())) {
|
||||
return null;
|
||||
}
|
||||
return mAppContext.getText(R.string.condition_turn_off);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsConstant() {
|
||||
return MetricsProto.MetricsEvent.SETTINGS_CONDITION_HOTSPOT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIcon() {
|
||||
return mAppContext.getDrawable(R.drawable.ic_hotspot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTitle() {
|
||||
return mAppContext.getText(R.string.condition_hotspot_title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
final HotspotConditionController controller = mConditionManager.getController(getId());
|
||||
return controller.getSummary();
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.TetherSettings;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
|
||||
@@ -87,6 +88,20 @@ public class HotspotConditionController implements ConditionalCardController {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextualCard buildContextualCard() {
|
||||
return new ConditionalContextualCard.Builder()
|
||||
.setConditionId(ID)
|
||||
.setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_HOTSPOT)
|
||||
.setActionText(mAppContext.getText(R.string.condition_turn_off))
|
||||
.setName(mAppContext.getPackageName() + "/"
|
||||
+ mAppContext.getText(R.string.condition_hotspot_title))
|
||||
.setTitleText(mAppContext.getText(R.string.condition_hotspot_title).toString())
|
||||
.setSummaryText(getSummary().toString())
|
||||
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_hotspot))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startMonitoringStateChange() {
|
||||
mAppContext.registerReceiver(mReceiver, WIFI_AP_STATE_FILTER);
|
||||
|
||||
@@ -1,62 +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.homepage.contextualcards.conditional;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
|
||||
public class NightDisplayConditionCard implements ConditionalCard {
|
||||
|
||||
private final Context mAppContext;
|
||||
|
||||
public NightDisplayConditionCard(Context appContext) {
|
||||
mAppContext = appContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return NightDisplayConditionController.ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getActionText() {
|
||||
return mAppContext.getText(R.string.condition_turn_off);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsConstant() {
|
||||
return MetricsProto.MetricsEvent.SETTINGS_CONDITION_NIGHT_DISPLAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIcon() {
|
||||
return mAppContext.getDrawable(R.drawable.ic_settings_night_display);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTitle() {
|
||||
return mAppContext.getText(R.string.condition_night_display_title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
return mAppContext.getText(R.string.condition_night_display_summary);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.display.NightDisplaySettings;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -30,11 +31,13 @@ public class NightDisplayConditionController implements ConditionalCardControlle
|
||||
ColorDisplayController.Callback {
|
||||
static final int ID = Objects.hash("NightDisplayConditionController");
|
||||
|
||||
private final Context mAppContext;
|
||||
private final ConditionManager mConditionManager;
|
||||
private final ColorDisplayController mController;
|
||||
|
||||
public NightDisplayConditionController(Context appContext, ConditionManager manager) {
|
||||
mController = new ColorDisplayController(appContext);
|
||||
mAppContext = appContext;
|
||||
mConditionManager = manager;
|
||||
}
|
||||
|
||||
@@ -62,6 +65,22 @@ public class NightDisplayConditionController implements ConditionalCardControlle
|
||||
mController.setActivated(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextualCard buildContextualCard() {
|
||||
return new ConditionalContextualCard.Builder()
|
||||
.setConditionId(ID)
|
||||
.setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_NIGHT_DISPLAY)
|
||||
.setActionText(mAppContext.getText(R.string.condition_turn_off))
|
||||
.setName(mAppContext.getPackageName() + "/"
|
||||
+ mAppContext.getText(R.string.condition_night_display_title))
|
||||
.setTitleText(mAppContext.getText(
|
||||
R.string.condition_night_display_title).toString())
|
||||
.setSummaryText(
|
||||
mAppContext.getText(R.string.condition_night_display_summary).toString())
|
||||
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_settings_night_display))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startMonitoringStateChange() {
|
||||
mController.setListener(this);
|
||||
|
||||
@@ -1,62 +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.homepage.contextualcards.conditional;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
|
||||
public class RingerMutedConditionCard implements ConditionalCard {
|
||||
|
||||
private final Context mAppContext;
|
||||
|
||||
public RingerMutedConditionCard(Context appContext) {
|
||||
mAppContext = appContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return RingerMutedConditionController.ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getActionText() {
|
||||
return mAppContext.getText(R.string.condition_device_muted_action_turn_on_sound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsConstant() {
|
||||
return MetricsProto.MetricsEvent.SETTINGS_CONDITION_DEVICE_MUTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIcon() {
|
||||
return mAppContext.getDrawable(R.drawable.ic_notifications_off_24dp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTitle() {
|
||||
return mAppContext.getText(R.string.condition_device_muted_title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
return mAppContext.getText(R.string.condition_device_muted_summary);
|
||||
}
|
||||
}
|
||||
@@ -23,15 +23,21 @@ import android.content.Context;
|
||||
import android.media.AudioManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class RingerMutedConditionController extends AbnormalRingerConditionController {
|
||||
static final int ID = Objects.hash("RingerMutedConditionController");
|
||||
|
||||
private final NotificationManager mNotificationManager;
|
||||
private final Context mAppContext;
|
||||
|
||||
public RingerMutedConditionController(Context appContext, ConditionManager conditionManager) {
|
||||
super(appContext, conditionManager);
|
||||
mAppContext = appContext;
|
||||
mNotificationManager =
|
||||
(NotificationManager) appContext.getSystemService(NOTIFICATION_SERVICE);
|
||||
}
|
||||
@@ -52,4 +58,20 @@ public class RingerMutedConditionController extends AbnormalRingerConditionContr
|
||||
mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT;
|
||||
return isSilent && !zenModeEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextualCard buildContextualCard() {
|
||||
return new ConditionalContextualCard.Builder()
|
||||
.setConditionId(ID)
|
||||
.setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_DEVICE_MUTED)
|
||||
.setActionText(
|
||||
mAppContext.getText(R.string.condition_device_muted_action_turn_on_sound))
|
||||
.setName(mAppContext.getPackageName() + "/"
|
||||
+ mAppContext.getText(R.string.condition_device_muted_title))
|
||||
.setTitleText(mAppContext.getText(R.string.condition_device_muted_title).toString())
|
||||
.setSummaryText(
|
||||
mAppContext.getText(R.string.condition_device_muted_summary).toString())
|
||||
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_notifications_off_24dp))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,62 +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.homepage.contextualcards.conditional;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
|
||||
public class RingerVibrateConditionCard implements ConditionalCard {
|
||||
|
||||
private final Context mAppContext;
|
||||
|
||||
public RingerVibrateConditionCard(Context appContext) {
|
||||
mAppContext = appContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return RingerVibrateConditionController.ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getActionText() {
|
||||
return mAppContext.getText(R.string.condition_device_muted_action_turn_on_sound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsConstant() {
|
||||
return MetricsProto.MetricsEvent.SETTINGS_CONDITION_DEVICE_VIBRATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIcon() {
|
||||
return mAppContext.getDrawable(R.drawable.ic_volume_ringer_vibrate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTitle() {
|
||||
return mAppContext.getText(R.string.condition_device_vibrate_title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
return mAppContext.getText(R.string.condition_device_vibrate_summary);
|
||||
}
|
||||
}
|
||||
@@ -19,13 +19,20 @@ package com.android.settings.homepage.contextualcards.conditional;
|
||||
import android.content.Context;
|
||||
import android.media.AudioManager;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class RingerVibrateConditionController extends AbnormalRingerConditionController {
|
||||
static final int ID = Objects.hash("RingerVibrateConditionController");
|
||||
|
||||
private final Context mAppContext;
|
||||
|
||||
public RingerVibrateConditionController(Context appContext, ConditionManager conditionManager) {
|
||||
super(appContext, conditionManager);
|
||||
mAppContext = appContext;
|
||||
|
||||
}
|
||||
|
||||
@@ -38,4 +45,21 @@ public class RingerVibrateConditionController extends AbnormalRingerConditionCon
|
||||
public boolean isDisplayable() {
|
||||
return mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextualCard buildContextualCard() {
|
||||
return new ConditionalContextualCard.Builder()
|
||||
.setConditionId(ID)
|
||||
.setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_DEVICE_VIBRATE)
|
||||
.setActionText(
|
||||
mAppContext.getText(R.string.condition_device_muted_action_turn_on_sound))
|
||||
.setName(mAppContext.getPackageName() + "/"
|
||||
+ mAppContext.getText(R.string.condition_device_vibrate_title))
|
||||
.setTitleText(
|
||||
mAppContext.getText(R.string.condition_device_vibrate_title).toString())
|
||||
.setSummaryText(
|
||||
mAppContext.getText(R.string.condition_device_vibrate_summary).toString())
|
||||
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_volume_ringer_vibrate))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +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.homepage.contextualcards.conditional;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
|
||||
public class WorkModeConditionCard implements ConditionalCard {
|
||||
|
||||
private final Context mAppContext;
|
||||
|
||||
public WorkModeConditionCard(Context appContext) {
|
||||
mAppContext = appContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return WorkModeConditionController.ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getActionText() {
|
||||
return mAppContext.getText(R.string.condition_turn_on);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsConstant() {
|
||||
return MetricsProto.MetricsEvent.SETTINGS_CONDITION_WORK_MODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIcon() {
|
||||
return mAppContext.getDrawable(R.drawable.ic_signal_workmode_enable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTitle() {
|
||||
return mAppContext.getText(R.string.condition_work_title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
return mAppContext.getText(R.string.condition_work_summary);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,7 +25,10 @@ import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Settings;
|
||||
import com.android.settings.homepage.contextualcards.ContextualCard;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -79,6 +82,20 @@ public class WorkModeConditionController implements ConditionalCardController {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextualCard buildContextualCard() {
|
||||
return new ConditionalContextualCard.Builder()
|
||||
.setConditionId(ID)
|
||||
.setMetricsConstant(MetricsProto.MetricsEvent.SETTINGS_CONDITION_WORK_MODE)
|
||||
.setActionText(mAppContext.getText(R.string.condition_turn_on))
|
||||
.setName(mAppContext.getPackageName() + "/"
|
||||
+ mAppContext.getText(R.string.condition_work_title))
|
||||
.setTitleText(mAppContext.getText(R.string.condition_work_title).toString())
|
||||
.setSummaryText(mAppContext.getText(R.string.condition_work_summary).toString())
|
||||
.setIconDrawable(mAppContext.getDrawable(R.drawable.ic_signal_workmode_enable))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startMonitoringStateChange() {
|
||||
mAppContext.registerReceiver(mReceiver, FILTER);
|
||||
|
||||
@@ -95,8 +95,6 @@ public class ConnectedDeviceSlice implements CustomSliceable {
|
||||
private static final Comparator<CachedBluetoothDevice> COMPARATOR
|
||||
= Comparator.naturalOrder();
|
||||
|
||||
private static final int DEFAULT_EXPANDED_ROW_COUNT = 4;
|
||||
|
||||
private static final String TAG = "ConnectedDeviceSlice";
|
||||
|
||||
private final Context mContext;
|
||||
@@ -162,13 +160,6 @@ public class ConnectedDeviceSlice implements CustomSliceable {
|
||||
for (ListBuilder.RowBuilder rowBuilder : rows) {
|
||||
listBuilder.addRow(rowBuilder);
|
||||
}
|
||||
|
||||
// Only show "see more" button when the number of data row is more than or equal to 4.
|
||||
// TODO(b/118465996): SHOW MORE button won't work properly when having two data rows
|
||||
if (rows.size() >= DEFAULT_EXPANDED_ROW_COUNT) {
|
||||
listBuilder.setSeeMoreAction(primaryActionIntent);
|
||||
}
|
||||
|
||||
return listBuilder.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ public class AppLocationPermissionPreferenceController extends
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return Settings.Global.getInt(mContext.getContentResolver(),
|
||||
android.provider.Settings.Global.LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED, 1)
|
||||
== 1;
|
||||
Settings.Global.LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED, 1) == 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ public class CarrierPreferenceController extends BasePreferenceController {
|
||||
|
||||
public CarrierPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
mCarrierConfigManager = new CarrierConfigManager(context);
|
||||
mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
}
|
||||
|
||||
@@ -1,57 +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.network.telephony;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
/**
|
||||
* List of Phone-specific settings screens.
|
||||
*/
|
||||
public class CdmaOptions {
|
||||
private static final String LOG_TAG = "CdmaOptions";
|
||||
|
||||
private static final String BUTTON_CDMA_SYSTEM_SELECT_KEY = "cdma_system_select_key";
|
||||
private static final String BUTTON_CDMA_SUBSCRIPTION_KEY = "cdma_subscription_key";
|
||||
|
||||
private PreferenceFragmentCompat mPrefFragment;
|
||||
|
||||
public CdmaOptions(PreferenceFragmentCompat prefFragment, PreferenceScreen prefScreen,
|
||||
int subId) {
|
||||
mPrefFragment = prefFragment;
|
||||
}
|
||||
|
||||
public boolean preferenceTreeClick(Preference preference) {
|
||||
//TODO(b/114749736): handle it in preferenceController and remove this file
|
||||
if (preference.getKey().equals(BUTTON_CDMA_SYSTEM_SELECT_KEY)) {
|
||||
log("preferenceTreeClick: return BUTTON_CDMA_ROAMING_KEY true");
|
||||
return true;
|
||||
}
|
||||
if (preference.getKey().equals(BUTTON_CDMA_SUBSCRIPTION_KEY)) {
|
||||
log("preferenceTreeClick: return CDMA_SUBSCRIPTION_KEY true");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void log(String s) {
|
||||
android.util.Log.d(LOG_TAG, s);
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,8 @@ public class EnabledNetworkModePreferenceController extends BasePreferenceContro
|
||||
private PersistableBundle mPersistableBundle;
|
||||
private int mSubId;
|
||||
private boolean mIsGlobalCdma;
|
||||
private boolean mShow4GForLTE;
|
||||
@VisibleForTesting
|
||||
boolean mShow4GForLTE;
|
||||
|
||||
public EnabledNetworkModePreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
@@ -111,12 +112,10 @@ public class EnabledNetworkModePreferenceController extends BasePreferenceContro
|
||||
mTelephonyManager.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE;
|
||||
mIsGlobalCdma = isLteOnCdma
|
||||
&& mPersistableBundle.getBoolean(CarrierConfigManager.KEY_SHOW_CDMA_CHOICES_BOOL);
|
||||
initShow4GForLTE();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void initShow4GForLTE() {
|
||||
mShow4GForLTE = MobileNetworkUtils.isShow4GForLTE(mContext);
|
||||
mShow4GForLTE = mPersistableBundle != null
|
||||
? mPersistableBundle.getBoolean(
|
||||
CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL)
|
||||
: false;
|
||||
}
|
||||
|
||||
private int getPreferredNetworkMode() {
|
||||
|
||||
@@ -59,6 +59,7 @@ public class MobileDataPreferenceController extends TogglePreferenceController
|
||||
|
||||
public MobileDataPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
|
||||
mDataContentObserver = new DataContentObserver(new Handler(Looper.getMainLooper()));
|
||||
mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
|
||||
@@ -82,7 +82,7 @@ public class MobileNetworkUtils {
|
||||
* Returns true if Wifi calling is enabled for at least one phone.
|
||||
*/
|
||||
public static boolean isWifiCallingEnabled(Context context) {
|
||||
int phoneCount = TelephonyManager.from(context).getPhoneCount();
|
||||
int phoneCount = context.getSystemService(TelephonyManager.class).getPhoneCount();
|
||||
for (int i = 0; i < phoneCount; i++) {
|
||||
if (isWifiCallingEnabled(context, i)) {
|
||||
return true;
|
||||
@@ -218,7 +218,7 @@ public class MobileNetworkUtils {
|
||||
*/
|
||||
public static void setMobileDataEnabled(Context context, int subId, boolean enabled,
|
||||
boolean disableOtherSubscriptions) {
|
||||
final TelephonyManager telephonyManager = TelephonyManager.from(context)
|
||||
final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
|
||||
.createForSubscriptionId(subId);
|
||||
final SubscriptionManager subscriptionManager = context.getSystemService(
|
||||
SubscriptionManager.class);
|
||||
@@ -230,7 +230,7 @@ public class MobileNetworkUtils {
|
||||
if (subInfoList != null) {
|
||||
for (SubscriptionInfo subInfo : subInfoList) {
|
||||
if (subInfo.getSubscriptionId() != subId) {
|
||||
TelephonyManager.from(context).createForSubscriptionId(
|
||||
context.getSystemService(TelephonyManager.class).createForSubscriptionId(
|
||||
subInfo.getSubscriptionId()).setDataEnabled(false);
|
||||
}
|
||||
}
|
||||
@@ -245,7 +245,7 @@ public class MobileNetworkUtils {
|
||||
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
return false;
|
||||
}
|
||||
final TelephonyManager telephonyManager = TelephonyManager.from(context)
|
||||
final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
|
||||
.createForSubscriptionId(subId);
|
||||
final PersistableBundle carrierConfig = context.getSystemService(
|
||||
CarrierConfigManager.class).getConfigForSubId(subId);
|
||||
@@ -307,7 +307,7 @@ public class MobileNetworkUtils {
|
||||
}
|
||||
|
||||
private static boolean isGsmBasicOptions(Context context, int subId) {
|
||||
final TelephonyManager telephonyManager = TelephonyManager.from(context)
|
||||
final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
|
||||
.createForSubscriptionId(subId);
|
||||
final PersistableBundle carrierConfig = context.getSystemService(
|
||||
CarrierConfigManager.class).getConfigForSubId(subId);
|
||||
@@ -329,7 +329,7 @@ public class MobileNetworkUtils {
|
||||
* settings
|
||||
*/
|
||||
public static boolean isWorldMode(Context context, int subId) {
|
||||
final TelephonyManager telephonyManager = TelephonyManager.from(context)
|
||||
final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
|
||||
.createForSubscriptionId(subId);
|
||||
boolean worldModeOn = false;
|
||||
final String configString = context.getString(R.string.config_world_mode);
|
||||
@@ -386,25 +386,12 @@ public class MobileNetworkUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isShow4GForLTE(Context context) {
|
||||
//TODO(b/117882862): move this to framework
|
||||
try {
|
||||
Context con = context.createPackageContext("com.android.systemui", 0);
|
||||
int id = con.getResources().getIdentifier("config_show4GForLTE",
|
||||
"bool", "com.android.systemui");
|
||||
return con.getResources().getBoolean(id);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(TAG, "NameNotFoundException for show4GFotLTE");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if Tdscdma is supported in current subscription
|
||||
*/
|
||||
public static boolean isTdscdmaSupported(Context context, int subId) {
|
||||
return isTdscdmaSupported(context,
|
||||
TelephonyManager.from(context).createForSubscriptionId(subId));
|
||||
context.getSystemService(TelephonyManager.class).createForSubscriptionId(subId));
|
||||
}
|
||||
|
||||
//TODO(b/117651939): move it to telephony
|
||||
|
||||
@@ -59,6 +59,7 @@ public class RoamingPreferenceController extends TogglePreferenceController impl
|
||||
|
||||
public RoamingPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
|
||||
mDataContentObserver = new DataContentObserver(new Handler(Looper.getMainLooper()));
|
||||
mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
@@ -48,6 +49,7 @@ public abstract class CdmaBasePreferenceController extends BasePreferenceControl
|
||||
|
||||
public CdmaBasePreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
mDataContentObserver = new DataContentObserver(new Handler(Looper.getMainLooper()));
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ import android.os.UserManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceGroup;
|
||||
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
@@ -83,24 +82,6 @@ public abstract class NotificationPreferenceController extends AbstractPreferenc
|
||||
return true;
|
||||
}
|
||||
|
||||
// finds the preference recursively and removes it from its parent
|
||||
private void findAndRemovePreference(PreferenceGroup prefGroup, String key) {
|
||||
final int preferenceCount = prefGroup.getPreferenceCount();
|
||||
for (int i = preferenceCount - 1; i >= 0; i--) {
|
||||
final Preference preference = prefGroup.getPreference(i);
|
||||
final String curKey = preference.getKey();
|
||||
|
||||
if (curKey != null && curKey.equals(key)) {
|
||||
mPreference = preference;
|
||||
prefGroup.removePreference(preference);
|
||||
}
|
||||
|
||||
if (preference instanceof PreferenceGroup) {
|
||||
findAndRemovePreference((PreferenceGroup) preference, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void onResume(NotificationBackend.AppRow appRow,
|
||||
@Nullable NotificationChannel channel, @Nullable NotificationChannelGroup group,
|
||||
RestrictedLockUtils.EnforcedAdmin admin) {
|
||||
|
||||
@@ -21,19 +21,20 @@ import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
public class ZenModeAlarmsPreferenceController extends
|
||||
AbstractZenModePreferenceController implements Preference.OnPreferenceChangeListener {
|
||||
|
||||
protected static final String KEY = "zen_mode_alarms";
|
||||
private final String KEY;
|
||||
|
||||
public ZenModeAlarmsPreferenceController(Context context, Lifecycle lifecycle) {
|
||||
super(context, KEY, lifecycle);
|
||||
public ZenModeAlarmsPreferenceController(Context context, Lifecycle lifecycle, String key) {
|
||||
super(context, key, lifecycle);
|
||||
KEY = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.notification;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
public class ZenModeBehaviorCallsPreferenceController extends
|
||||
AbstractZenModePreferenceController implements PreferenceControllerMixin {
|
||||
|
||||
protected static final String KEY_BEHAVIOR_SETTINGS = "zen_mode_calls_settings";
|
||||
private final ZenModeSettings.SummaryBuilder mSummaryBuilder;
|
||||
|
||||
public ZenModeBehaviorCallsPreferenceController(Context context, Lifecycle lifecycle) {
|
||||
super(context, KEY_BEHAVIOR_SETTINGS, lifecycle);
|
||||
mSummaryBuilder = new ZenModeSettings.SummaryBuilder(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_BEHAVIOR_SETTINGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
|
||||
preference.setSummary(mSummaryBuilder.getCallsSettingSummary(getPolicy()));
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.notification;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
public class ZenModeBehaviorMsgEventReminderPreferenceController extends
|
||||
AbstractZenModePreferenceController implements PreferenceControllerMixin {
|
||||
|
||||
protected static final String KEY_BEHAVIOR_SETTINGS = "zen_mode_msg_event_reminder_settings";
|
||||
private final ZenModeSettings.SummaryBuilder mSummaryBuilder;
|
||||
|
||||
public ZenModeBehaviorMsgEventReminderPreferenceController(Context context,
|
||||
Lifecycle lifecycle) {
|
||||
super(context, KEY_BEHAVIOR_SETTINGS, lifecycle);
|
||||
mSummaryBuilder = new ZenModeSettings.SummaryBuilder(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_BEHAVIOR_SETTINGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
|
||||
preference.setSummary(mSummaryBuilder.getMsgEventReminderSettingSummary(getPolicy()));
|
||||
}
|
||||
}
|
||||
@@ -1,53 +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.notification;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
public class ZenModeBehaviorSoundPreferenceController extends
|
||||
AbstractZenModePreferenceController implements PreferenceControllerMixin {
|
||||
|
||||
protected static final String KEY_BEHAVIOR_SETTINGS = "zen_sound_vibration_settings";
|
||||
private final ZenModeSettings.SummaryBuilder mSummaryBuilder;
|
||||
|
||||
public ZenModeBehaviorSoundPreferenceController(Context context, Lifecycle lifecycle) {
|
||||
super(context, KEY_BEHAVIOR_SETTINGS, lifecycle);
|
||||
mSummaryBuilder = new ZenModeSettings.SummaryBuilder(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_BEHAVIOR_SETTINGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
|
||||
preference.setSummary(mSummaryBuilder.getSoundSettingSummary(getPolicy()));
|
||||
}
|
||||
}
|
||||
@@ -16,36 +16,29 @@
|
||||
|
||||
package com.android.settings.notification;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
public class ZenModeCallsPreferenceController extends AbstractZenModePreferenceController implements
|
||||
Preference.OnPreferenceChangeListener {
|
||||
import androidx.preference.Preference;
|
||||
|
||||
protected static final String KEY = "zen_mode_calls";
|
||||
private final ZenModeBackend mBackend;
|
||||
private ListPreference mPreference;
|
||||
private final String[] mListValues;
|
||||
public class ZenModeCallsPreferenceController extends
|
||||
AbstractZenModePreferenceController implements PreferenceControllerMixin {
|
||||
|
||||
public ZenModeCallsPreferenceController(Context context, Lifecycle lifecycle) {
|
||||
super(context, KEY, lifecycle);
|
||||
mBackend = ZenModeBackend.getInstance(context);
|
||||
mListValues = context.getResources().getStringArray(R.array.zen_mode_contacts_values);
|
||||
private final String KEY_BEHAVIOR_SETTINGS;
|
||||
private final ZenModeSettings.SummaryBuilder mSummaryBuilder;
|
||||
|
||||
public ZenModeCallsPreferenceController(Context context, Lifecycle lifecycle,
|
||||
String key) {
|
||||
super(context, key, lifecycle);
|
||||
KEY_BEHAVIOR_SETTINGS = key;
|
||||
mSummaryBuilder = new ZenModeSettings.SummaryBuilder(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY;
|
||||
return KEY_BEHAVIOR_SETTINGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,55 +46,10 @@ public class ZenModeCallsPreferenceController extends AbstractZenModePreferenceC
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = (ListPreference) screen.findPreference(KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
updateFromContactsValue(preference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object selectedContactsFrom) {
|
||||
mBackend.saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS,
|
||||
ZenModeBackend.getSettingFromPrefKey(selectedContactsFrom.toString()));
|
||||
updateFromContactsValue(preference);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateFromContactsValue(Preference preference) {
|
||||
mPreference = (ListPreference) preference;
|
||||
switch (getZenMode()) {
|
||||
case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
|
||||
case Settings.Global.ZEN_MODE_ALARMS:
|
||||
mPreference.setEnabled(false);
|
||||
mPreference.setValue(ZenModeBackend.ZEN_MODE_FROM_NONE);
|
||||
mPreference.setSummary(mBackend.getContactsSummary(ZenModeBackend.SOURCE_NONE));
|
||||
break;
|
||||
default:
|
||||
preference.setEnabled(true);
|
||||
preference.setSummary(mBackend.getContactsSummary(
|
||||
NotificationManager.Policy.PRIORITY_CATEGORY_CALLS));
|
||||
|
||||
final String currentVal = ZenModeBackend.getKeyFromSetting(
|
||||
mBackend.getPriorityCallSenders());
|
||||
mPreference.setValue(mListValues[getIndexOfSendersValue(currentVal)]);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected int getIndexOfSendersValue(String currentVal) {
|
||||
int index = 3; // defaults to "none" based on R.array.zen_mode_contacts_values
|
||||
for (int i = 0; i < mListValues.length; i++) {
|
||||
if (TextUtils.equals(currentVal, mListValues[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
preference.setSummary(mSummaryBuilder.getCallsSettingSummary(getPolicy()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ZenModeCallsSettings extends ZenModeSettingsBase implements Indexab
|
||||
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
|
||||
Lifecycle lifecycle) {
|
||||
List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new ZenModeCallsPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModePriorityCallsPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModeStarredContactsPreferenceController(context, lifecycle,
|
||||
PRIORITY_CATEGORY_CALLS, "zen_mode_starred_contacts_callers"));
|
||||
controllers.add(new ZenModeRepeatCallersPreferenceController(context, lifecycle,
|
||||
|
||||
@@ -1,31 +1,38 @@
|
||||
/*
|
||||
* 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.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
public class ZenModeMessagesPreferenceController extends AbstractZenModePreferenceController
|
||||
implements Preference.OnPreferenceChangeListener {
|
||||
import androidx.preference.Preference;
|
||||
|
||||
protected static final String KEY = "zen_mode_messages";
|
||||
public class ZenModeMessagesPreferenceController extends
|
||||
AbstractZenModePreferenceController implements PreferenceControllerMixin {
|
||||
|
||||
private final ZenModeBackend mBackend;
|
||||
private ListPreference mPreference;
|
||||
private final String[] mListValues;
|
||||
private final String KEY;
|
||||
private final ZenModeSettings.SummaryBuilder mSummaryBuilder;
|
||||
|
||||
public ZenModeMessagesPreferenceController(Context context, Lifecycle lifecycle) {
|
||||
super(context, KEY, lifecycle);
|
||||
mBackend = ZenModeBackend.getInstance(context);
|
||||
mListValues = context.getResources().getStringArray(R.array.zen_mode_contacts_values);
|
||||
public ZenModeMessagesPreferenceController(Context context, Lifecycle lifecycle, String key) {
|
||||
super(context, key, lifecycle);
|
||||
KEY = key;
|
||||
mSummaryBuilder = new ZenModeSettings.SummaryBuilder(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -38,55 +45,9 @@ public class ZenModeMessagesPreferenceController extends AbstractZenModePreferen
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = (ListPreference) screen.findPreference(KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
updateFromContactsValue(preference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object selectedContactsFrom) {
|
||||
mBackend.saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES,
|
||||
ZenModeBackend.getSettingFromPrefKey(selectedContactsFrom.toString()));
|
||||
updateFromContactsValue(preference);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateFromContactsValue(Preference preference) {
|
||||
mPreference = (ListPreference) preference;
|
||||
switch (getZenMode()) {
|
||||
case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
|
||||
case Settings.Global.ZEN_MODE_ALARMS:
|
||||
mPreference.setEnabled(false);
|
||||
mPreference.setValue(ZenModeBackend.ZEN_MODE_FROM_NONE);
|
||||
mPreference.setSummary(mBackend.getContactsSummary(ZenModeBackend.SOURCE_NONE));
|
||||
break;
|
||||
default:
|
||||
preference.setEnabled(true);
|
||||
preference.setSummary(mBackend.getContactsSummary(
|
||||
NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES));
|
||||
|
||||
final String currentVal = ZenModeBackend.getKeyFromSetting(
|
||||
mBackend.getPriorityMessageSenders());
|
||||
mPreference.setValue(mListValues[getIndexOfSendersValue(currentVal)]);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected int getIndexOfSendersValue(String currentVal) {
|
||||
int index = 3; // defaults to "none" based on R.array.zen_mode_contacts_values
|
||||
for (int i = 0; i < mListValues.length; i++) {
|
||||
if (TextUtils.equals(currentVal, mListValues[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
// TODO: (b/111475013 - beverlyt) set messages summary
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@SearchIndexable
|
||||
public class ZenModeMsgEventReminderSettings extends ZenModeSettingsBase implements Indexable {
|
||||
public class ZenModeMessagesSettings extends ZenModeSettingsBase implements Indexable {
|
||||
|
||||
@Override
|
||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
@@ -43,19 +43,17 @@ public class ZenModeMsgEventReminderSettings extends ZenModeSettingsBase impleme
|
||||
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
|
||||
Lifecycle lifecycle) {
|
||||
List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new ZenModeEventsPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModeRemindersPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModeMessagesPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModePriorityMessagesPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModeStarredContactsPreferenceController(context, lifecycle,
|
||||
PRIORITY_CATEGORY_MESSAGES, "zen_mode_starred_contacts_messages"));
|
||||
controllers.add(new ZenModeBehaviorFooterPreferenceController(context, lifecycle,
|
||||
R.string.zen_msg_event_reminder_footer));
|
||||
controllers.add(new ZenModeBehaviorFooterPreferenceController(
|
||||
context, lifecycle, R.string.zen_mode_messages_footer));
|
||||
return controllers;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.zen_mode_msg_event_reminder_settings;
|
||||
return R.xml.zen_mode_messages_settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,7 +64,7 @@ public class ZenModeMsgEventReminderSettings extends ZenModeSettingsBase impleme
|
||||
/**
|
||||
* For Search.
|
||||
*/
|
||||
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider() {
|
||||
|
||||
@Override
|
||||
@@ -75,14 +73,15 @@ public class ZenModeMsgEventReminderSettings extends ZenModeSettingsBase impleme
|
||||
final ArrayList<SearchIndexableResource> result = new ArrayList<>();
|
||||
|
||||
final SearchIndexableResource sir = new SearchIndexableResource(context);
|
||||
sir.xmlResId = R.xml.zen_mode_msg_event_reminder_settings;
|
||||
sir.xmlResId = R.xml.zen_mode_messages_settings;
|
||||
result.add(sir);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
return buildPreferenceControllers(context, null);
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public List<AbstractPreferenceController> createPreferenceControllers(
|
||||
Context context) {
|
||||
return buildPreferenceControllers(context, null);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
public class ZenModePriorityCallsPreferenceController extends AbstractZenModePreferenceController
|
||||
implements Preference.OnPreferenceChangeListener {
|
||||
|
||||
protected static final String KEY = "zen_mode_calls";
|
||||
private final ZenModeBackend mBackend;
|
||||
private ListPreference mPreference;
|
||||
private final String[] mListValues;
|
||||
|
||||
public ZenModePriorityCallsPreferenceController(Context context, Lifecycle lifecycle) {
|
||||
super(context, KEY, lifecycle);
|
||||
mBackend = ZenModeBackend.getInstance(context);
|
||||
mListValues = context.getResources().getStringArray(R.array.zen_mode_contacts_values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = (ListPreference) screen.findPreference(KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
updateFromContactsValue(preference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object selectedContactsFrom) {
|
||||
mBackend.saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS,
|
||||
ZenModeBackend.getSettingFromPrefKey(selectedContactsFrom.toString()));
|
||||
updateFromContactsValue(preference);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateFromContactsValue(Preference preference) {
|
||||
mPreference = (ListPreference) preference;
|
||||
switch (getZenMode()) {
|
||||
case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
|
||||
case Settings.Global.ZEN_MODE_ALARMS:
|
||||
mPreference.setEnabled(false);
|
||||
mPreference.setValue(ZenModeBackend.ZEN_MODE_FROM_NONE);
|
||||
mPreference.setSummary(mBackend.getContactsSummary(ZenModeBackend.SOURCE_NONE));
|
||||
break;
|
||||
default:
|
||||
preference.setEnabled(true);
|
||||
preference.setSummary(mBackend.getContactsSummary(
|
||||
NotificationManager.Policy.PRIORITY_CATEGORY_CALLS));
|
||||
|
||||
final String currentVal = ZenModeBackend.getKeyFromSetting(
|
||||
mBackend.getPriorityCallSenders());
|
||||
mPreference.setValue(mListValues[getIndexOfSendersValue(currentVal)]);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected int getIndexOfSendersValue(String currentVal) {
|
||||
int index = 3; // defaults to "none" based on R.array.zen_mode_contacts_values
|
||||
for (int i = 0; i < mListValues.length; i++) {
|
||||
if (TextUtils.equals(currentVal, mListValues[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
public class ZenModePriorityMessagesPreferenceController extends AbstractZenModePreferenceController
|
||||
implements Preference.OnPreferenceChangeListener {
|
||||
|
||||
protected static final String KEY = "zen_mode_messages";
|
||||
private final ZenModeBackend mBackend;
|
||||
private ListPreference mPreference;
|
||||
private final String[] mListValues;
|
||||
|
||||
public ZenModePriorityMessagesPreferenceController(Context context, Lifecycle lifecycle) {
|
||||
super(context, KEY, lifecycle);
|
||||
mBackend = ZenModeBackend.getInstance(context);
|
||||
mListValues = context.getResources().getStringArray(R.array.zen_mode_contacts_values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = (ListPreference) screen.findPreference(KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
updateFromContactsValue(preference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object selectedContactsFrom) {
|
||||
mBackend.saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES,
|
||||
ZenModeBackend.getSettingFromPrefKey(selectedContactsFrom.toString()));
|
||||
updateFromContactsValue(preference);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateFromContactsValue(Preference preference) {
|
||||
mPreference = (ListPreference) preference;
|
||||
switch (getZenMode()) {
|
||||
case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
|
||||
case Settings.Global.ZEN_MODE_ALARMS:
|
||||
mPreference.setEnabled(false);
|
||||
mPreference.setValue(ZenModeBackend.ZEN_MODE_FROM_NONE);
|
||||
mPreference.setSummary(mBackend.getContactsSummary(ZenModeBackend.SOURCE_NONE));
|
||||
break;
|
||||
default:
|
||||
preference.setEnabled(true);
|
||||
preference.setSummary(mBackend.getContactsSummary(
|
||||
NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES));
|
||||
|
||||
final String currentVal = ZenModeBackend.getKeyFromSetting(
|
||||
mBackend.getPriorityMessageSenders());
|
||||
mPreference.setValue(mListValues[getIndexOfSendersValue(currentVal)]);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected int getIndexOfSendersValue(String currentVal) {
|
||||
int index = 3; // defaults to "none" based on R.array.zen_mode_contacts_values
|
||||
for (int i = 0; i < mListValues.length; i++) {
|
||||
if (TextUtils.equals(currentVal, mListValues[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
@@ -82,9 +82,12 @@ public class ZenModeSettings extends ZenModeSettingsBase {
|
||||
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
|
||||
Lifecycle lifecycle, FragmentManager fragmentManager) {
|
||||
List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new ZenModeBehaviorMsgEventReminderPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModeBehaviorSoundPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModeBehaviorCallsPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModeCallsPreferenceController(context, lifecycle,
|
||||
"zen_mode_behavior_calls"));
|
||||
controllers.add(new ZenModeMessagesPreferenceController(context, lifecycle,
|
||||
"zen_mode_behavior_messages"));
|
||||
controllers.add(new ZenModeAlarmsPreferenceController(context, lifecycle,
|
||||
"zen_mode_behavior_alarms"));
|
||||
controllers.add(new ZenModeBlockedEffectsPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModeDurationPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModeAutomationPreferenceController(context));
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings.notification;
|
||||
|
||||
import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.SearchIndexableResource;
|
||||
|
||||
@@ -41,9 +43,16 @@ public class ZenModeSoundVibrationSettings extends ZenModeSettingsBase implement
|
||||
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
|
||||
Lifecycle lifecycle) {
|
||||
List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new ZenModeAlarmsPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModeCallsPreferenceController(context, lifecycle,
|
||||
"zen_mode_calls_settings"));
|
||||
controllers.add(new ZenModeMessagesPreferenceController(context, lifecycle,
|
||||
"zen_mode_messages_settings"));
|
||||
controllers.add(new ZenModeAlarmsPreferenceController(context, lifecycle,
|
||||
"zen_mode_alarms"));
|
||||
controllers.add(new ZenModeMediaPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModeSystemPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModeRemindersPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModeEventsPreferenceController(context, lifecycle));
|
||||
controllers.add(new ZenModeBehaviorFooterPreferenceController(context, lifecycle,
|
||||
R.string.zen_sound_footer));
|
||||
return controllers;
|
||||
|
||||
198
src/com/android/settings/password/BiometricFragment.java
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* 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.password;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.DialogInterface;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricPrompt;
|
||||
import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback;
|
||||
import android.hardware.biometrics.BiometricPrompt.AuthenticationResult;
|
||||
import android.os.Bundle;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* A fragment that wraps the BiometricPrompt and manages its lifecycle.
|
||||
*/
|
||||
public class BiometricFragment extends InstrumentedFragment {
|
||||
|
||||
private static final String KEY_TITLE = "title";
|
||||
private static final String KEY_SUBTITLE = "subtitle";
|
||||
private static final String KEY_DESCRIPTION = "description";
|
||||
private static final String KEY_NEGATIVE_TEXT = "negative_text";
|
||||
|
||||
// Re-set by the application. Should be done upon orientation changes, etc
|
||||
private Executor mClientExecutor;
|
||||
private AuthenticationCallback mClientCallback;
|
||||
|
||||
// Created/Initialized once and retained
|
||||
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
||||
private PromptInfo mPromptInfo;
|
||||
private BiometricPrompt mBiometricPrompt;
|
||||
private CancellationSignal mCancellationSignal;
|
||||
|
||||
private AuthenticationCallback mAuthenticationCallback =
|
||||
new AuthenticationCallback() {
|
||||
@Override
|
||||
public void onAuthenticationError(int error, @NonNull CharSequence message) {
|
||||
mClientExecutor.execute(() -> {
|
||||
mClientCallback.onAuthenticationError(error, message);
|
||||
});
|
||||
cleanup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(AuthenticationResult result) {
|
||||
mClientExecutor.execute(() -> {
|
||||
mClientCallback.onAuthenticationSucceeded(result);
|
||||
});
|
||||
cleanup();
|
||||
}
|
||||
};
|
||||
|
||||
private final DialogInterface.OnClickListener mNegativeButtonListener =
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
mAuthenticationCallback.onAuthenticationError(
|
||||
BiometricConstants.BIOMETRIC_ERROR_NEGATIVE_BUTTON,
|
||||
mPromptInfo.getNegativeButtonText());
|
||||
}
|
||||
};
|
||||
|
||||
public static BiometricFragment newInstance(PromptInfo info) {
|
||||
BiometricFragment biometricFragment = new BiometricFragment();
|
||||
biometricFragment.setArguments(info.getBundle());
|
||||
return biometricFragment;
|
||||
}
|
||||
|
||||
public void setCallbacks(Executor executor, AuthenticationCallback callback) {
|
||||
mClientExecutor = executor;
|
||||
mClientCallback = callback;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
if (mCancellationSignal != null) {
|
||||
mCancellationSignal.cancel();
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
if (getActivity() != null) {
|
||||
getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setRetainInstance(true);
|
||||
|
||||
mPromptInfo = new PromptInfo(getArguments());
|
||||
mBiometricPrompt = new BiometricPrompt.Builder(getContext())
|
||||
.setTitle(mPromptInfo.getTitle())
|
||||
.setUseDefaultTitle() // use default title if title is null/empty
|
||||
.setSubtitle(mPromptInfo.getSubtitle())
|
||||
.setDescription(mPromptInfo.getDescription())
|
||||
.setNegativeButton(mPromptInfo.getNegativeButtonText(), mClientExecutor,
|
||||
mNegativeButtonListener)
|
||||
.build();
|
||||
mCancellationSignal = new CancellationSignal();
|
||||
|
||||
// TODO: CC doesn't use crypto for now
|
||||
mBiometricPrompt.authenticate(mCancellationSignal, mClientExecutor,
|
||||
mAuthenticationCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.BIOMETRIC_FRAGMENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple wrapper for BiometricPrompt.PromptInfo. Since we want to manage the lifecycle
|
||||
* of BiometricPrompt correctly, the information needs to be stored in here.
|
||||
*/
|
||||
static class PromptInfo {
|
||||
private final Bundle mBundle;
|
||||
|
||||
private PromptInfo(Bundle bundle) {
|
||||
mBundle = bundle;
|
||||
}
|
||||
|
||||
Bundle getBundle() {
|
||||
return mBundle;
|
||||
}
|
||||
|
||||
public CharSequence getTitle() {
|
||||
return mBundle.getCharSequence(KEY_TITLE);
|
||||
}
|
||||
|
||||
public CharSequence getSubtitle() {
|
||||
return mBundle.getCharSequence(KEY_SUBTITLE);
|
||||
}
|
||||
|
||||
public CharSequence getDescription() {
|
||||
return mBundle.getCharSequence(KEY_DESCRIPTION);
|
||||
}
|
||||
|
||||
public CharSequence getNegativeButtonText() {
|
||||
return mBundle.getCharSequence(KEY_NEGATIVE_TEXT);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final Bundle mBundle = new Bundle();
|
||||
|
||||
public Builder setTitle(@NonNull CharSequence title) {
|
||||
mBundle.putCharSequence(KEY_TITLE, title);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSubtitle(@Nullable CharSequence subtitle) {
|
||||
mBundle.putCharSequence(KEY_SUBTITLE, subtitle);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDescription(@Nullable CharSequence description) {
|
||||
mBundle.putCharSequence(KEY_DESCRIPTION, description);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setNegativeButtonText(@NonNull CharSequence text) {
|
||||
mBundle.putCharSequence(KEY_NEGATIVE_TEXT, text);
|
||||
return this;
|
||||
}
|
||||
|
||||
public PromptInfo build() {
|
||||
return new PromptInfo(mBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,13 @@ public final class ChooseLockSettingsHelper {
|
||||
* @see Activity#onActivityResult(int, int, android.content.Intent)
|
||||
*/
|
||||
public boolean launchConfirmationActivity(int request, CharSequence title) {
|
||||
return launchConfirmationActivity(request, title, null, null, false, false);
|
||||
return launchConfirmationActivity(
|
||||
request /* request */,
|
||||
title /* title */,
|
||||
null /* header */,
|
||||
null /* description */,
|
||||
false /* returnCredentials */,
|
||||
false /* external */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,7 +97,13 @@ public final class ChooseLockSettingsHelper {
|
||||
* @see Activity#onActivityResult(int, int, android.content.Intent)
|
||||
*/
|
||||
public boolean launchConfirmationActivity(int request, CharSequence title, boolean returnCredentials) {
|
||||
return launchConfirmationActivity(request, title, null, null, returnCredentials, false);
|
||||
return launchConfirmationActivity(
|
||||
request /* request */,
|
||||
title /* title */,
|
||||
null /* header */,
|
||||
null /* description */,
|
||||
returnCredentials /* returnCredentials */,
|
||||
false /* external */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,8 +118,16 @@ public final class ChooseLockSettingsHelper {
|
||||
*/
|
||||
public boolean launchConfirmationActivity(int request, CharSequence title,
|
||||
boolean returnCredentials, int userId) {
|
||||
return launchConfirmationActivity(request, title, null, null,
|
||||
returnCredentials, false, false, 0, Utils.enforceSameOwner(mActivity, userId));
|
||||
return launchConfirmationActivity(
|
||||
request /* request */,
|
||||
title /* title */,
|
||||
null /* header */,
|
||||
null /* description */,
|
||||
returnCredentials /* returnCredentials */,
|
||||
false /* external */,
|
||||
false /* hasChallenge */,
|
||||
0 /* challenge */,
|
||||
Utils.enforceSameOwner(mActivity, userId) /* userId */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,8 +147,16 @@ public final class ChooseLockSettingsHelper {
|
||||
boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
|
||||
@Nullable CharSequence header, @Nullable CharSequence description,
|
||||
boolean returnCredentials, boolean external) {
|
||||
return launchConfirmationActivity(request, title, header, description,
|
||||
returnCredentials, external, false, 0, Utils.getCredentialOwnerUserId(mActivity));
|
||||
return launchConfirmationActivity(
|
||||
request /* request */,
|
||||
title /* title */,
|
||||
header /* header */,
|
||||
description /* description */,
|
||||
returnCredentials /* returnCredentials */,
|
||||
external /* external */,
|
||||
false /* hasChallenge */,
|
||||
0 /* challenge */,
|
||||
Utils.getCredentialOwnerUserId(mActivity) /* userId */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,8 +177,16 @@ public final class ChooseLockSettingsHelper {
|
||||
boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
|
||||
@Nullable CharSequence header, @Nullable CharSequence description,
|
||||
boolean returnCredentials, boolean external, int userId) {
|
||||
return launchConfirmationActivity(request, title, header, description,
|
||||
returnCredentials, external, false, 0, Utils.enforceSameOwner(mActivity, userId));
|
||||
return launchConfirmationActivity(
|
||||
request /* request */,
|
||||
title /* title */,
|
||||
header /* header */,
|
||||
description /* description */,
|
||||
returnCredentials /* returnCredentials */,
|
||||
external /* external */,
|
||||
false /* hasChallenge */,
|
||||
0 /* challenge */,
|
||||
Utils.enforceSameOwner(mActivity, userId) /* userId */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,8 +202,16 @@ public final class ChooseLockSettingsHelper {
|
||||
public boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
|
||||
@Nullable CharSequence header, @Nullable CharSequence description,
|
||||
long challenge) {
|
||||
return launchConfirmationActivity(request, title, header, description,
|
||||
true, false, true, challenge, Utils.getCredentialOwnerUserId(mActivity));
|
||||
return launchConfirmationActivity(
|
||||
request /* request */,
|
||||
title /* title */,
|
||||
header /* header */,
|
||||
description /* description */,
|
||||
true /* returnCredentials */,
|
||||
false /* external */,
|
||||
true /* hasChallenge */,
|
||||
challenge /* challenge */,
|
||||
Utils.getCredentialOwnerUserId(mActivity) /* userId */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,8 +228,16 @@ public final class ChooseLockSettingsHelper {
|
||||
public boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
|
||||
@Nullable CharSequence header, @Nullable CharSequence description,
|
||||
long challenge, int userId) {
|
||||
return launchConfirmationActivity(request, title, header, description,
|
||||
true, false, true, challenge, Utils.enforceSameOwner(mActivity, userId));
|
||||
return launchConfirmationActivity(
|
||||
request /* request */,
|
||||
title /* title */,
|
||||
header /* header */,
|
||||
description /* description */,
|
||||
true /* returnCredentials */,
|
||||
false /* external */,
|
||||
true /* hasChallenge */,
|
||||
challenge /* challenge */,
|
||||
Utils.enforceSameOwner(mActivity, userId) /* userId */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,8 +257,16 @@ public final class ChooseLockSettingsHelper {
|
||||
public boolean launchConfirmationActivityWithExternalAndChallenge(int request,
|
||||
@Nullable CharSequence title, @Nullable CharSequence header,
|
||||
@Nullable CharSequence description, boolean external, long challenge, int userId) {
|
||||
return launchConfirmationActivity(request, title, header, description, false,
|
||||
external, true, challenge, Utils.enforceSameOwner(mActivity, userId));
|
||||
return launchConfirmationActivity(
|
||||
request /* request */,
|
||||
title /* title */,
|
||||
header /* header */,
|
||||
description /* description */,
|
||||
false /* returnCredentials */,
|
||||
external /* external */,
|
||||
true /* hasChallenge */,
|
||||
challenge /* challenge */,
|
||||
Utils.enforceSameOwner(mActivity, userId) /* userId */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,31 +279,69 @@ public final class ChooseLockSettingsHelper {
|
||||
@Nullable CharSequence description, int userId) {
|
||||
final Bundle extras = new Bundle();
|
||||
extras.putBoolean(EXTRA_ALLOW_ANY_USER, true);
|
||||
return launchConfirmationActivity(request, title, header, description, false,
|
||||
false, true, 0, userId, extras);
|
||||
return launchConfirmationActivity(
|
||||
request /* request */,
|
||||
title /* title */,
|
||||
header /* header */,
|
||||
description /* description */,
|
||||
false /* returnCredentials */,
|
||||
false /* external */,
|
||||
true /* hasChallenge */,
|
||||
0 /* challenge */,
|
||||
userId /* userId */,
|
||||
extras /* extras */);
|
||||
}
|
||||
|
||||
private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
|
||||
@Nullable CharSequence header, @Nullable CharSequence description,
|
||||
boolean returnCredentials, boolean external, boolean hasChallenge,
|
||||
long challenge, int userId) {
|
||||
return launchConfirmationActivity(request, title, header, description, returnCredentials,
|
||||
external, hasChallenge, challenge, userId, null /* alternateButton */, null);
|
||||
return launchConfirmationActivity(
|
||||
request /* request */,
|
||||
title /* title */,
|
||||
header /* header */,
|
||||
description /* description */,
|
||||
returnCredentials /* returnCredentials */,
|
||||
external /* external */,
|
||||
hasChallenge /* hasChallenge */,
|
||||
challenge /* challenge */,
|
||||
userId /* userId */,
|
||||
null /* alternateButton */,
|
||||
null /* extras */);
|
||||
}
|
||||
|
||||
private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
|
||||
@Nullable CharSequence header, @Nullable CharSequence description,
|
||||
boolean returnCredentials, boolean external, boolean hasChallenge,
|
||||
long challenge, int userId, Bundle extras) {
|
||||
return launchConfirmationActivity(request, title, header, description, returnCredentials,
|
||||
external, hasChallenge, challenge, userId, null /* alternateButton */, extras);
|
||||
return launchConfirmationActivity(
|
||||
request /* request */,
|
||||
title /* title */,
|
||||
header /* header */,
|
||||
description /* description */,
|
||||
returnCredentials /* returnCredentials */,
|
||||
external /* external */,
|
||||
hasChallenge /* hasChallenge */,
|
||||
challenge /* challenge */,
|
||||
userId /* userId */,
|
||||
null /* alternateButton */,
|
||||
extras /* extras */);
|
||||
}
|
||||
|
||||
public boolean launchFrpConfirmationActivity(int request, @Nullable CharSequence header,
|
||||
@Nullable CharSequence description, @Nullable CharSequence alternateButton) {
|
||||
return launchConfirmationActivity(request, null /* title */, header, description,
|
||||
false /* returnCredentials */, true /* external */, false /* hasChallenge */,
|
||||
0 /* challenge */, LockPatternUtils.USER_FRP, alternateButton, null);
|
||||
return launchConfirmationActivity(
|
||||
request /* request */,
|
||||
null /* title */,
|
||||
header /* header */,
|
||||
description /* description */,
|
||||
false /* returnCredentials */,
|
||||
true /* external */,
|
||||
false /* hasChallenge */,
|
||||
0 /* challenge */,
|
||||
LockPatternUtils.USER_FRP /* userId */,
|
||||
alternateButton /* alternateButton */,
|
||||
null /* extras */);
|
||||
}
|
||||
|
||||
private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
|
||||
@@ -285,11 +383,11 @@ public final class ChooseLockSettingsHelper {
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.TITLE_TEXT, title);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.HEADER_TEXT, header);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.DETAILS_TEXT, message);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.ALLOW_FP_AUTHENTICATION, external);
|
||||
// TODO: Remove dark theme and show_cancel_button options since they are no longer used
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.DARK_THEME, false);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.SHOW_CANCEL_BUTTON, false);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.SHOW_WHEN_LOCKED, external);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.USE_FADE_ANIMATION, external);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_RETURN_CREDENTIALS, returnCredentials);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, hasChallenge);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
|
||||
|
||||
@@ -22,21 +22,40 @@ import android.app.KeyguardManager;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricManager;
|
||||
import android.hardware.biometrics.BiometricPrompt;
|
||||
import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Launch this when you want to confirm the user is present by asking them to enter their
|
||||
* PIN/password/pattern.
|
||||
*/
|
||||
public class ConfirmDeviceCredentialActivity extends Activity {
|
||||
public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
||||
public static final String TAG = ConfirmDeviceCredentialActivity.class.getSimpleName();
|
||||
|
||||
// The normal flow that apps go through
|
||||
private static final int CREDENTIAL_NORMAL = 1;
|
||||
// Unlocks the managed profile when the primary profile is unlocked
|
||||
private static final int CREDENTIAL_MANAGED = 2;
|
||||
|
||||
private static final String TAG_BIOMETRIC_FRAGMENT = "fragment";
|
||||
|
||||
public static class InternalActivity extends ConfirmDeviceCredentialActivity {
|
||||
}
|
||||
|
||||
@@ -60,57 +79,217 @@ public class ConfirmDeviceCredentialActivity extends Activity {
|
||||
return intent;
|
||||
}
|
||||
|
||||
private BiometricManager mBiometricManager;
|
||||
private BiometricFragment mBiometricFragment;
|
||||
private DevicePolicyManager mDevicePolicyManager;
|
||||
private LockPatternUtils mLockPatternUtils;
|
||||
private UserManager mUserManager;
|
||||
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
|
||||
private Handler mHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
private String mTitle;
|
||||
private String mDetails;
|
||||
private int mUserId;
|
||||
private int mEffectiveUserId;
|
||||
private int mCredentialMode;
|
||||
private boolean mGoingToBackground;
|
||||
|
||||
private Executor mExecutor = (runnable -> {
|
||||
mHandler.post(runnable);
|
||||
});
|
||||
|
||||
private AuthenticationCallback mAuthenticationCallback = new AuthenticationCallback() {
|
||||
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
|
||||
if (!mGoingToBackground) {
|
||||
if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_USER_CANCELED) {
|
||||
finish();
|
||||
} else {
|
||||
// All other errors go to some version of CC
|
||||
showConfirmCredentials();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
|
||||
setResult(Activity.RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mBiometricManager = getSystemService(BiometricManager.class);
|
||||
mDevicePolicyManager = getSystemService(DevicePolicyManager.class);
|
||||
mUserManager = UserManager.get(this);
|
||||
mLockPatternUtils = new LockPatternUtils(this);
|
||||
|
||||
Intent intent = getIntent();
|
||||
String title = intent.getStringExtra(KeyguardManager.EXTRA_TITLE);
|
||||
String details = intent.getStringExtra(KeyguardManager.EXTRA_DESCRIPTION);
|
||||
mTitle = intent.getStringExtra(KeyguardManager.EXTRA_TITLE);
|
||||
mDetails = intent.getStringExtra(KeyguardManager.EXTRA_DESCRIPTION);
|
||||
String alternateButton = intent.getStringExtra(
|
||||
KeyguardManager.EXTRA_ALTERNATE_BUTTON_LABEL);
|
||||
boolean frp = KeyguardManager.ACTION_CONFIRM_FRP_CREDENTIAL.equals(intent.getAction());
|
||||
|
||||
int userId = UserHandle.myUserId();
|
||||
mUserId = UserHandle.myUserId();
|
||||
mEffectiveUserId = mUserManager.getCredentialOwnerProfile(mUserId);
|
||||
if (isInternalActivity()) {
|
||||
try {
|
||||
userId = Utils.getUserIdFromBundle(this, intent.getExtras());
|
||||
mUserId = Utils.getUserIdFromBundle(this, intent.getExtras());
|
||||
} catch (SecurityException se) {
|
||||
Log.e(TAG, "Invalid intent extra", se);
|
||||
}
|
||||
}
|
||||
final boolean isManagedProfile = UserManager.get(this).isManagedProfile(userId);
|
||||
final boolean isManagedProfile = UserManager.get(this).isManagedProfile(mUserId);
|
||||
// if the client app did not hand in a title and we are about to show the work challenge,
|
||||
// check whether there is a policy setting the organization name and use that as title
|
||||
if ((title == null) && isManagedProfile) {
|
||||
title = getTitleFromOrganizationName(userId);
|
||||
if ((mTitle == null) && isManagedProfile) {
|
||||
mTitle = getTitleFromOrganizationName(mUserId);
|
||||
}
|
||||
ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(this);
|
||||
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this);
|
||||
final LockPatternUtils lockPatternUtils = new LockPatternUtils(this);
|
||||
boolean launched;
|
||||
|
||||
boolean launchedBiometric = false;
|
||||
boolean launchedCDC = false;
|
||||
// If the target is a managed user and user key not unlocked yet, we will force unlock
|
||||
// tied profile so it will enable work mode and unlock managed profile, when personal
|
||||
// challenge is unlocked.
|
||||
if (frp) {
|
||||
launched = helper.launchFrpConfirmationActivity(0, title, details, alternateButton);
|
||||
launchedCDC = mChooseLockSettingsHelper.launchFrpConfirmationActivity(
|
||||
0, mTitle, mDetails, alternateButton);
|
||||
} else if (isManagedProfile && isInternalActivity()
|
||||
&& !lockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
|
||||
&& !lockPatternUtils.isSeparateProfileChallengeEnabled(mUserId)) {
|
||||
mCredentialMode = CREDENTIAL_MANAGED;
|
||||
if (isBiometricAllowed()) {
|
||||
showBiometricPrompt();
|
||||
launchedBiometric = true;
|
||||
} else {
|
||||
showConfirmCredentials();
|
||||
}
|
||||
} else {
|
||||
mCredentialMode = CREDENTIAL_NORMAL;
|
||||
if (isBiometricAllowed()) {
|
||||
// Don't need to check if biometrics / pin/pattern/pass are enrolled. It will go to
|
||||
// onAuthenticationError and do the right thing automatically.
|
||||
showBiometricPrompt();
|
||||
launchedBiometric = true;
|
||||
} else {
|
||||
showConfirmCredentials();
|
||||
}
|
||||
}
|
||||
|
||||
if (launchedCDC) {
|
||||
finish();
|
||||
} else if (launchedBiometric) {
|
||||
// Keep this activity alive until BiometricPrompt goes away
|
||||
} else {
|
||||
Log.d(TAG, "No pattern, password or PIN set.");
|
||||
setResult(Activity.RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
// Translucent activity that is "visible", so it doesn't complain about finish()
|
||||
// not being called before onResume().
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (!isChangingConfigurations()) {
|
||||
mGoingToBackground = true;
|
||||
if (mBiometricFragment != null) {
|
||||
mBiometricFragment.cancel();
|
||||
}
|
||||
finish();
|
||||
} else {
|
||||
mGoingToBackground = false;
|
||||
}
|
||||
}
|
||||
|
||||
// User could be locked while Effective user is unlocked even though the effective owns the
|
||||
// credential. Otherwise, biometric can't unlock fbe/keystore through
|
||||
// verifyTiedProfileChallenge. In such case, we also wanna show the user message that
|
||||
// biometric is disabled due to device restart.
|
||||
private boolean isStrongAuthRequired() {
|
||||
return !mLockPatternUtils.isBiometricAllowedForUser(mEffectiveUserId)
|
||||
|| !mUserManager.isUserUnlocked(mUserId);
|
||||
}
|
||||
|
||||
private boolean isBiometricDisabledByAdmin() {
|
||||
final int disabledFeatures =
|
||||
mDevicePolicyManager.getKeyguardDisabledFeatures(null, mEffectiveUserId);
|
||||
return (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_BIOMETRICS) != 0;
|
||||
}
|
||||
|
||||
private boolean isBiometricAllowed() {
|
||||
return !isStrongAuthRequired() && !isBiometricDisabledByAdmin();
|
||||
}
|
||||
|
||||
private void showBiometricPrompt() {
|
||||
mBiometricManager.setActiveUser(mUserId);
|
||||
|
||||
mBiometricFragment = (BiometricFragment) getSupportFragmentManager()
|
||||
.findFragmentByTag(TAG_BIOMETRIC_FRAGMENT);
|
||||
boolean newFragment = false;
|
||||
|
||||
if (mBiometricFragment == null) {
|
||||
final BiometricFragment.PromptInfo info = new BiometricFragment.PromptInfo.Builder()
|
||||
.setTitle(mTitle)
|
||||
.setSubtitle(mDetails)
|
||||
.setNegativeButtonText(getResources()
|
||||
.getString(R.string.confirm_device_credential_use_alternate_method))
|
||||
.build();
|
||||
mBiometricFragment = BiometricFragment.newInstance(info);
|
||||
newFragment = true;
|
||||
}
|
||||
mBiometricFragment.setCallbacks(mExecutor, mAuthenticationCallback);
|
||||
|
||||
if (newFragment) {
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.add(mBiometricFragment, TAG_BIOMETRIC_FRAGMENT).commit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows ConfirmDeviceCredentials for normal apps.
|
||||
*/
|
||||
private void showConfirmCredentials() {
|
||||
boolean launched = false;
|
||||
if (mCredentialMode == CREDENTIAL_MANAGED) {
|
||||
// We set the challenge as 0L, so it will force to unlock managed profile when it
|
||||
// unlocks primary profile screen lock, by calling verifyTiedProfileChallenge()
|
||||
launched = helper.launchConfirmationActivityWithExternalAndChallenge(
|
||||
0 /* request code */, null /* title */, title, details, true /* isExternal */,
|
||||
0L /* challenge */, userId);
|
||||
} else {
|
||||
launched = helper.launchConfirmationActivity(0 /* request code */, null /* title */,
|
||||
title, details, false /* returnCredentials */, true /* isExternal */, userId);
|
||||
launched = mChooseLockSettingsHelper
|
||||
.launchConfirmationActivityWithExternalAndChallenge(
|
||||
0 /* request code */, null /* title */, mTitle, mDetails,
|
||||
true /* isExternal */, 0L /* challenge */, mUserId);
|
||||
} else if (mCredentialMode == CREDENTIAL_NORMAL){
|
||||
launched = mChooseLockSettingsHelper.launchConfirmationActivity(
|
||||
0 /* request code */, null /* title */,
|
||||
mTitle, mDetails, false /* returnCredentials */, true /* isExternal */,
|
||||
mUserId);
|
||||
}
|
||||
if (!launched) {
|
||||
Log.d(TAG, "No pattern, password or PIN set.");
|
||||
Log.d(TAG, "No pin/pattern/pass set");
|
||||
setResult(Activity.RESULT_OK);
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
// Finish without animation since the activity is just there so we can launch
|
||||
// BiometricPrompt.
|
||||
overridePendingTransition(R.anim.confirm_credential_biometric_transition_enter, 0);
|
||||
}
|
||||
|
||||
private boolean isInternalActivity() {
|
||||
return this instanceof ConfirmDeviceCredentialActivity.InternalActivity;
|
||||
}
|
||||
|
||||
@@ -140,6 +140,15 @@ public abstract class ConfirmDeviceCredentialBaseActivity extends SettingsActivi
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
if (getIntent().getBooleanExtra(
|
||||
ConfirmDeviceCredentialBaseFragment.USE_FADE_ANIMATION, false)) {
|
||||
overridePendingTransition(0, R.anim.confirm_credential_biometric_transition_exit);
|
||||
}
|
||||
}
|
||||
|
||||
public void prepareEnterAnimation() {
|
||||
getFragment().prepareEnterAnimation();
|
||||
}
|
||||
|
||||
@@ -53,26 +53,24 @@ import androidx.fragment.app.FragmentManager;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.fingerprint.FingerprintUiHelper;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
|
||||
/**
|
||||
* Base fragment to be shared for PIN/Pattern/Password confirmation fragments.
|
||||
*/
|
||||
public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFragment
|
||||
implements FingerprintUiHelper.Callback {
|
||||
public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFragment {
|
||||
|
||||
public static final String PACKAGE = "com.android.settings";
|
||||
public static final String TITLE_TEXT = PACKAGE + ".ConfirmCredentials.title";
|
||||
public static final String HEADER_TEXT = PACKAGE + ".ConfirmCredentials.header";
|
||||
public static final String DETAILS_TEXT = PACKAGE + ".ConfirmCredentials.details";
|
||||
public static final String ALLOW_FP_AUTHENTICATION =
|
||||
PACKAGE + ".ConfirmCredentials.allowFpAuthentication";
|
||||
public static final String DARK_THEME = PACKAGE + ".ConfirmCredentials.darkTheme";
|
||||
public static final String SHOW_CANCEL_BUTTON =
|
||||
PACKAGE + ".ConfirmCredentials.showCancelButton";
|
||||
public static final String SHOW_WHEN_LOCKED =
|
||||
PACKAGE + ".ConfirmCredentials.showWhenLocked";
|
||||
public static final String USE_FADE_ANIMATION =
|
||||
PACKAGE + ".ConfirmCredentials.useFadeAnimation";
|
||||
|
||||
protected static final int USER_TYPE_PRIMARY = 1;
|
||||
protected static final int USER_TYPE_MANAGED_PROFILE = 2;
|
||||
@@ -81,10 +79,8 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
||||
/** Time we wait before clearing a wrong input attempt (e.g. pattern) and the error message. */
|
||||
protected static final long CLEAR_WRONG_ATTEMPT_TIMEOUT_MS = 3000;
|
||||
|
||||
private FingerprintUiHelper mFingerprintHelper;
|
||||
protected boolean mReturnCredentials = false;
|
||||
protected Button mCancelButton;
|
||||
protected ImageView mFingerprintIcon;
|
||||
protected int mEffectiveUserId;
|
||||
protected int mUserId;
|
||||
protected UserManager mUserManager;
|
||||
@@ -123,9 +119,7 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mCancelButton = (Button) view.findViewById(R.id.cancelButton);
|
||||
mFingerprintIcon = (ImageView) view.findViewById(R.id.fingerprintIcon);
|
||||
mFingerprintHelper = new FingerprintUiHelper(
|
||||
mFingerprintIcon, view.findViewById(R.id.errorText), this, mUserId);
|
||||
|
||||
boolean showCancelButton = getActivity().getIntent().getBooleanExtra(
|
||||
SHOW_CANCEL_BUTTON, false);
|
||||
boolean hasAlternateButton = mFrp && !TextUtils.isEmpty(mFrpAlternateButtonText);
|
||||
@@ -153,29 +147,16 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isFingerprintDisabledByAdmin() {
|
||||
final int disabledFeatures =
|
||||
mDevicePolicyManager.getKeyguardDisabledFeatures(null, mEffectiveUserId);
|
||||
return (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0;
|
||||
}
|
||||
|
||||
// User could be locked while Effective user is unlocked even though the effective owns the
|
||||
// credential. Otherwise, fingerprint can't unlock fbe/keystore through
|
||||
// verifyTiedProfileChallenge. In such case, we also wanna show the user message that
|
||||
// fingerprint is disabled due to device restart.
|
||||
protected boolean isStrongAuthRequired() {
|
||||
return mFrp
|
||||
|| !mLockPatternUtils.isFingerprintAllowedForUser(mEffectiveUserId)
|
||||
|| !mLockPatternUtils.isBiometricAllowedForUser(mEffectiveUserId)
|
||||
|| !mUserManager.isUserUnlocked(mUserId);
|
||||
}
|
||||
|
||||
private boolean isFingerprintAllowed() {
|
||||
return !mReturnCredentials
|
||||
&& getActivity().getIntent().getBooleanExtra(ALLOW_FP_AUTHENTICATION, false)
|
||||
&& !isStrongAuthRequired()
|
||||
&& !isFingerprintDisabledByAdmin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
@@ -183,13 +164,6 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
||||
}
|
||||
|
||||
protected void refreshLockScreen() {
|
||||
if (isFingerprintAllowed()) {
|
||||
mFingerprintHelper.startListening();
|
||||
} else {
|
||||
if (mFingerprintHelper.isListening()) {
|
||||
mFingerprintHelper.stopListening();
|
||||
}
|
||||
}
|
||||
updateErrorMessage(mLockPatternUtils.getCurrentFailedPasswordAttempts(mEffectiveUserId));
|
||||
}
|
||||
|
||||
@@ -214,28 +188,10 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (mFingerprintHelper.isListening()) {
|
||||
mFingerprintHelper.stopListening();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticated() {
|
||||
// Check whether we are still active.
|
||||
if (getActivity() != null && getActivity().isResumed()) {
|
||||
TrustManager trustManager =
|
||||
(TrustManager) getActivity().getSystemService(Context.TRUST_SERVICE);
|
||||
trustManager.setDeviceLockedForUser(mEffectiveUserId, false);
|
||||
authenticationSucceeded();
|
||||
checkForPendingIntent();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void authenticationSucceeded();
|
||||
|
||||
@Override
|
||||
public void onFingerprintIconVisibilityChanged(boolean visible) {
|
||||
}
|
||||
|
||||
public void prepareEnterAnimation() {
|
||||
}
|
||||
|
||||
@@ -105,7 +105,6 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
||||
private CountDownTimer mCountdownTimer;
|
||||
private boolean mIsAlpha;
|
||||
private InputMethodManager mImm;
|
||||
private boolean mUsingFingerprint = false;
|
||||
private AppearAnimationUtils mAppearAnimationUtils;
|
||||
private DisappearAnimationUtils mDisappearAnimationUtils;
|
||||
|
||||
@@ -243,7 +242,6 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
||||
mCancelButton.setAlpha(0f);
|
||||
mPasswordEntry.setAlpha(0f);
|
||||
mErrorTextView.setAlpha(0f);
|
||||
mFingerprintIcon.setAlpha(0f);
|
||||
}
|
||||
|
||||
private View[] getActiveViews() {
|
||||
@@ -255,9 +253,6 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
||||
}
|
||||
result.add(mPasswordEntry);
|
||||
result.add(mErrorTextView);
|
||||
if (mFingerprintIcon.getVisibility() == View.VISIBLE) {
|
||||
result.add(mFingerprintIcon);
|
||||
}
|
||||
return result.toArray(new View[] {});
|
||||
}
|
||||
|
||||
@@ -303,17 +298,12 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
||||
mCredentialCheckResultTracker.setResult(true, new Intent(), 0, mEffectiveUserId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFingerprintIconVisibilityChanged(boolean visible) {
|
||||
mUsingFingerprint = visible;
|
||||
}
|
||||
|
||||
private void updatePasswordEntry() {
|
||||
final boolean isLockedOut =
|
||||
mLockPatternUtils.getLockoutAttemptDeadline(mEffectiveUserId) != 0;
|
||||
mPasswordEntry.setEnabled(!isLockedOut);
|
||||
mPasswordEntryInputDisabler.setInputEnabled(!isLockedOut);
|
||||
if (isLockedOut || mUsingFingerprint) {
|
||||
if (isLockedOut) {
|
||||
mImm.hideSoftInputFromWindow(mPasswordEntry.getWindowToken(), 0 /*flags*/);
|
||||
} else {
|
||||
mPasswordEntry.scheduleShowSoftInput();
|
||||
|
||||
@@ -231,7 +231,6 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
||||
mCancelButton.setAlpha(0f);
|
||||
mLockPatternView.setAlpha(0f);
|
||||
mDetailsTextView.setAlpha(0f);
|
||||
mFingerprintIcon.setAlpha(0f);
|
||||
}
|
||||
|
||||
private int getDefaultDetails() {
|
||||
@@ -265,9 +264,6 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
||||
}
|
||||
result.add(row);
|
||||
}
|
||||
if (mFingerprintIcon.getVisibility() == View.VISIBLE) {
|
||||
result.add(new ArrayList<Object>(Collections.singletonList(mFingerprintIcon)));
|
||||
}
|
||||
Object[][] resultArr = new Object[result.size()][cellStates[0].length];
|
||||
for (int i = 0; i < result.size(); i++) {
|
||||
ArrayList<Object> row = result.get(i);
|
||||
@@ -377,16 +373,6 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFingerprintIconVisibilityChanged(boolean visible) {
|
||||
if (mLeftSpacerLandscape != null && mRightSpacerLandscape != null) {
|
||||
|
||||
// In landscape, adjust spacing depending on fingerprint icon visibility.
|
||||
mLeftSpacerLandscape.setVisibility(visible ? View.GONE : View.VISIBLE);
|
||||
mRightSpacerLandscape.setVisibility(visible ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The pattern listener that responds according to a user confirming
|
||||
* an existing lock pattern.
|
||||
|
||||
@@ -385,7 +385,7 @@ public class SliceBuilderUtils {
|
||||
final Set<String> keywords = buildSliceKeywords(data);
|
||||
@ColorInt final int color = Utils.getColorAccentDefaultColor(context);
|
||||
final CharSequence summary = context.getText(R.string.disabled_dependent_setting_summary);
|
||||
final IconCompat icon = IconCompat.createWithResource(context, data.getIconResource());
|
||||
final IconCompat icon = getSafeIcon(context, data);
|
||||
final SliceAction primaryAction = new SliceAction(getContentPendingIntent(context, data),
|
||||
icon, title);
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@ class SliceDataConverter {
|
||||
SliceBuilderUtils.getPreferenceController(mContext, xmlSlice);
|
||||
|
||||
// Only add pre-approved Slices available on the device.
|
||||
if (controller.isAvailable() && controller.isSliceable()) {
|
||||
if (controller.isSliceable() && controller.isAvailable()) {
|
||||
xmlSliceData.add(xmlSlice);
|
||||
}
|
||||
}
|
||||
@@ -277,7 +277,7 @@ class SliceDataConverter {
|
||||
final String title = resolveInfo.loadLabel(packageManager).toString();
|
||||
int iconResource = resolveInfo.getIconResource();
|
||||
if (iconResource == 0) {
|
||||
iconResource = R.mipmap.ic_accessibility_generic;
|
||||
iconResource = R.drawable.ic_accessibility_generic;
|
||||
}
|
||||
|
||||
sliceDataBuilder.setKey(flattenedName)
|
||||
|
||||
@@ -66,12 +66,11 @@ class SlicesIndexer implements Runnable {
|
||||
return;
|
||||
}
|
||||
|
||||
SQLiteDatabase database = mHelper.getWritableDatabase();
|
||||
final SQLiteDatabase database = mHelper.getWritableDatabase();
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
database.beginTransaction();
|
||||
try {
|
||||
long startTime = System.currentTimeMillis();
|
||||
database.beginTransaction();
|
||||
|
||||
mHelper.reconstruct(mHelper.getWritableDatabase());
|
||||
List<SliceData> indexData = getSliceData();
|
||||
insertSliceData(database, indexData);
|
||||
@@ -85,6 +84,7 @@ class SlicesIndexer implements Runnable {
|
||||
} finally {
|
||||
database.endTransaction();
|
||||
}
|
||||
database.close();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
117
src/com/android/settings/wifi/NetworkRequestDialogFragment.java
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.wifi;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settingslib.wifi.AccessPoint;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class NetworkRequestDialogFragment extends InstrumentedDialogFragment implements
|
||||
DialogInterface.OnClickListener {
|
||||
|
||||
private List<AccessPoint> mAccessPointList;
|
||||
|
||||
public static NetworkRequestDialogFragment newInstance(int uid, String packageName) {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt("uid", uid);
|
||||
args.putString("packageName", packageName);
|
||||
NetworkRequestDialogFragment dialogFragment = new NetworkRequestDialogFragment();
|
||||
dialogFragment.setArguments(args);
|
||||
return dialogFragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
Context context = getContext();
|
||||
|
||||
// Prepares title.
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
View customTitle = inflater.inflate(R.layout.network_request_dialog_title, null);
|
||||
|
||||
TextView title = customTitle.findViewById(R.id.network_request_title_text);
|
||||
title.setText(R.string.network_connection_request_dialog_title);
|
||||
ProgressBar progressBar = customTitle.findViewById(R.id.network_request_title_progress);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
// Prepares adapter.
|
||||
AccessPointAdapter adapter = new AccessPointAdapter(context,
|
||||
R.layout.preference_access_point, getAccessPointList());
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context)
|
||||
.setCustomTitle(customTitle)
|
||||
.setAdapter(adapter, this)
|
||||
.setPositiveButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
List<AccessPoint> getAccessPointList() {
|
||||
// Initials list for adapter, in case of display crashing.
|
||||
if (mAccessPointList == null) {
|
||||
mAccessPointList = new ArrayList<>();
|
||||
}
|
||||
return mAccessPointList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsProto.MetricsEvent.WIFI_SCANNING_NEEDED_DIALOG;
|
||||
}
|
||||
|
||||
private class AccessPointAdapter extends ArrayAdapter<AccessPoint> {
|
||||
|
||||
private final int mResourceId;
|
||||
private final LayoutInflater mInflater;
|
||||
|
||||
public AccessPointAdapter(Context context, int resourceId, List<AccessPoint> objects) {
|
||||
super(context, resourceId, objects);
|
||||
mResourceId = resourceId;
|
||||
mInflater = LayoutInflater.from(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View view, ViewGroup parent) {
|
||||
if (view == null) {
|
||||
view = mInflater.inflate(mResourceId, parent, false);
|
||||
}
|
||||
|
||||
// TODO: Sets correct information to list item.
|
||||
final View divider = view.findViewById(com.android.settingslib.R.id.two_target_divider);
|
||||
divider.setVisibility(View.GONE);
|
||||
|
||||
return view;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||