Snap for 5110273 from c9b56254a6 to qt-release

Change-Id: I1000a110e95b1216ab1d4dfe01f8a97b647fd566
This commit is contained in:
android-build-team Robot
2018-11-04 03:02:02 +00:00
252 changed files with 2990 additions and 3306 deletions

View File

@@ -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"/>

View 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>

View 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>

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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"

View File

@@ -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>

View File

@@ -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"

View File

@@ -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>

View 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>

View File

@@ -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>

View File

@@ -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 &amp; 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 &amp; 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 &amp; 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 &amp; 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&#8217;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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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" >

View 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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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/>

View File

@@ -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());
}

View File

@@ -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());
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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 +

View File

@@ -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)

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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() {

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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<>();

View File

@@ -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;
}
}
}

View File

@@ -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();
}

View File

@@ -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();

View File

@@ -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 {

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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();
}
}

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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() {

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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()));
}

View File

@@ -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) {

View File

@@ -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

View File

@@ -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()));
}
}

View File

@@ -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()));
}
}

View File

@@ -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()));
}
}

View File

@@ -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()));
}
}

View File

@@ -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,

View File

@@ -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
}
}

View File

@@ -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);
}
};
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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));

View File

@@ -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;

View 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);
}
}
}
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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() {
}

View File

@@ -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();

View File

@@ -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.

View File

@@ -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);

View File

@@ -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)

View File

@@ -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

View 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;
}
}
}

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