Snap for 4796633 from 72a9730426 to qt-release
Change-Id: I196689fafbd3b12bcc32acc4124122cae26daa4f
This commit is contained in:
@@ -715,7 +715,7 @@
|
||||
<activity
|
||||
android:name="Settings$ZenModeSettingsActivity"
|
||||
android:label="@string/zen_mode_settings_title"
|
||||
android:icon="@drawable/ic_settings_notifications"
|
||||
android:icon="@drawable/ic_notifications"
|
||||
android:exported="true"
|
||||
android:taskAffinity="com.android.settings"
|
||||
android:parentActivityName="Settings">
|
||||
@@ -763,7 +763,7 @@
|
||||
<activity
|
||||
android:name=".notification.ZenOnboardingActivity"
|
||||
android:label="@string/zen_onboarding_dnd_visual_disturbances_header"
|
||||
android:icon="@drawable/ic_settings_notifications"
|
||||
android:icon="@drawable/ic_notifications"
|
||||
android:theme="@*android:style/Theme.DeviceDefault.Settings.Dialog.NoActionBar"
|
||||
android:exported="true"
|
||||
android:taskAffinity="com.android.settings"
|
||||
@@ -776,7 +776,7 @@
|
||||
<activity
|
||||
android:name="Settings$ZenModeAutomationSettingsActivity"
|
||||
android:label="@string/zen_mode_automation_settings_title"
|
||||
android:icon="@drawable/ic_settings_notifications"
|
||||
android:icon="@drawable/ic_notifications"
|
||||
android:exported="true"
|
||||
android:taskAffinity="com.android.settings"
|
||||
android:parentActivityName="Settings$ZenModeSettingsActivity">
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M18,3v2h-2V3H8v2H6V3H5C4.45,3 4,3.45 4,4v16c0,0.55 0.45,1 1,1h1v-2h2v2h8v-2h2v2h1c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1H18zM8,17H6v-2h2V17zM8,13H6v-2h2V13zM8,9H6V7h2V9zM18,17h-2v-2h2V17zM18,13h-2v-2h2V13zM18,9h-2V7h2V9z"/>
|
||||
android:pathData="M20,4h-3l2,4h-3l-2,-4h-2l2,4h-3L9,4H7l2,4H6L4,4C2.9,4 2.01,4.9 2.01,6L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V6C22,4.9 21.1,4 20,4zM20,18L4,18v-8h16V18z"/>
|
||||
</vector>
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M18,3h-5c-0.55,0 -1,0.45 -1,1v8.3a3.88,3.88 0,0 0,-2.9 -0.04c-1.79,0.67 -3.11,2.35 -3.1,4.26A4.483,4.483 0,0 0,10.5 21c2.5,0 4.5,-2.3 4.5,-4.5V6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1z"/>
|
||||
android:pathData="M12,3l0.01,10.55c-0.59,-0.34 -1.27,-0.55 -2,-0.55C7.79,13 6,14.79 6,17c0,2.21 1.79,4 4.01,4S14,19.21 14,17V7h4V3H12zM10.01,19c-1.1,0 -2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2C12.01,18.1 11.11,19 10.01,19z"/>
|
||||
</vector>
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z"
|
||||
android:fillColor="#FFFFFFFF"/>
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M18,17v-6c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C7.64,5.36 6,7.92 6,11v6H4v2h10h0.38H20v-2H18zM16,17H8v-6c0,-2.48 1.51,-4.5 4,-4.5s4,2.02 4,4.5V17z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/>
|
||||
</vector>
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#0F9D58"
|
||||
android:pathData="M13,7h-2v2h2L13,7zM13,11h-2v6h2v-6zM17,1.01L7,1c-1.1,0 -2,0.9 -2,2v18c0,
|
||||
1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2L19,3c0,-1.1 -0.9,-1.99 -2,-1.99zM17,19L7,19L7,5h10v14z"/>
|
||||
android:pathData="M11,7h2v2h-2z"/>
|
||||
<path
|
||||
android:fillColor="#0F9D58"
|
||||
android:pathData="M11,11h2v6h-2z"/>
|
||||
<path
|
||||
android:fillColor="#0F9D58"
|
||||
android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7z"/>
|
||||
</vector>
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
android:tint="?android:attr/colorError">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M13,7h-2v2h2L13,7zM13,11h-2v6h2v-6zM17,1.01L7,1c-1.1,0 -2,0.9 -2,2v18c0,
|
||||
1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2L19,3c0,-1.1 -0.9,-1.99 -2,-1.99zM17,19L7,19L7,5h10v14z"/>
|
||||
android:pathData="M11,7h2v2h-2z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M11,11h2v6h-2z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7z"/>
|
||||
</vector>
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24.0dp"
|
||||
android:height="24.0dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M12.0,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0c0.0,1.0 0.89,2.0 2.0,2.0zm6.0,-6.0l0.0,-5.0c0.0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4.0c0.0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.0,0.67 -1.5,1.5l0.0,0.68C7.63,5.36 6.0,7.92 6.0,11.0l0.0,5.0l-2.0,2.0l0.0,1.0l16.0,0.0l0.0,-1.0l-2.0,-2.0z"/>
|
||||
</vector>
|
||||
@@ -14,11 +14,14 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24.0dp"
|
||||
android:height="24.0dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="@color/suw_color_accent_light"
|
||||
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4a2,2 0,0 0,2 2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2.15,2.15a0.5,0.5 0,0 0,0.35 0.85h15.6c0.45,0 0.67,-0.54 0.35,-0.85L18,16z"/>
|
||||
android:pathData="M18,17v-6c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C7.64,5.36 6,7.92 6,11v6H4v2h10h0.38H20v-2H18zM16,17H8v-6c0,-2.48 1.51,-4.5 4,-4.5s4,2.02 4,4.5V17z"/>
|
||||
<path
|
||||
android:fillColor="@color/suw_color_accent_light"
|
||||
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/>
|
||||
</vector>
|
||||
|
||||
@@ -1,22 +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.
|
||||
-->
|
||||
|
||||
<ripple
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="?android:attr/colorControlHighlight">
|
||||
<item android:drawable="?android:attr/colorPrimary"/>
|
||||
</ripple>
|
||||
@@ -24,7 +24,6 @@
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingBottom="24dp"
|
||||
android:background="@drawable/selectable_card_grey"
|
||||
style="@style/EntityHeader">
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
android:paddingStart="@dimen/preference_no_icon_padding_start"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/selectable_card_grey"
|
||||
android:selectable="false"
|
||||
style="@style/EntityHeader">
|
||||
|
||||
@@ -31,7 +30,7 @@
|
||||
android:id="@+id/usage_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:attr/colorAccent"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:text="@string/data_usage_title" />
|
||||
|
||||
<com.android.settings.datausage.MeasurableLinearLayout
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="1dip"
|
||||
android:background="#000000" />
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<!-- Preferred Network Type -->
|
||||
<TextView
|
||||
@@ -126,7 +126,7 @@
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="1dip"
|
||||
android:background="#000000" />
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<!-- Radio Power -->
|
||||
<Switch android:id="@+id/radio_power"
|
||||
@@ -172,7 +172,7 @@
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="1dip"
|
||||
android:background="#000000" />
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<!-- Ping stats -->
|
||||
<Button android:id="@+id/ping_test"
|
||||
@@ -202,7 +202,7 @@
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="1dip"
|
||||
android:background="#000000" />
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<!-- PPP Sent -->
|
||||
<LinearLayout style="@style/entry_layout">
|
||||
@@ -229,7 +229,7 @@
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="1dip"
|
||||
android:background="#000000" />
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<!-- Call Status -->
|
||||
<LinearLayout style="@style/entry_layout">
|
||||
@@ -253,7 +253,7 @@
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="1dip"
|
||||
android:background="#000000" />
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<!-- CellInfoListRate Selection -->
|
||||
<!-- Location -->
|
||||
@@ -290,7 +290,7 @@
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="1dip"
|
||||
android:background="#000000" />
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<!-- Launch OEM-specific Info/Settings Activity (if any) -->
|
||||
<!-- Carrier Provisioning -->
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
-->
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="320dp"
|
||||
android:layout_height="wrap_content" >
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/zen_onboarding_choices"
|
||||
|
||||
@@ -7244,15 +7244,15 @@
|
||||
<!-- Do not disturb: restrict notifications title [CHAR LIMIT=60] -->
|
||||
<string name="zen_mode_restrict_notifications_title">Notifications</string>
|
||||
<!-- Do not disturb: Mute notifications option [CHAR LIMIT=60] -->
|
||||
<string name="zen_mode_restrict_notifications_mute">Show notifications silently</string>
|
||||
<string name="zen_mode_restrict_notifications_mute">No sound from notifications</string>
|
||||
<!-- Do not disturb:Mute notifications summary [CHAR LIMIT=NONE] -->
|
||||
<string name="zen_mode_restrict_notifications_mute_summary">Notifications will be muted</string>
|
||||
<string name="zen_mode_restrict_notifications_mute_summary">You will see notifications on your screen</string>
|
||||
<!-- Do not disturb:Mute notifications footer [CHAR LIMIT=NONE] -->
|
||||
<string name="zen_mode_restrict_notifications_mute_footer">When notifications arrive, your phone won\u2019t make a sound or vibrate.</string>
|
||||
<!-- Do not disturb: Hide notifications option [CHAR LIMIT=60] -->
|
||||
<string name="zen_mode_restrict_notifications_hide">Hide notifications</string>
|
||||
<string name="zen_mode_restrict_notifications_hide">No visuals or sound from notifications</string>
|
||||
<!-- Do not disturb: Hide notifications summary [CHAR LIMIT=NONE] -->
|
||||
<string name="zen_mode_restrict_notifications_hide_summary">You won\u2019t see new or existing notifications</string>
|
||||
<string name="zen_mode_restrict_notifications_hide_summary">You won\u2019t see or hear notifications</string>
|
||||
<!-- Do not disturb: Hide notifications footer [CHAR LIMIT=NONE] -->
|
||||
<string name="zen_mode_restrict_notifications_hide_footer">Your phone won\u2019t show new or existing notifications, and won\u2019t make a sound or vibrate. Notifications won\u2019t appear when you swipe down from the top of your screen.\n\nKeep in mind, critical notifications for phone activity and status will still appear.</string>
|
||||
<!-- Do not disturb: Custom settings option [CHAR LIMIT=60] -->
|
||||
@@ -7262,11 +7262,11 @@
|
||||
<!-- Do not disturb: restrict notifications page, menu option [CHAR LIMIT=60] -->
|
||||
<string name="zen_mode_restrict_notifications_disable_custom">Remove custom setting</string>
|
||||
<!-- Do not disturb: restrict notifications page, menu option [CHAR LIMIT=60] -->
|
||||
<string name="zen_mode_restrict_notifications_summary_muted">Will appear</string>
|
||||
<string name="zen_mode_restrict_notifications_summary_muted">No sound from notifications</string>
|
||||
<!-- Do not disturb: restrict notifications page, menu option [CHAR LIMIT=60] -->
|
||||
<string name="zen_mode_restrict_notifications_summary_custom">Partially hidden</string>
|
||||
<!-- Do not disturb: restrict notifications page, menu option [CHAR LIMIT=60] -->
|
||||
<string name="zen_mode_restrict_notifications_summary_hidden">Hidden</string>
|
||||
<!-- Do not disturb: restrict notifications page, menu option [CHAR LIMIT=100] -->
|
||||
<string name="zen_mode_restrict_notifications_summary_hidden">No visuals or sound from notifications</string>
|
||||
|
||||
<!-- Do not disturb: what to block title [CHAR LIMIT = 60] -->
|
||||
<string name="zen_mode_what_to_block_title">Custom restrictions</string>
|
||||
@@ -7409,7 +7409,7 @@
|
||||
<string name="zen_onboarding_settings">Settings</string>
|
||||
|
||||
<!-- Do not disturb onboarding dialog, title for radio button [CHAR LIMIT=80]-->
|
||||
<string name="zen_onboarding_new_setting_title">No visuals or sounds from notifications</string>
|
||||
<string name="zen_onboarding_new_setting_title">No visuals or sound from notifications</string>
|
||||
<!-- Do not disturb onboarding dialog, title for radio button [CHAR LIMIT=80]-->
|
||||
<string name="zen_onboarding_current_setting_title">No sound from notifications</string>
|
||||
<!-- Do not disturb onboarding dialog, secondary text for radio button [CHAR LIMIT=NONE]-->
|
||||
@@ -9916,7 +9916,7 @@
|
||||
<string name="zen_suggestion_title">Update Do Not Disturb</string>
|
||||
|
||||
<!-- Summary label for dnd suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] -->
|
||||
<string name="zen_suggestion_summary">Hide notifications to stay focused</string>
|
||||
<string name="zen_suggestion_summary">Pause notifications to stay focused</string>
|
||||
|
||||
<!-- Title label for new device suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] -->
|
||||
<string name="new_device_suggestion_title">What\'s new and exciting?</string>
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
<com.android.settings.applications.LayoutPreference
|
||||
android:key="night_display_activated"
|
||||
android:title="@string/night_display_status_title"
|
||||
android:title="@string/night_display_title"
|
||||
android:selectable="false"
|
||||
android:layout="@layout/night_display_activation_button"
|
||||
settings:keywords="@string/keywords_display_night_display"
|
||||
|
||||
@@ -452,8 +452,7 @@ public class RunningProcessesView extends FrameLayout
|
||||
final Context context = getContext();
|
||||
mColorBar.setProgressTintList(
|
||||
ColorStateList.valueOf(context.getColor(R.color.running_processes_system_ram)));
|
||||
mColorBar.setSecondaryProgressTintList(
|
||||
ColorStateList.valueOf(Utils.getColorAccent(context)));
|
||||
mColorBar.setSecondaryProgressTintList(Utils.getColorAccent(context));
|
||||
mColorBar.setSecondaryProgressTintMode(PorterDuff.Mode.SRC);
|
||||
mColorBar.setProgressBackgroundTintList(
|
||||
ColorStateList.valueOf(context.getColor(R.color.running_processes_free_ram)));
|
||||
|
||||
146
src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
Normal file
146
src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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.bluetooth;
|
||||
|
||||
import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.app.PendingIntent;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SubSettings;
|
||||
import com.android.settings.connecteddevice.BluetoothDashboardFragment;
|
||||
import com.android.settings.search.DatabaseIndexingUtils;
|
||||
import com.android.settings.slices.SliceBroadcastReceiver;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
|
||||
/**
|
||||
* Utility class to build a Bluetooth Slice, and handle all associated actions.
|
||||
*/
|
||||
public class BluetoothSliceBuilder {
|
||||
|
||||
private static final String TAG = "BluetoothSliceBuilder";
|
||||
|
||||
/**
|
||||
* Backing Uri for the Bluetooth Slice.
|
||||
*/
|
||||
public static final Uri BLUETOOTH_URI = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsSlicesContract.AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||
.appendPath(SettingsSlicesContract.KEY_BLUETOOTH)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Action notifying a change on the BluetoothSlice.
|
||||
*/
|
||||
public static final String ACTION_BLUETOOTH_SLICE_CHANGED =
|
||||
"com.android.settings.bluetooth.action.BLUETOOTH_MODE_CHANGED";
|
||||
|
||||
public static final IntentFilter INTENT_FILTER = new IntentFilter();
|
||||
|
||||
static {
|
||||
INTENT_FILTER.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
|
||||
INTENT_FILTER.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
|
||||
}
|
||||
|
||||
private BluetoothSliceBuilder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Bluetooth Slice bound to {@link #BLUETOOTH_URI}.
|
||||
* <p>
|
||||
* Note that you should register a listener for {@link #INTENT_FILTER} to get changes for
|
||||
* Bluetooth.
|
||||
*/
|
||||
public static Slice getSlice(Context context) {
|
||||
final boolean isBluetoothEnabled = isBluetoothEnabled(context);
|
||||
final CharSequence title = context.getText(R.string.bluetooth_settings);
|
||||
final IconCompat icon = IconCompat.createWithResource(context,
|
||||
R.drawable.ic_settings_bluetooth);
|
||||
@ColorInt final int color = com.android.settings.Utils.getColorAccent(
|
||||
context).getDefaultColor();
|
||||
final PendingIntent toggleAction = getBroadcastIntent(context);
|
||||
final PendingIntent primaryAction = getPrimaryAction(context);
|
||||
final SliceAction primarySliceAction = new SliceAction(primaryAction, icon, title);
|
||||
final SliceAction toggleSliceAction = new SliceAction(toggleAction, null /* actionTitle */,
|
||||
isBluetoothEnabled);
|
||||
|
||||
return new ListBuilder(context, BLUETOOTH_URI, ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
.addRow(b -> b
|
||||
.setTitle(title)
|
||||
.addEndItem(toggleSliceAction)
|
||||
.setPrimaryAction(primarySliceAction))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current Bluetooth status to the boolean value keyed by
|
||||
* {@link android.app.slice.Slice#EXTRA_TOGGLE_STATE} on {@param intent}.
|
||||
*/
|
||||
public static void handleUriChange(Context context, Intent intent) {
|
||||
final boolean newBluetoothState = intent.getBooleanExtra(EXTRA_TOGGLE_STATE, false);
|
||||
final LocalBluetoothAdapter adapter = LocalBluetoothManager.getInstance(context,
|
||||
null /* callback */).getBluetoothAdapter();
|
||||
|
||||
adapter.setBluetoothEnabled(newBluetoothState);
|
||||
// Do not notifyChange on Uri. The service takes longer to update the current value than it
|
||||
// does for the Slice to check the current value again. Let {@link SliceBroadcastRelay}
|
||||
// handle it.
|
||||
}
|
||||
|
||||
private static boolean isBluetoothEnabled(Context context) {
|
||||
final LocalBluetoothAdapter adapter = LocalBluetoothManager.getInstance(context,
|
||||
null /* callback */).getBluetoothAdapter();
|
||||
return adapter.isEnabled();
|
||||
}
|
||||
|
||||
private static PendingIntent getPrimaryAction(Context context) {
|
||||
final String screenTitle = context.getText(R.string.bluetooth_settings_title).toString();
|
||||
final Uri contentUri = new Uri.Builder().appendPath(
|
||||
SettingsSlicesContract.KEY_BLUETOOTH).build();
|
||||
final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
|
||||
BluetoothDashboardFragment.class.getName(), null /* key */, screenTitle,
|
||||
MetricsProto.MetricsEvent.SETTINGS_CONNECTED_DEVICE_CATEGORY)
|
||||
.setClassName(context.getPackageName(), SubSettings.class.getName())
|
||||
.setData(contentUri);
|
||||
|
||||
return PendingIntent.getActivity(context, 0 /* requestCode */,
|
||||
intent, 0 /* flags */);
|
||||
}
|
||||
|
||||
private static PendingIntent getBroadcastIntent(Context context) {
|
||||
final Intent intent = new Intent(ACTION_BLUETOOTH_SLICE_CHANGED)
|
||||
.setClass(context, SliceBroadcastReceiver.class);
|
||||
return PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,9 @@
|
||||
package com.android.settings.connecteddevice;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.nfc.NfcPreferenceController;
|
||||
@@ -26,6 +28,9 @@ import com.android.settings.nfc.NfcPreferenceController;
|
||||
*/
|
||||
public class AdvancedConnectedDeviceController extends BasePreferenceController {
|
||||
|
||||
private static final String DRIVING_MODE_SETTINGS_ENABLED =
|
||||
"gearhead:driving_mode_settings_enabled";
|
||||
|
||||
public AdvancedConnectedDeviceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
@@ -47,10 +52,15 @@ public class AdvancedConnectedDeviceController extends BasePreferenceController
|
||||
public static int getConnectedDevicesSummaryResourceId(Context context) {
|
||||
final NfcPreferenceController nfcPreferenceController =
|
||||
new NfcPreferenceController(context);
|
||||
final boolean isDrivingModeAvailable = false;
|
||||
|
||||
return getConnectedDevicesSummaryResourceId(nfcPreferenceController,
|
||||
isDrivingModeAvailable);
|
||||
isDrivingModeAvailable(context));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static boolean isDrivingModeAvailable(Context context) {
|
||||
return Settings.System.
|
||||
getInt(context.getContentResolver(), DRIVING_MODE_SETTINGS_ENABLED, 0) == 1;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
@@ -26,8 +26,11 @@ import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.dashboard.SummaryLoader;
|
||||
import com.android.settings.nfc.NfcPreferenceController;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -61,12 +64,32 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment {
|
||||
return R.xml.connected_devices;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
return buildPreferenceControllers(context, getLifecycle());
|
||||
}
|
||||
|
||||
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
|
||||
Lifecycle lifecycle) {
|
||||
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
final DiscoverableFooterPreferenceController discoverableFooterPreferenceController =
|
||||
new DiscoverableFooterPreferenceController(context);
|
||||
controllers.add(discoverableFooterPreferenceController);
|
||||
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(discoverableFooterPreferenceController);
|
||||
}
|
||||
|
||||
return controllers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
use(AvailableMediaDeviceGroupController.class).init(this);
|
||||
use(ConnectedDeviceGroupController.class).init(this);
|
||||
use(PreviouslyConnectedDevicePreferenceController.class).init(this);
|
||||
use(DiscoverableFooterPreferenceController.class).init(this);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -111,6 +134,12 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment {
|
||||
return Arrays.asList(sir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AbstractPreferenceController> createPreferenceControllers(Context
|
||||
context) {
|
||||
return buildPreferenceControllers(context, null /* lifecycle */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNonIndexableKeys(Context context) {
|
||||
List<String> keys = super.getNonIndexableKeys(context);
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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.connecteddevice;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.text.BidiFormatter;
|
||||
import android.text.TextUtils;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.bluetooth.AlwaysDiscoverable;
|
||||
import com.android.settings.bluetooth.Utils;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.widget.FooterPreference;
|
||||
import com.android.settingslib.widget.FooterPreferenceMixin;
|
||||
|
||||
/**
|
||||
* Controller that shows and updates the bluetooth device name
|
||||
*/
|
||||
public class DiscoverableFooterPreferenceController extends BasePreferenceController
|
||||
implements LifecycleObserver, OnResume, OnPause {
|
||||
private static final String KEY = "discoverable_footer_preference";
|
||||
|
||||
@VisibleForTesting
|
||||
BroadcastReceiver mBluetoothChangedReceiver;
|
||||
private FooterPreferenceMixin mFooterPreferenceMixin;
|
||||
private FooterPreference mPreference;
|
||||
private LocalBluetoothManager mLocalManager;
|
||||
private LocalBluetoothAdapter mLocalAdapter;
|
||||
private AlwaysDiscoverable mAlwaysDiscoverable;
|
||||
|
||||
public DiscoverableFooterPreferenceController(Context context) {
|
||||
super(context, KEY);
|
||||
mLocalManager = Utils.getLocalBtManager(context);
|
||||
if (mLocalManager == null) {
|
||||
return;
|
||||
}
|
||||
mLocalAdapter = mLocalManager.getBluetoothAdapter();
|
||||
mAlwaysDiscoverable = new AlwaysDiscoverable(context, mLocalAdapter);
|
||||
initReceiver();
|
||||
}
|
||||
|
||||
private void initReceiver() {
|
||||
mBluetoothChangedReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
|
||||
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
|
||||
BluetoothAdapter.ERROR);
|
||||
updateFooterPreferenceTitle(state);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void init(DashboardFragment fragment) {
|
||||
mFooterPreferenceMixin = new FooterPreferenceMixin(fragment, fragment.getLifecycle());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void init(FooterPreferenceMixin footerPreferenceMixin, FooterPreference preference,
|
||||
AlwaysDiscoverable alwaysDiscoverable) {
|
||||
mFooterPreferenceMixin = footerPreferenceMixin;
|
||||
mPreference = preference;
|
||||
mAlwaysDiscoverable = alwaysDiscoverable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
addFooterPreference(screen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
|
||||
? AVAILABLE
|
||||
: UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
private void addFooterPreference(PreferenceScreen screen) {
|
||||
mPreference = mFooterPreferenceMixin.createFooterPreference();
|
||||
mPreference.setKey(KEY);
|
||||
screen.addPreference(mPreference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
mContext.registerReceiver(mBluetoothChangedReceiver,
|
||||
new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
|
||||
mAlwaysDiscoverable.start();
|
||||
updateFooterPreferenceTitle(mLocalAdapter.getState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
mContext.unregisterReceiver(mBluetoothChangedReceiver);
|
||||
mAlwaysDiscoverable.stop();
|
||||
}
|
||||
|
||||
private void updateFooterPreferenceTitle (int bluetoothState) {
|
||||
if (bluetoothState == BluetoothAdapter.STATE_ON) {
|
||||
mPreference.setTitle(getPreferenceTitle());
|
||||
} else {
|
||||
mPreference.setTitle(R.string.bluetooth_off_footer);
|
||||
}
|
||||
}
|
||||
|
||||
private CharSequence getPreferenceTitle() {
|
||||
final String deviceName = mLocalAdapter.getName();
|
||||
if (TextUtils.isEmpty(deviceName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return TextUtils.expandTemplate(
|
||||
mContext.getText(R.string.bluetooth_device_name_summary),
|
||||
BidiFormatter.getInstance().unicodeWrap(deviceName));
|
||||
}
|
||||
}
|
||||
@@ -120,7 +120,7 @@ public class SuggestionAdapter extends RecyclerView.Adapter<DashboardItemHolder>
|
||||
final Icon icon = suggestion.getIcon();
|
||||
final Drawable drawable = mCache.getIcon(icon);
|
||||
if (drawable != null && (suggestion.getFlags() & Suggestion.FLAG_ICON_TINTABLE) != 0) {
|
||||
drawable.setTint(Utils.getColorAccent(mContext));
|
||||
drawable.setTintList(Utils.getColorAccent(mContext));
|
||||
}
|
||||
holder.icon.setImageDrawable(drawable);
|
||||
holder.title.setText(suggestion.getTitle());
|
||||
|
||||
@@ -162,7 +162,7 @@ public abstract class StorageWizardBase extends Activity {
|
||||
protected void setIcon(int resId) {
|
||||
final GlifLayout layout = getGlifLayout();
|
||||
final Drawable icon = getDrawable(resId).mutate();
|
||||
icon.setTint(Utils.getColorAccent(layout.getContext()));
|
||||
icon.setTintList(Utils.getColorAccent(layout.getContext()));
|
||||
layout.setIcon(icon);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,9 @@ public class ColorModePreferenceController extends BasePreferenceController {
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
final int colorMode = getColorDisplayController().getColorMode();
|
||||
if (colorMode == ColorDisplayController.COLOR_MODE_AUTOMATIC) {
|
||||
return mContext.getText(R.string.color_mode_option_automatic);
|
||||
}
|
||||
if (colorMode == ColorDisplayController.COLOR_MODE_SATURATED) {
|
||||
return mContext.getText(R.string.color_mode_option_saturated);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.widget.RadioButtonPickerFragment;
|
||||
import com.android.settingslib.widget.CandidateInfo;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@@ -39,6 +39,8 @@ public class ColorModePreferenceFragment extends RadioButtonPickerFragment
|
||||
static final String KEY_COLOR_MODE_BOOSTED = "color_mode_boosted";
|
||||
@VisibleForTesting
|
||||
static final String KEY_COLOR_MODE_SATURATED = "color_mode_saturated";
|
||||
@VisibleForTesting
|
||||
static final String KEY_COLOR_MODE_AUTOMATIC = "color_mode_automatic";
|
||||
|
||||
private ColorDisplayController mController;
|
||||
|
||||
@@ -78,21 +80,41 @@ public class ColorModePreferenceFragment extends RadioButtonPickerFragment
|
||||
|
||||
@Override
|
||||
protected List<? extends CandidateInfo> getCandidates() {
|
||||
Context c = getContext();
|
||||
return Arrays.asList(
|
||||
new ColorModeCandidateInfo(c.getText(R.string.color_mode_option_natural),
|
||||
KEY_COLOR_MODE_NATURAL, true /* enabled */),
|
||||
new ColorModeCandidateInfo(c.getText(R.string.color_mode_option_boosted),
|
||||
KEY_COLOR_MODE_BOOSTED, true /* enabled */),
|
||||
new ColorModeCandidateInfo(c.getText(R.string.color_mode_option_saturated),
|
||||
KEY_COLOR_MODE_SATURATED, true /* enabled */)
|
||||
);
|
||||
final Context c = getContext();
|
||||
final int[] availableColorModes = c.getResources().getIntArray(
|
||||
com.android.internal.R.array.config_availableColorModes);
|
||||
|
||||
List<ColorModeCandidateInfo> candidates = new ArrayList<ColorModeCandidateInfo>();
|
||||
if (availableColorModes != null) {
|
||||
for (int colorMode : availableColorModes) {
|
||||
if (colorMode == ColorDisplayController.COLOR_MODE_NATURAL) {
|
||||
candidates.add(new ColorModeCandidateInfo(
|
||||
c.getText(R.string.color_mode_option_natural),
|
||||
KEY_COLOR_MODE_NATURAL, true /* enabled */));
|
||||
} else if (colorMode == ColorDisplayController.COLOR_MODE_BOOSTED) {
|
||||
candidates.add(new ColorModeCandidateInfo(
|
||||
c.getText(R.string.color_mode_option_boosted),
|
||||
KEY_COLOR_MODE_BOOSTED, true /* enabled */));
|
||||
} else if (colorMode == ColorDisplayController.COLOR_MODE_SATURATED) {
|
||||
candidates.add(new ColorModeCandidateInfo(
|
||||
c.getText(R.string.color_mode_option_saturated),
|
||||
KEY_COLOR_MODE_SATURATED, true /* enabled */));
|
||||
} else if (colorMode == ColorDisplayController.COLOR_MODE_AUTOMATIC) {
|
||||
candidates.add(new ColorModeCandidateInfo(
|
||||
c.getText(R.string.color_mode_option_automatic),
|
||||
KEY_COLOR_MODE_AUTOMATIC, true /* enabled */));
|
||||
}
|
||||
}
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultKey() {
|
||||
final int colorMode = mController.getColorMode();
|
||||
if (colorMode == ColorDisplayController.COLOR_MODE_SATURATED) {
|
||||
if (colorMode == ColorDisplayController.COLOR_MODE_AUTOMATIC) {
|
||||
return KEY_COLOR_MODE_AUTOMATIC;
|
||||
} else if (colorMode == ColorDisplayController.COLOR_MODE_SATURATED) {
|
||||
return KEY_COLOR_MODE_SATURATED;
|
||||
} else if (colorMode == ColorDisplayController.COLOR_MODE_BOOSTED) {
|
||||
return KEY_COLOR_MODE_BOOSTED;
|
||||
@@ -112,6 +134,9 @@ public class ColorModePreferenceFragment extends RadioButtonPickerFragment
|
||||
case KEY_COLOR_MODE_SATURATED:
|
||||
mController.setColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
|
||||
break;
|
||||
case KEY_COLOR_MODE_AUTOMATIC:
|
||||
mController.setColorMode(ColorDisplayController.COLOR_MODE_AUTOMATIC);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public class FingerprintLocationAnimationView extends View implements
|
||||
R.fraction.fingerprint_sensor_location_fraction_x, 1, 1);
|
||||
mFractionCenterY = getResources().getFraction(
|
||||
R.fraction.fingerprint_sensor_location_fraction_y, 1, 1);
|
||||
@ColorInt int colorAccent = Utils.getColorAccent(context);
|
||||
@ColorInt int colorAccent = Utils.getColorAccentDefaultColor(context);
|
||||
mDotPaint.setAntiAlias(true);
|
||||
mPulsePaint.setAntiAlias(true);
|
||||
mDotPaint.setColor(colorAccent);
|
||||
|
||||
@@ -129,6 +129,7 @@ public class BackgroundActivityPreferenceController extends AbstractPreferenceCo
|
||||
@VisibleForTesting
|
||||
void showDialog(boolean restricted) {
|
||||
final AppInfo appInfo = new AppInfo.Builder()
|
||||
.setUid(mUid)
|
||||
.setPackageName(mTargetPackage)
|
||||
.build();
|
||||
BatteryTip tip = restricted
|
||||
|
||||
@@ -363,7 +363,7 @@ public class BatteryHistoryChart extends View {
|
||||
mThinLineWidth = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
|
||||
2, getResources().getDisplayMetrics());
|
||||
|
||||
int accentColor = Utils.getColorAccent(mContext);
|
||||
int accentColor = Utils.getColorAccentDefaultColor(mContext);
|
||||
mBatteryBackgroundPaint.setColor(accentColor);
|
||||
mBatteryBackgroundPaint.setStyle(Paint.Style.FILL);
|
||||
mBatteryGoodPaint.setARGB(128, 0, 128, 0);
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.settings.fuelgauge;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -35,6 +34,11 @@ import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipDialogFragment;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
|
||||
import com.android.settings.widget.AppCheckBoxPreference;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.widget.FooterPreferenceMixin;
|
||||
@@ -44,7 +48,8 @@ import java.util.List;
|
||||
/**
|
||||
* Fragment to show a list of anomaly apps, where user could handle these anomalies
|
||||
*/
|
||||
public class RestrictedAppDetails extends DashboardFragment {
|
||||
public class RestrictedAppDetails extends DashboardFragment implements
|
||||
BatteryTipPreferenceController.BatteryTipListener {
|
||||
|
||||
public static final String TAG = "RestrictedAppDetails";
|
||||
|
||||
@@ -143,12 +148,14 @@ public class RestrictedAppDetails extends DashboardFragment {
|
||||
Utils.getBadgedIcon(mIconDrawableFactory, mPackageManager,
|
||||
appInfo.packageName,
|
||||
UserHandle.getUserId(appInfo.uid)));
|
||||
checkBoxPreference.setKey(getKeyFromAppInfo(appInfo));
|
||||
checkBoxPreference.setOnPreferenceChangeListener((pref, value) -> {
|
||||
// change the toggle
|
||||
final int mode = (Boolean) value ? AppOpsManager.MODE_IGNORED
|
||||
: AppOpsManager.MODE_ALLOWED;
|
||||
mBatteryUtils.setForceAppStandby(appInfo.uid, appInfo.packageName, mode);
|
||||
return true;
|
||||
final BatteryTipDialogFragment fragment = createDialogFragment(appInfo,
|
||||
(Boolean) value);
|
||||
fragment.setTargetFragment(this, 0 /* requestCode */);
|
||||
fragment.show(getFragmentManager(), TAG);
|
||||
|
||||
return false;
|
||||
});
|
||||
mRestrictedAppListGroup.addPreference(checkBoxPreference);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
@@ -157,4 +164,35 @@ public class RestrictedAppDetails extends DashboardFragment {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBatteryTipHandled(BatteryTip batteryTip) {
|
||||
final AppInfo appInfo;
|
||||
final boolean isRestricted = batteryTip instanceof RestrictAppTip;
|
||||
if (isRestricted) {
|
||||
appInfo = ((RestrictAppTip) batteryTip).getRestrictAppList().get(0);
|
||||
} else {
|
||||
appInfo = ((UnrestrictAppTip) batteryTip).getUnrestrictAppInfo();
|
||||
}
|
||||
|
||||
CheckBoxPreference preference = (CheckBoxPreference) mRestrictedAppListGroup
|
||||
.findPreference(getKeyFromAppInfo(appInfo));
|
||||
if (preference != null) {
|
||||
preference.setChecked(isRestricted);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
BatteryTipDialogFragment createDialogFragment(AppInfo appInfo, boolean toRestrict) {
|
||||
final BatteryTip batteryTip = toRestrict
|
||||
? new RestrictAppTip(BatteryTip.StateType.NEW, appInfo)
|
||||
: new UnrestrictAppTip(BatteryTip.StateType.NEW, appInfo);
|
||||
|
||||
return BatteryTipDialogFragment.newInstance(
|
||||
batteryTip, getMetricsCategory());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String getKeyFromAppInfo(AppInfo appInfo) {
|
||||
return appInfo.uid + "," + appInfo.packageName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public class RestrictAppAction extends BatteryTipAction {
|
||||
final AppInfo appInfo = appInfos.get(i);
|
||||
final String packageName = appInfo.packageName;
|
||||
// Force app standby, then app can't run in the background
|
||||
mBatteryUtils.setForceAppStandby(mBatteryUtils.getPackageUid(packageName), packageName,
|
||||
mBatteryUtils.setForceAppStandby(appInfo.uid, packageName,
|
||||
AppOpsManager.MODE_IGNORED);
|
||||
if (CollectionUtils.isEmpty(appInfo.anomalyTypes)) {
|
||||
// Only log context if there is no anomaly type
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.util.Pair;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
|
||||
|
||||
/**
|
||||
@@ -44,12 +45,12 @@ public class UnrestrictAppAction extends BatteryTipAction {
|
||||
*/
|
||||
@Override
|
||||
public void handlePositiveAction(int metricsKey) {
|
||||
final String packageName = mUnRestrictAppTip.getPackageName();
|
||||
final AppInfo appInfo = mUnRestrictAppTip.getUnrestrictAppInfo();
|
||||
// Clear force app standby, then app can run in the background
|
||||
mBatteryUtils.setForceAppStandby(mBatteryUtils.getPackageUid(packageName), packageName,
|
||||
mBatteryUtils.setForceAppStandby(appInfo.uid, appInfo.packageName,
|
||||
AppOpsManager.MODE_ALLOWED);
|
||||
mMetricsFeatureProvider.action(mContext,
|
||||
MetricsProto.MetricsEvent.ACTION_TIP_UNRESTRICT_APP, packageName, Pair.create(
|
||||
MetricsProto.MetricsEvent.FIELD_CONTEXT, metricsKey));
|
||||
MetricsProto.MetricsEvent.ACTION_TIP_UNRESTRICT_APP, appInfo.packageName,
|
||||
Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, metricsKey));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,10 @@ public class UnrestrictAppTip extends BatteryTip {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
public AppInfo getUnrestrictAppInfo() {
|
||||
return mAppInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
|
||||
@@ -18,30 +18,30 @@ package com.android.settings.notification;
|
||||
|
||||
import static com.android.settings.widget.EntityHeaderController.PREF_KEY_APP_HEADER;
|
||||
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import androidx.preference.PreferenceFragment;
|
||||
import androidx.preference.Preference;
|
||||
import android.text.BidiFormatter;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
import androidx.preference.PreferenceFragment;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.applications.LayoutPreference;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class HeaderPreferenceController extends NotificationPreferenceController
|
||||
implements PreferenceControllerMixin, LifecycleObserver {
|
||||
|
||||
private final PreferenceFragment mFragment;
|
||||
private EntityHeaderController mHeaderController;
|
||||
private boolean mStarted = false;
|
||||
|
||||
public HeaderPreferenceController(Context context, PreferenceFragment fragment) {
|
||||
super(context, null);
|
||||
@@ -61,6 +61,13 @@ public class HeaderPreferenceController extends NotificationPreferenceController
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
if (mAppRow != null && mFragment != null) {
|
||||
|
||||
Activity activity = null;
|
||||
if (mStarted) {
|
||||
// don't call done on an activity if it hasn't started yet
|
||||
activity = mFragment.getActivity();
|
||||
}
|
||||
|
||||
LayoutPreference pref = (LayoutPreference) preference;
|
||||
mHeaderController = EntityHeaderController.newInstance(
|
||||
mFragment.getActivity(), mFragment, pref.findViewById(R.id.entity_header));
|
||||
@@ -72,7 +79,7 @@ public class HeaderPreferenceController extends NotificationPreferenceController
|
||||
.setButtonActions(EntityHeaderController.ActionType.ACTION_NOTIF_PREFERENCE,
|
||||
EntityHeaderController.ActionType.ACTION_NONE)
|
||||
.setHasAppInfoLink(true)
|
||||
.done(null, mContext);
|
||||
.done(activity, mContext);
|
||||
pref.findViewById(R.id.entity_header).setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
@@ -108,6 +115,7 @@ public class HeaderPreferenceController extends NotificationPreferenceController
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_START)
|
||||
public void onStart() {
|
||||
mStarted = true;
|
||||
if (mHeaderController != null) {
|
||||
mHeaderController.styleActionBar(mFragment.getActivity());
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public class ZenModeSliceBuilder {
|
||||
public static Slice getSlice(Context context) {
|
||||
final boolean isZenModeEnabled = isZenModeEnabled(context);
|
||||
final CharSequence title = context.getText(R.string.zen_mode_settings_title);
|
||||
@ColorInt final int color = Utils.getColorAccent(context);
|
||||
@ColorInt final int color = Utils.getColorAccentDefaultColor(context);
|
||||
final PendingIntent toggleAction = getBroadcastIntent(context);
|
||||
final PendingIntent primaryAction = getPrimaryAction(context);
|
||||
final SliceAction primarySliceAction = new SliceAction(primaryAction,
|
||||
|
||||
@@ -28,6 +28,8 @@ public class ZenModeVisEffectsAllPreferenceController
|
||||
extends AbstractZenModePreferenceController
|
||||
implements ZenCustomRadioButtonPreference.OnRadioButtonClickListener {
|
||||
|
||||
private ZenCustomRadioButtonPreference mPreference;
|
||||
|
||||
protected static final int EFFECTS = Policy.SUPPRESSED_EFFECT_SCREEN_OFF
|
||||
| Policy.SUPPRESSED_EFFECT_SCREEN_ON
|
||||
| Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
|
||||
@@ -43,6 +45,13 @@ public class ZenModeVisEffectsAllPreferenceController
|
||||
super(context, key, lifecycle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
|
||||
mPreference.setOnRadioButtonClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
@@ -54,17 +63,7 @@ public class ZenModeVisEffectsAllPreferenceController
|
||||
|
||||
boolean everythingBlocked = Policy.areAllVisualEffectsSuppressed(
|
||||
mBackend.mPolicy.suppressedVisualEffects);
|
||||
ZenCustomRadioButtonPreference pref = (ZenCustomRadioButtonPreference) preference;
|
||||
pref.setOnRadioButtonClickListener(this);
|
||||
pref.setChecked(everythingBlocked);
|
||||
}
|
||||
|
||||
protected void deselect(PreferenceScreen screen) {
|
||||
ZenCustomRadioButtonPreference preference =
|
||||
(ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
|
||||
if (preference != null) {
|
||||
preference.setChecked(false);
|
||||
}
|
||||
mPreference.setChecked(everythingBlocked);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
|
||||
package com.android.settings.notification;
|
||||
|
||||
import android.app.NotificationManager.Policy;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
@@ -30,10 +29,13 @@ import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
public class ZenModeVisEffectsCustomPreferenceController
|
||||
extends AbstractZenModePreferenceController {
|
||||
|
||||
protected static final int INTERRUPTIVE_EFFECTS = Policy.SUPPRESSED_EFFECT_AMBIENT
|
||||
| Policy.SUPPRESSED_EFFECT_PEEK
|
||||
| Policy.SUPPRESSED_EFFECT_LIGHTS
|
||||
| Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
|
||||
private ZenCustomRadioButtonPreference mPreference;
|
||||
|
||||
protected static final int INTERRUPTIVE_EFFECTS =
|
||||
NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT
|
||||
| NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK
|
||||
| NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS
|
||||
| NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
|
||||
|
||||
public ZenModeVisEffectsCustomPreferenceController(Context context, Lifecycle lifecycle,
|
||||
String key) {
|
||||
@@ -46,25 +48,31 @@ public class ZenModeVisEffectsCustomPreferenceController
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
|
||||
|
||||
ZenCustomRadioButtonPreference pref = (ZenCustomRadioButtonPreference) preference;
|
||||
pref.setChecked(areCustomOptionsSelected());
|
||||
|
||||
pref.setOnGearClickListener(p -> {
|
||||
mPreference.setOnGearClickListener(p -> {
|
||||
launchCustomSettings();
|
||||
|
||||
});
|
||||
|
||||
pref.setOnRadioButtonClickListener(p -> {
|
||||
mPreference.setOnRadioButtonClickListener(p -> {
|
||||
launchCustomSettings();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
|
||||
mPreference.setChecked(areCustomOptionsSelected());
|
||||
}
|
||||
|
||||
protected boolean areCustomOptionsSelected() {
|
||||
boolean allEffectsSuppressed =
|
||||
Policy.areAllVisualEffectsSuppressed(mBackend.mPolicy.suppressedVisualEffects);
|
||||
NotificationManager.Policy.areAllVisualEffectsSuppressed(
|
||||
mBackend.mPolicy.suppressedVisualEffects);
|
||||
boolean noEffectsSuppressed = mBackend.mPolicy.suppressedVisualEffects == 0;
|
||||
|
||||
return !(allEffectsSuppressed || noEffectsSuppressed);
|
||||
|
||||
@@ -28,6 +28,8 @@ public class ZenModeVisEffectsNonePreferenceController
|
||||
extends AbstractZenModePreferenceController
|
||||
implements ZenCustomRadioButtonPreference.OnRadioButtonClickListener {
|
||||
|
||||
private ZenCustomRadioButtonPreference mPreference;
|
||||
|
||||
protected static final int EFFECTS = Policy.SUPPRESSED_EFFECT_SCREEN_OFF
|
||||
| Policy.SUPPRESSED_EFFECT_SCREEN_ON
|
||||
| Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
|
||||
@@ -43,6 +45,13 @@ public class ZenModeVisEffectsNonePreferenceController
|
||||
super(context, key, lifecycle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
|
||||
mPreference.setOnRadioButtonClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
@@ -53,9 +62,7 @@ public class ZenModeVisEffectsNonePreferenceController
|
||||
super.updateState(preference);
|
||||
|
||||
boolean nothingBlocked = mBackend.mPolicy.suppressedVisualEffects == 0;
|
||||
ZenCustomRadioButtonPreference pref = (ZenCustomRadioButtonPreference) preference;
|
||||
pref.setOnRadioButtonClickListener(this);
|
||||
pref.setChecked(nothingBlocked);
|
||||
mPreference.setChecked(nothingBlocked);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,12 +71,4 @@ public class ZenModeVisEffectsNonePreferenceController
|
||||
MetricsProto.MetricsEvent.ACTION_ZEN_SOUND_ONLY, true);
|
||||
mBackend.saveVisualEffectsPolicy(EFFECTS, false);
|
||||
}
|
||||
|
||||
protected void deselect(PreferenceScreen screen) {
|
||||
ZenCustomRadioButtonPreference preference =
|
||||
(ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
|
||||
if (preference != null) {
|
||||
preference.setChecked(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.wifi.WifiSliceBuilder;
|
||||
import com.android.settings.wifi.calling.WifiCallingSliceHelper;
|
||||
import com.android.settings.bluetooth.BluetoothSliceBuilder;
|
||||
import com.android.settings.notification.ZenModeSliceBuilder;
|
||||
import com.android.settingslib.SliceBroadcastRelay;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
@@ -147,7 +148,9 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
return;
|
||||
} else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
|
||||
registerIntentToUri(ZenModeSliceBuilder.INTENT_FILTER, sliceUri);
|
||||
mRegisteredUris.add(sliceUri);
|
||||
return;
|
||||
} else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
|
||||
registerIntentToUri(BluetoothSliceBuilder.INTENT_FILTER, sliceUri);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -178,6 +181,8 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
return WifiSliceBuilder.getSlice(getContext());
|
||||
} else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
|
||||
return ZenModeSliceBuilder.getSlice(getContext());
|
||||
} else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
|
||||
return BluetoothSliceBuilder.getSlice(getContext());
|
||||
}
|
||||
|
||||
SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);
|
||||
@@ -325,7 +330,8 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
|
||||
private List<Uri> getSpecialCasePlatformUris() {
|
||||
return Arrays.asList(
|
||||
WifiSliceBuilder.WIFI_URI
|
||||
WifiSliceBuilder.WIFI_URI,
|
||||
BluetoothSliceBuilder.BLUETOOTH_URI
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settings.slices;
|
||||
|
||||
import static com.android.settings.bluetooth.BluetoothSliceBuilder.ACTION_BLUETOOTH_SLICE_CHANGED;
|
||||
import static com.android.settings.notification.ZenModeSliceBuilder.ACTION_ZEN_MODE_SLICE_CHANGED;
|
||||
import static com.android.settings.slices.SettingsSliceProvider.ACTION_SLIDER_CHANGED;
|
||||
import static com.android.settings.slices.SettingsSliceProvider.ACTION_TOGGLE_CHANGED;
|
||||
@@ -35,6 +36,7 @@ import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.bluetooth.BluetoothSliceBuilder;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.SliderPreferenceController;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
@@ -66,6 +68,9 @@ public class SliceBroadcastReceiver extends BroadcastReceiver {
|
||||
final int newPosition = intent.getIntExtra(Slice.EXTRA_RANGE_VALUE, -1);
|
||||
handleSliderAction(context, key, newPosition, isPlatformSlice);
|
||||
break;
|
||||
case ACTION_BLUETOOTH_SLICE_CHANGED:
|
||||
BluetoothSliceBuilder.handleUriChange(context, intent);
|
||||
break;
|
||||
case ACTION_WIFI_SLICE_CHANGED:
|
||||
WifiSliceBuilder.handleUriChange(context, intent);
|
||||
break;
|
||||
|
||||
@@ -238,7 +238,7 @@ public class SliceBuilderUtils {
|
||||
final PendingIntent contentIntent = getContentPendingIntent(context, sliceData);
|
||||
final IconCompat icon = IconCompat.createWithResource(context, sliceData.getIconResource());
|
||||
final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
|
||||
@ColorInt final int color = Utils.getColorAccent(context);
|
||||
@ColorInt final int color = Utils.getColorAccentDefaultColor(context);
|
||||
final TogglePreferenceController toggleController =
|
||||
(TogglePreferenceController) controller;
|
||||
final SliceAction sliceAction = getToggleAction(context, sliceData,
|
||||
@@ -262,7 +262,7 @@ public class SliceBuilderUtils {
|
||||
final PendingIntent contentIntent = getContentPendingIntent(context, sliceData);
|
||||
final IconCompat icon = IconCompat.createWithResource(context, sliceData.getIconResource());
|
||||
final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
|
||||
@ColorInt final int color = Utils.getColorAccent(context);
|
||||
@ColorInt final int color = Utils.getColorAccentDefaultColor(context);
|
||||
final List<String> keywords = buildSliceKeywords(sliceData);
|
||||
|
||||
return new ListBuilder(context, sliceData.getUri(), ListBuilder.INFINITY)
|
||||
@@ -282,7 +282,7 @@ public class SliceBuilderUtils {
|
||||
final PendingIntent actionIntent = getSliderAction(context, sliceData);
|
||||
final PendingIntent contentIntent = getContentPendingIntent(context, sliceData);
|
||||
final IconCompat icon = IconCompat.createWithResource(context, sliceData.getIconResource());
|
||||
@ColorInt final int color = Utils.getColorAccent(context);
|
||||
@ColorInt final int color = Utils.getColorAccentDefaultColor(context);
|
||||
final SliceAction primaryAction = new SliceAction(contentIntent, icon,
|
||||
sliceData.getTitle());
|
||||
final List<String> keywords = buildSliceKeywords(sliceData);
|
||||
@@ -359,7 +359,7 @@ public class SliceBuilderUtils {
|
||||
BasePreferenceController controller) {
|
||||
final String title = data.getTitle();
|
||||
final List<String> keywords = buildSliceKeywords(data);
|
||||
@ColorInt final int color = Utils.getColorAccent(context);
|
||||
@ColorInt final int color = Utils.getColorAccentDefaultColor(context);
|
||||
final String summary;
|
||||
final SliceAction primaryAction;
|
||||
final IconCompat icon = IconCompat.createWithResource(context, data.getIconResource());
|
||||
|
||||
@@ -41,6 +41,7 @@ import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import android.text.TextUtils;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.Utils;
|
||||
@@ -59,6 +60,8 @@ import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
/**
|
||||
* Abstract class for audio switcher controller to notify subclass
|
||||
@@ -70,21 +73,22 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
|
||||
implements Preference.OnPreferenceChangeListener, BluetoothCallback,
|
||||
LifecycleObserver, OnStart, OnStop {
|
||||
|
||||
private static final String TAG = "AudioSwitchPreferenceController";
|
||||
private static final int INVALID_INDEX = -1;
|
||||
|
||||
protected final List<BluetoothDevice> mConnectedDevices;
|
||||
protected final AudioManager mAudioManager;
|
||||
protected final MediaRouter mMediaRouter;
|
||||
protected final LocalBluetoothProfileManager mProfileManager;
|
||||
protected int mSelectedIndex;
|
||||
protected Preference mPreference;
|
||||
protected LocalBluetoothProfileManager mProfileManager;
|
||||
protected AudioSwitchCallback mAudioSwitchPreferenceCallback;
|
||||
|
||||
private final AudioManagerAudioDeviceCallback mAudioManagerAudioDeviceCallback;
|
||||
private final LocalBluetoothManager mLocalBluetoothManager;
|
||||
private final MediaRouterCallback mMediaRouterCallback;
|
||||
private final WiredHeadsetBroadcastReceiver mReceiver;
|
||||
private final Handler mHandler;
|
||||
private LocalBluetoothManager mLocalBluetoothManager;
|
||||
|
||||
public interface AudioSwitchCallback {
|
||||
void onPreferenceDataChanged(ListPreference preference);
|
||||
@@ -94,14 +98,23 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
|
||||
super(context, preferenceKey);
|
||||
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
mMediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
|
||||
mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
|
||||
mLocalBluetoothManager.setForegroundActivity(context);
|
||||
mProfileManager = mLocalBluetoothManager.getProfileManager();
|
||||
mHandler = new Handler(Looper.getMainLooper());
|
||||
mAudioManagerAudioDeviceCallback = new AudioManagerAudioDeviceCallback();
|
||||
mReceiver = new WiredHeadsetBroadcastReceiver();
|
||||
mMediaRouterCallback = new MediaRouterCallback();
|
||||
mConnectedDevices = new ArrayList<>();
|
||||
final FutureTask<LocalBluetoothManager> localBtManagerFutureTask = new FutureTask<>(
|
||||
// Avoid StrictMode ThreadPolicy violation
|
||||
() -> Utils.getLocalBtManager(mContext));
|
||||
try {
|
||||
localBtManagerFutureTask.run();
|
||||
mLocalBluetoothManager = localBtManagerFutureTask.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
Log.w(TAG, "Error getting LocalBluetoothManager.", e);
|
||||
return;
|
||||
}
|
||||
mLocalBluetoothManager.setForegroundActivity(mContext);
|
||||
mProfileManager = mLocalBluetoothManager.getProfileManager();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -122,7 +122,7 @@ public class DonutView extends View {
|
||||
: Paint.BIDI_RTL;
|
||||
|
||||
mTextPaint = new TextPaint();
|
||||
mTextPaint.setColor(Utils.getColorAccent(getContext()));
|
||||
mTextPaint.setColor(Utils.getColorAccentDefaultColor(getContext()));
|
||||
mTextPaint.setAntiAlias(true);
|
||||
mTextPaint.setTextSize(
|
||||
resources.getDimension(R.dimen.storage_donut_view_label_text_size));
|
||||
@@ -130,7 +130,7 @@ public class DonutView extends View {
|
||||
mTextPaint.setBidiFlags(bidiFlags);
|
||||
|
||||
mBigNumberPaint = new TextPaint();
|
||||
mBigNumberPaint.setColor(Utils.getColorAccent(getContext()));
|
||||
mBigNumberPaint.setColor(Utils.getColorAccentDefaultColor(getContext()));
|
||||
mBigNumberPaint.setAntiAlias(true);
|
||||
mBigNumberPaint.setTextSize(
|
||||
resources.getDimension(R.dimen.storage_donut_view_percent_text_size));
|
||||
|
||||
@@ -31,9 +31,11 @@ import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.IconDrawableFactory;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -87,7 +87,7 @@ public class WifiSliceBuilder {
|
||||
R.drawable.ic_settings_wireless);
|
||||
final String title = context.getString(R.string.wifi_settings);
|
||||
final CharSequence summary = getSummary(context);
|
||||
@ColorInt final int color = Utils.getColorAccent(context);
|
||||
@ColorInt final int color = Utils.getColorAccentDefaultColor(context);
|
||||
final PendingIntent toggleAction = getBroadcastIntent(context);
|
||||
final PendingIntent primaryAction = getPrimaryAction(context);
|
||||
final SliceAction primarySliceAction = new SliceAction(primaryAction, icon, title);
|
||||
|
||||
@@ -406,7 +406,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
|
||||
mRssiSignalLevel = signalLevel;
|
||||
Drawable wifiIcon = mIconInjector.getIcon(mRssiSignalLevel);
|
||||
|
||||
wifiIcon.setTint(Utils.getColorAccent(mContext));
|
||||
wifiIcon.setTintList(Utils.getColorAccent(mContext));
|
||||
mEntityHeaderController.setIcon(wifiIcon).done(mFragment.getActivity(), true /* rebind */);
|
||||
|
||||
Drawable wifiIconDark = wifiIcon.getConstantState().newDrawable().mutate();
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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.bluetooth;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.SliceTester;
|
||||
import com.android.settings.testutils.shadow.ShadowLocalBluetoothAdapter;
|
||||
import com.android.settings.testutils.shadow.ShadowLocalBluetoothProfileManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceItem;
|
||||
import androidx.slice.SliceMetadata;
|
||||
import androidx.slice.SliceProvider;
|
||||
import androidx.slice.core.SliceAction;
|
||||
import androidx.slice.widget.SliceLiveData;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowLocalBluetoothAdapter.class, ShadowLocalBluetoothProfileManager.class})
|
||||
public class BluetoothSliceBuilderTest {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
|
||||
// Prevent crash in SliceMetadata.
|
||||
Resources resources = spy(mContext.getResources());
|
||||
doReturn(60).when(resources).getDimensionPixelSize(anyInt());
|
||||
doReturn(resources).when(mContext).getResources();
|
||||
|
||||
// Set-up specs for SliceMetadata.
|
||||
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getBluetoothSlice_correctSliceContent() {
|
||||
final Slice BluetoothSlice = BluetoothSliceBuilder.getSlice(mContext);
|
||||
final SliceMetadata metadata = SliceMetadata.from(mContext, BluetoothSlice);
|
||||
|
||||
final List<SliceAction> toggles = metadata.getToggles();
|
||||
assertThat(toggles).hasSize(1);
|
||||
|
||||
final SliceAction primaryAction = metadata.getPrimaryAction();
|
||||
final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext,
|
||||
R.drawable.ic_settings_bluetooth);
|
||||
assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString());
|
||||
|
||||
final List<SliceItem> sliceItems = BluetoothSlice.getItems();
|
||||
SliceTester.assertTitle(sliceItems, mContext.getString(R.string.bluetooth_settings_title));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleUriChange_updatesBluetooth() {
|
||||
final LocalBluetoothAdapter adapter = LocalBluetoothManager.getInstance(mContext,
|
||||
null /* callback */).getBluetoothAdapter();
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(android.app.slice.Slice.EXTRA_TOGGLE_STATE, true);
|
||||
adapter.setBluetoothEnabled(false /* enabled */);
|
||||
|
||||
BluetoothSliceBuilder.handleUriChange(mContext, intent);
|
||||
|
||||
assertThat(adapter.isEnabled()).isTrue();
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,9 @@ package com.android.settings.connecteddevice;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.nfc.NfcPreferenceController;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
@@ -39,16 +41,20 @@ import static org.robolectric.Shadows.shadowOf;
|
||||
public class AdvancedConnectedDeviceControllerTest {
|
||||
|
||||
private static final String KEY = "test_key";
|
||||
private static final String DRIVING_MODE_SETTINGS_ENABLED =
|
||||
"gearhead:driving_mode_settings_enabled";
|
||||
|
||||
private Context mContext;
|
||||
private NfcPreferenceController mNfcController;
|
||||
private ShadowNfcAdapter mShadowNfcAdapter;
|
||||
private ContentResolver mContentResolver;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mContentResolver = mContext.getContentResolver();
|
||||
mNfcController = new NfcPreferenceController(mContext);
|
||||
mShadowNfcAdapter = shadowOf(ShadowNfcAdapter.getNfcAdapter(mContext));
|
||||
}
|
||||
@@ -62,43 +68,53 @@ public class AdvancedConnectedDeviceControllerTest {
|
||||
AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isDrivingModeAvailable_returnTrue() {
|
||||
Settings.System.putInt(mContentResolver, DRIVING_MODE_SETTINGS_ENABLED, 1);
|
||||
|
||||
assertThat(AdvancedConnectedDeviceController.isDrivingModeAvailable(mContext)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isDrivingModeAvailable_returnFalse() {
|
||||
Settings.System.putInt(mContentResolver, DRIVING_MODE_SETTINGS_ENABLED, 0);
|
||||
|
||||
assertThat(AdvancedConnectedDeviceController.isDrivingModeAvailable(mContext)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConnectedDevicesSummaryResourceId_NFCAndDrivingModeAvailable() {
|
||||
// NFC available, driving mode available
|
||||
final boolean isDrivingModeAvailable = true;
|
||||
mShadowNfcAdapter.setEnabled(true);
|
||||
assertThat(AdvancedConnectedDeviceController
|
||||
.getConnectedDevicesSummaryResourceId(mNfcController, isDrivingModeAvailable))
|
||||
.getConnectedDevicesSummaryResourceId(mNfcController, true))
|
||||
.isEqualTo(R.string.connected_devices_dashboard_summary);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConnectedDevicesSummaryResourceId_NFCAvailableAndDrivingModeNotAvailable() {
|
||||
// NFC is available, driving mode not available
|
||||
final boolean isDrivingModeAvailable = false;
|
||||
mShadowNfcAdapter.setEnabled(true);
|
||||
assertThat(AdvancedConnectedDeviceController
|
||||
.getConnectedDevicesSummaryResourceId(mNfcController, isDrivingModeAvailable))
|
||||
.getConnectedDevicesSummaryResourceId(mNfcController, false))
|
||||
.isEqualTo(R.string.connected_devices_dashboard_no_driving_mode_summary);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConnectedDevicesSummaryResourceId_NFCNotAvailableDrivingModeAvailable() {
|
||||
// NFC not available, driving mode available
|
||||
final boolean isDrivingModeAvailable = true;
|
||||
ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null);
|
||||
assertThat(AdvancedConnectedDeviceController
|
||||
.getConnectedDevicesSummaryResourceId(mNfcController, isDrivingModeAvailable))
|
||||
.getConnectedDevicesSummaryResourceId(mNfcController, true))
|
||||
.isEqualTo(R.string.connected_devices_dashboard_no_nfc_summary);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConnectedDevicesSummaryResourceId_NFCAndDrivingModeNotAvailable() {
|
||||
// NFC not available, driving mode not available
|
||||
final boolean isDrivingModeAvailable = false;
|
||||
ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null);
|
||||
assertThat(AdvancedConnectedDeviceController
|
||||
.getConnectedDevicesSummaryResourceId(mNfcController, isDrivingModeAvailable))
|
||||
.getConnectedDevicesSummaryResourceId(mNfcController, false))
|
||||
.isEqualTo(R.string.connected_devices_dashboard_no_driving_mode_no_nfc_summary);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.provider.SearchIndexableResource;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothPan;
|
||||
import com.android.settings.testutils.shadow.ShadowConnectivityManager;
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
@@ -47,7 +48,7 @@ import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowBluetoothPan.class, ShadowUserManager.class,
|
||||
ShadowConnectivityManager.class})
|
||||
ShadowConnectivityManager.class, ShadowBluetoothAdapter.class})
|
||||
public class ConnectedDeviceDashboardFragmentTest {
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright 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.connecteddevice;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.text.BidiFormatter;
|
||||
import android.text.TextUtils;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.bluetooth.AlwaysDiscoverable;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothPan;
|
||||
import com.android.settings.testutils.shadow.ShadowLocalBluetoothAdapter;
|
||||
import com.android.settingslib.widget.FooterPreference;
|
||||
import com.android.settingslib.widget.FooterPreferenceMixin;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowBluetoothPan.class, ShadowBluetoothAdapter.class,
|
||||
ShadowLocalBluetoothAdapter.class})
|
||||
public class DiscoverableFooterPreferenceControllerTest {
|
||||
private static final String DEVICE_NAME = "device name";
|
||||
private static final String KEY = "discoverable_footer_preference";
|
||||
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
@Mock
|
||||
private FooterPreferenceMixin mFooterPreferenceMixin;
|
||||
@Mock
|
||||
private AlwaysDiscoverable mAlwaysDiscoverable;
|
||||
|
||||
private Context mContext;
|
||||
private FooterPreference mPreference;
|
||||
private DiscoverableFooterPreferenceController mDiscoverableFooterPreferenceController;
|
||||
private BroadcastReceiver mBluetoothChangedReceiver;
|
||||
private ShadowApplication mShadowApplication;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mShadowApplication = Shadows.shadowOf(RuntimeEnvironment.application);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
|
||||
doReturn(mPackageManager).when(mContext).getPackageManager();
|
||||
mDiscoverableFooterPreferenceController =
|
||||
new DiscoverableFooterPreferenceController(mContext);
|
||||
mPreference = spy(new FooterPreference(mContext));
|
||||
mDiscoverableFooterPreferenceController.init(mFooterPreferenceMixin, mPreference,
|
||||
mAlwaysDiscoverable);
|
||||
mBluetoothChangedReceiver = mDiscoverableFooterPreferenceController
|
||||
.mBluetoothChangedReceiver;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_noBluetoothFeature_returnUnSupported() {
|
||||
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)).thenReturn(false);
|
||||
|
||||
assertThat(mDiscoverableFooterPreferenceController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.UNSUPPORTED_ON_DEVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_BluetoothFeature_returnAvailable() {
|
||||
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)).thenReturn(true);
|
||||
|
||||
assertThat(mDiscoverableFooterPreferenceController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference() {
|
||||
when(mFooterPreferenceMixin.createFooterPreference()).thenReturn(mPreference);
|
||||
mDiscoverableFooterPreferenceController.displayPreference(mScreen);
|
||||
|
||||
verify(mPreference).setKey(KEY);
|
||||
verify(mScreen).addPreference(mPreference);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onResume() {
|
||||
mDiscoverableFooterPreferenceController.onResume();
|
||||
assertThat(getRegisteredBroadcastReceivers()).contains(mBluetoothChangedReceiver);
|
||||
verify(mAlwaysDiscoverable).start();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPause() {
|
||||
mDiscoverableFooterPreferenceController.onResume();
|
||||
mDiscoverableFooterPreferenceController.onPause();
|
||||
|
||||
assertThat(getRegisteredBroadcastReceivers()).doesNotContain(mBluetoothChangedReceiver);
|
||||
verify(mAlwaysDiscoverable).stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBluetoothStateChanged_bluetoothOn_updateTitle() {
|
||||
ShadowLocalBluetoothAdapter.setName(DEVICE_NAME);
|
||||
sendBluetoothStateChangedIntent(BluetoothAdapter.STATE_ON);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(generateTitle(DEVICE_NAME));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBluetoothStateChanged_bluetoothOff_updateTitle(){
|
||||
ShadowLocalBluetoothAdapter.setName(DEVICE_NAME);
|
||||
sendBluetoothStateChangedIntent(BluetoothAdapter.STATE_OFF);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(generateTitle(null));
|
||||
}
|
||||
|
||||
private CharSequence generateTitle(String deviceName) {
|
||||
if (deviceName == null) {
|
||||
return mContext.getString(R.string.bluetooth_off_footer);
|
||||
|
||||
} else {
|
||||
return TextUtils.expandTemplate(
|
||||
mContext.getText(R.string.bluetooth_device_name_summary),
|
||||
BidiFormatter.getInstance().unicodeWrap(deviceName));
|
||||
}
|
||||
}
|
||||
|
||||
private void sendBluetoothStateChangedIntent(int state) {
|
||||
Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
|
||||
intent.putExtra(BluetoothAdapter.EXTRA_STATE, state);
|
||||
mBluetoothChangedReceiver.onReceive(mContext, intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of all the registered broadcast receivers
|
||||
*/
|
||||
private List<BroadcastReceiver> getRegisteredBroadcastReceivers() {
|
||||
List<BroadcastReceiver> registeredBroadcastReceivers = new ArrayList();
|
||||
List<ShadowApplication.Wrapper> registeredReceivers =
|
||||
mShadowApplication.getRegisteredReceivers();
|
||||
for (ShadowApplication.Wrapper wrapper : registeredReceivers) {
|
||||
registeredBroadcastReceivers.add(wrapper.getBroadcastReceiver());
|
||||
}
|
||||
return registeredBroadcastReceivers;
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.service.settings.suggestions.Suggestion;
|
||||
@@ -47,6 +48,7 @@ import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.ShadowCardView;
|
||||
import com.android.settingslib.suggestions.SuggestionControllerMixin;
|
||||
import com.android.settingslib.utils.IconCache;
|
||||
import com.android.settingslib.Utils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -282,13 +284,13 @@ public class SuggestionAdapterTest {
|
||||
when(cache.getIcon(icon)).thenReturn(drawable);
|
||||
ReflectionHelpers.setField(mSuggestionAdapter, "mCache", cache);
|
||||
TypedArray typedArray = mock(TypedArray.class);
|
||||
final int colorAccent = 1234;
|
||||
final ColorStateList colorAccentState = Utils.getColorAccent(mContext);
|
||||
when(mActivity.obtainStyledAttributes(any())).thenReturn(typedArray);
|
||||
when(typedArray.getColor(anyInt(), anyInt())).thenReturn(colorAccent);
|
||||
when(typedArray.getColorStateList(anyInt())).thenReturn(colorAccentState);
|
||||
|
||||
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
|
||||
|
||||
verify(drawable).setTint(colorAccent);
|
||||
verify(drawable).setTintList(colorAccentState);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -54,6 +54,16 @@ public class ColorModePreferenceControllerTest {
|
||||
doReturn(mColorDisplayController).when(mController).getColorDisplayController();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_colorModeAutomatic_shouldSetSummaryToAutomatic() {
|
||||
when(mColorDisplayController.getColorMode())
|
||||
.thenReturn(ColorDisplayController.COLOR_MODE_AUTOMATIC);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setSummary(mContext.getString(R.string.color_mode_option_automatic));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_colorModeSaturated_shouldSetSummaryToSaturated() {
|
||||
when(mColorDisplayController.getColorMode())
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.applications.LayoutPreference;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||
import com.android.settingslib.widget.CandidateInfo;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -43,11 +44,13 @@ import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(shadows = SettingsShadowResources.class)
|
||||
public class ColorModePreferenceFragmentTest {
|
||||
|
||||
private ColorModePreferenceFragment mFragment;
|
||||
@@ -73,8 +76,64 @@ public class ColorModePreferenceFragmentTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCandidates() {
|
||||
public void getCandidates_all() {
|
||||
when(mFragment.getContext()).thenReturn(RuntimeEnvironment.application);
|
||||
SettingsShadowResources.overrideResource(
|
||||
com.android.internal.R.array.config_availableColorModes, new int[]{
|
||||
ColorDisplayController.COLOR_MODE_NATURAL,
|
||||
ColorDisplayController.COLOR_MODE_BOOSTED,
|
||||
ColorDisplayController.COLOR_MODE_SATURATED,
|
||||
ColorDisplayController.COLOR_MODE_AUTOMATIC
|
||||
});
|
||||
List<? extends CandidateInfo> candidates = mFragment.getCandidates();
|
||||
|
||||
assertThat(candidates.size()).isEqualTo(4);
|
||||
assertThat(candidates.get(0).getKey())
|
||||
.isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_NATURAL);
|
||||
assertThat(candidates.get(1).getKey())
|
||||
.isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_BOOSTED);
|
||||
assertThat(candidates.get(2).getKey())
|
||||
.isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_SATURATED);
|
||||
assertThat(candidates.get(3).getKey())
|
||||
.isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_AUTOMATIC);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCandidates_none() {
|
||||
when(mFragment.getContext()).thenReturn(RuntimeEnvironment.application);
|
||||
SettingsShadowResources.overrideResource(
|
||||
com.android.internal.R.array.config_availableColorModes, null);
|
||||
List<? extends CandidateInfo> candidates = mFragment.getCandidates();
|
||||
|
||||
assertThat(candidates.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCandidates_withAutomatic() {
|
||||
when(mFragment.getContext()).thenReturn(RuntimeEnvironment.application);
|
||||
SettingsShadowResources.overrideResource(
|
||||
com.android.internal.R.array.config_availableColorModes, new int[]{
|
||||
ColorDisplayController.COLOR_MODE_NATURAL,
|
||||
ColorDisplayController.COLOR_MODE_AUTOMATIC
|
||||
});
|
||||
List<? extends CandidateInfo> candidates = mFragment.getCandidates();
|
||||
|
||||
assertThat(candidates.size()).isEqualTo(2);
|
||||
assertThat(candidates.get(0).getKey())
|
||||
.isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_NATURAL);
|
||||
assertThat(candidates.get(1).getKey())
|
||||
.isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_AUTOMATIC);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCandidates_withoutAutomatic() {
|
||||
when(mFragment.getContext()).thenReturn(RuntimeEnvironment.application);
|
||||
SettingsShadowResources.overrideResource(
|
||||
com.android.internal.R.array.config_availableColorModes, new int[]{
|
||||
ColorDisplayController.COLOR_MODE_NATURAL,
|
||||
ColorDisplayController.COLOR_MODE_BOOSTED,
|
||||
ColorDisplayController.COLOR_MODE_SATURATED,
|
||||
});
|
||||
List<? extends CandidateInfo> candidates = mFragment.getCandidates();
|
||||
|
||||
assertThat(candidates.size()).isEqualTo(3);
|
||||
@@ -113,6 +172,15 @@ public class ColorModePreferenceFragmentTest {
|
||||
.isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_SATURATED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getKey_automatic() {
|
||||
when(mController.getColorMode())
|
||||
.thenReturn(ColorDisplayController.COLOR_MODE_AUTOMATIC);
|
||||
|
||||
assertThat(mFragment.getDefaultKey())
|
||||
.isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_AUTOMATIC);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setKey_natural() {
|
||||
mFragment.setDefaultKey(ColorModePreferenceFragment.KEY_COLOR_MODE_NATURAL);
|
||||
@@ -131,6 +199,12 @@ public class ColorModePreferenceFragmentTest {
|
||||
verify(mController).setColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setKey_automatic() {
|
||||
mFragment.setDefaultKey(ColorModePreferenceFragment.KEY_COLOR_MODE_AUTOMATIC);
|
||||
verify(mController).setColorMode(ColorDisplayController.COLOR_MODE_AUTOMATIC);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreatePreferences_useNewTitle_shouldAddColorModePreferences() {
|
||||
doNothing().when(mFragment).addPreferencesFromResource(anyInt());
|
||||
|
||||
@@ -21,7 +21,9 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
@@ -38,6 +40,11 @@ import android.widget.CheckBox;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipDialogFragment;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -46,13 +53,15 @@ import org.mockito.Answers;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.shadows.ShadowAlertDialog;
|
||||
import org.robolectric.shadows.ShadowDialog;
|
||||
import org.robolectric.util.FragmentTestUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class RestrictedAppDetailsTest {
|
||||
|
||||
private static final String PACKAGE_NAME = "com.android.app";
|
||||
@@ -60,20 +69,21 @@ public class RestrictedAppDetailsTest {
|
||||
private static final int UID = UserHandle.getUid(USER_ID, 234);
|
||||
private static final String APP_NAME = "app";
|
||||
|
||||
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private ApplicationInfo mApplicationInfo;
|
||||
@Mock
|
||||
private IconDrawableFactory mIconDrawableFactory;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private PreferenceManager mPreferenceManager;
|
||||
@Mock
|
||||
private InstrumentedPreferenceFragment mFragment;
|
||||
private PreferenceManager mPreferenceManager;
|
||||
private RestrictedAppDetails mRestrictedAppDetails;
|
||||
private Context mContext;
|
||||
private AppInfo mAppInfo;
|
||||
private Intent mIntent;
|
||||
private CheckBoxPreference mCheckBoxPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -86,8 +96,9 @@ public class RestrictedAppDetailsTest {
|
||||
.setUid(UID)
|
||||
.build();
|
||||
|
||||
mPreferenceManager = new PreferenceManager(mContext);
|
||||
|
||||
doReturn(mPreferenceManager).when(mRestrictedAppDetails).getPreferenceManager();
|
||||
doReturn(mContext).when(mPreferenceManager).getContext();
|
||||
doReturn(mContext).when(mFragment).getContext();
|
||||
mRestrictedAppDetails.mPackageManager = mPackageManager;
|
||||
mRestrictedAppDetails.mIconDrawableFactory = mIconDrawableFactory;
|
||||
@@ -97,10 +108,13 @@ public class RestrictedAppDetailsTest {
|
||||
mRestrictedAppDetails.mBatteryUtils = spy(new BatteryUtils(mContext));
|
||||
doReturn(mPreferenceManager).when(
|
||||
mRestrictedAppDetails.mRestrictedAppListGroup).getPreferenceManager();
|
||||
|
||||
mCheckBoxPreference = new CheckBoxPreference(mContext);
|
||||
mCheckBoxPreference.setKey(mRestrictedAppDetails.getKeyFromAppInfo(mAppInfo));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshUi_displayPreference() throws Exception {
|
||||
public void refreshUi_displayPreference() throws Exception {
|
||||
doReturn(mApplicationInfo).when(mPackageManager)
|
||||
.getApplicationInfoAsUser(PACKAGE_NAME, 0, USER_ID);
|
||||
doReturn(APP_NAME).when(mPackageManager).getApplicationLabel(mApplicationInfo);
|
||||
@@ -117,7 +131,7 @@ public class RestrictedAppDetailsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartRestrictedAppDetails_startWithCorrectData() {
|
||||
public void startRestrictedAppDetails_startWithCorrectData() {
|
||||
final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
|
||||
doAnswer(invocation -> {
|
||||
// Get the intent in which it has the app info bundle
|
||||
@@ -135,4 +149,50 @@ public class RestrictedAppDetailsTest {
|
||||
RestrictedAppDetails.EXTRA_APP_INFO_LIST);
|
||||
assertThat(appInfos).containsExactly(mAppInfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createDialogFragment_toRestrict_createRestrictDialog() {
|
||||
final BatteryTipDialogFragment dialogFragment = mRestrictedAppDetails.createDialogFragment(
|
||||
mAppInfo, true);
|
||||
|
||||
FragmentTestUtil.startFragment(dialogFragment);
|
||||
|
||||
final AlertDialog dialog = (AlertDialog) ShadowDialog.getLatestDialog();
|
||||
ShadowAlertDialog shadowDialog = shadowOf(dialog);
|
||||
assertThat(shadowDialog.getTitle()).isEqualTo("Restrict app?");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createDialogFragment_toUnrestrict_createUnrestrictDialog() {
|
||||
final BatteryTipDialogFragment dialogFragment = mRestrictedAppDetails.createDialogFragment(
|
||||
mAppInfo, false);
|
||||
|
||||
FragmentTestUtil.startFragment(dialogFragment);
|
||||
|
||||
final AlertDialog dialog = (AlertDialog) ShadowDialog.getLatestDialog();
|
||||
ShadowAlertDialog shadowDialog = shadowOf(dialog);
|
||||
assertThat(shadowDialog.getTitle()).isEqualTo("Remove restriction?");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBatteryTipHandled_restrict_setChecked() {
|
||||
final RestrictAppTip restrictAppTip = new RestrictAppTip(BatteryTip.StateType.NEW,
|
||||
mAppInfo);
|
||||
mRestrictedAppDetails.mRestrictedAppListGroup.addPreference(mCheckBoxPreference);
|
||||
|
||||
mRestrictedAppDetails.onBatteryTipHandled(restrictAppTip);
|
||||
|
||||
assertThat(mCheckBoxPreference.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBatteryTipHandled_unrestrict_setUnchecked() {
|
||||
final UnrestrictAppTip unrestrictAppTip = new UnrestrictAppTip(BatteryTip.StateType.NEW,
|
||||
mAppInfo);
|
||||
mRestrictedAppDetails.mRestrictedAppListGroup.addPreference(mCheckBoxPreference);
|
||||
|
||||
mRestrictedAppDetails.onBatteryTipHandled(unrestrictAppTip);
|
||||
|
||||
assertThat(mCheckBoxPreference.isChecked()).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ import java.util.List;
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class RestrictAppActionTest {
|
||||
|
||||
private static final int UID_1 = 12345;
|
||||
private static final int UID_2 = 23456;
|
||||
private static final String PACKAGE_NAME_1 = "com.android.app1";
|
||||
private static final String PACKAGE_NAME_2 = "com.android.app2";
|
||||
private static final int ANOMALY_WAKEUP = 0;
|
||||
@@ -63,9 +65,11 @@ public class RestrictAppActionTest {
|
||||
|
||||
final List<AppInfo> mAppInfos = new ArrayList<>();
|
||||
mAppInfos.add(new AppInfo.Builder()
|
||||
.setUid(UID_1)
|
||||
.setPackageName(PACKAGE_NAME_1)
|
||||
.build());
|
||||
mAppInfos.add(new AppInfo.Builder()
|
||||
.setUid(UID_2)
|
||||
.setPackageName(PACKAGE_NAME_2)
|
||||
.addAnomalyType(ANOMALY_BT)
|
||||
.addAnomalyType(ANOMALY_WAKEUP)
|
||||
@@ -87,9 +91,9 @@ public class RestrictAppActionTest {
|
||||
mRestrictAppAction.handlePositiveAction(METRICS_KEY);
|
||||
|
||||
verify(mBatteryUtils)
|
||||
.setForceAppStandby(anyInt(), eq(PACKAGE_NAME_1), eq(AppOpsManager.MODE_IGNORED));
|
||||
.setForceAppStandby(UID_1, PACKAGE_NAME_1, AppOpsManager.MODE_IGNORED);
|
||||
verify(mBatteryUtils)
|
||||
.setForceAppStandby(anyInt(), eq(PACKAGE_NAME_2), eq(AppOpsManager.MODE_IGNORED));
|
||||
.setForceAppStandby(UID_2, PACKAGE_NAME_2, AppOpsManager.MODE_IGNORED);
|
||||
verify(mFeatureFactory.metricsFeatureProvider).action(RuntimeEnvironment.application,
|
||||
MetricsProto.MetricsEvent.ACTION_TIP_RESTRICT_APP, PACKAGE_NAME_1, Pair.create(
|
||||
MetricsProto.MetricsEvent.FIELD_CONTEXT, METRICS_KEY));
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.robolectric.RuntimeEnvironment;
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class UnrestrictAppActionTest {
|
||||
|
||||
private static final int UID_1 = 12345;
|
||||
private static final String PACKAGE_NAME_1 = "com.android.app1";
|
||||
private static final int METRICS_KEY = 1;
|
||||
|
||||
@@ -54,7 +55,10 @@ public class UnrestrictAppActionTest {
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
final AppInfo appInfo = new AppInfo.Builder().setPackageName(PACKAGE_NAME_1).build();
|
||||
final AppInfo appInfo = new AppInfo.Builder()
|
||||
.setUid(UID_1)
|
||||
.setPackageName(PACKAGE_NAME_1)
|
||||
.build();
|
||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
|
||||
mUnrestrictAppAction = new UnrestrictAppAction(RuntimeEnvironment.application,
|
||||
@@ -72,7 +76,7 @@ public class UnrestrictAppActionTest {
|
||||
mUnrestrictAppAction.handlePositiveAction(METRICS_KEY);
|
||||
|
||||
verify(mBatteryUtils)
|
||||
.setForceAppStandby(anyInt(), eq(PACKAGE_NAME_1), eq(AppOpsManager.MODE_ALLOWED));
|
||||
.setForceAppStandby(UID_1, PACKAGE_NAME_1, AppOpsManager.MODE_ALLOWED);
|
||||
verify(mFeatureFactory.metricsFeatureProvider).action(RuntimeEnvironment.application,
|
||||
MetricsProto.MetricsEvent.ACTION_TIP_UNRESTRICT_APP, PACKAGE_NAME_1, Pair.create(
|
||||
MetricsProto.MetricsEvent.FIELD_CONTEXT, METRICS_KEY));
|
||||
|
||||
@@ -85,6 +85,7 @@ public class ZenModeVisEffectsCustomPreferenceControllerTest {
|
||||
ReflectionHelpers.setField(mController, "mBackend", mBackend);
|
||||
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
|
||||
mController.displayPreference(mScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.os.StrictMode;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
|
||||
import com.android.settings.wifi.WifiSliceBuilder;
|
||||
import com.android.settings.bluetooth.BluetoothSliceBuilder;
|
||||
import com.android.settings.notification.ZenModeSliceBuilder;
|
||||
import com.android.settings.testutils.DatabaseTestUtils;
|
||||
import com.android.settings.testutils.FakeToggleController;
|
||||
@@ -79,7 +80,8 @@ public class SettingsSliceProviderTest {
|
||||
private SliceManager mManager;
|
||||
|
||||
private static final List<Uri> SPECIAL_CASE_PLATFORM_URIS = Arrays.asList(
|
||||
WifiSliceBuilder.WIFI_URI
|
||||
WifiSliceBuilder.WIFI_URI,
|
||||
BluetoothSliceBuilder.BLUETOOTH_URI
|
||||
);
|
||||
|
||||
private static final List<Uri> SPECIAL_CASE_OEM_URIS = Arrays.asList(
|
||||
|
||||
@@ -75,7 +75,7 @@ public class SliceTester {
|
||||
|
||||
final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
|
||||
final int color = colorItem.getInt();
|
||||
assertThat(color).isEqualTo(Utils.getColorAccent(context));
|
||||
assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context));
|
||||
|
||||
final List<SliceAction> toggles = metadata.getToggles();
|
||||
assertThat(toggles).isEmpty();
|
||||
@@ -105,7 +105,7 @@ public class SliceTester {
|
||||
|
||||
final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
|
||||
final int color = colorItem.getInt();
|
||||
assertThat(color).isEqualTo(Utils.getColorAccent(context));
|
||||
assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context));
|
||||
|
||||
final List<SliceAction> toggles = metadata.getToggles();
|
||||
assertThat(toggles).hasSize(1);
|
||||
@@ -148,7 +148,7 @@ public class SliceTester {
|
||||
|
||||
final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
|
||||
final int color = colorItem.getInt();
|
||||
assertThat(color).isEqualTo(Utils.getColorAccent(context));
|
||||
assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context));
|
||||
|
||||
final IconCompat expectedToggleIcon = IconCompat.createWithResource(context,
|
||||
sliceData.getIconResource());
|
||||
@@ -185,7 +185,7 @@ public class SliceTester {
|
||||
|
||||
final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
|
||||
final int color = colorItem.getInt();
|
||||
assertThat(color).isEqualTo(Utils.getColorAccent(context));
|
||||
assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context));
|
||||
|
||||
final List<SliceAction> toggles = metadata.getToggles();
|
||||
assertThat(toggles).isEmpty();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import static android.util.TypedValue.TYPE_REFERENCE;
|
||||
|
||||
import static org.robolectric.RuntimeEnvironment.application;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
import static org.robolectric.shadow.api.Shadow.directlyOn;
|
||||
@@ -122,8 +121,6 @@ public class SettingsShadowResources extends ShadowResources {
|
||||
id = R.drawable.ic_settings_wireless;
|
||||
} else if (id == R.drawable.app_filter_spinner_background) {
|
||||
id = R.drawable.ic_expand_more_inverse;
|
||||
} else if (id == R.drawable.selectable_card_grey) {
|
||||
id = R.drawable.ic_expand_more_inverse;
|
||||
}
|
||||
return super.loadDrawable(value, id, theme);
|
||||
}
|
||||
@@ -135,6 +132,14 @@ public class SettingsShadowResources extends ShadowResources {
|
||||
|| id == com.android.settings.R.array.batterymeter_plus_points) {
|
||||
return new int[2];
|
||||
}
|
||||
|
||||
final Object override;
|
||||
synchronized (sResourceOverrides) {
|
||||
override = sResourceOverrides.get(id);
|
||||
}
|
||||
if (override instanceof int[]) {
|
||||
return (int[]) override;
|
||||
}
|
||||
return directlyOn(realResources, Resources.class).getIntArray(id);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,6 @@ public class SettingsShadowResourcesImpl extends ShadowResourcesImpl {
|
||||
id = R.drawable.ic_settings_wireless;
|
||||
} else if (id == R.drawable.app_filter_spinner_background) {
|
||||
id = R.drawable.ic_expand_more_inverse;
|
||||
} else if (id == R.drawable.selectable_card_grey) {
|
||||
id = R.drawable.ic_expand_more_inverse;
|
||||
} else if (id == R.drawable.color_bar_progress
|
||||
|| id == R.drawable.ring_progress) {
|
||||
// color_bar_progress and ring_progress use hidden resources, so just use the regular
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.testutils.shadow;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Implements(value = BluetoothAdapter.class, inheritImplementationMethods = true)
|
||||
public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBluetoothAdapter {
|
||||
/**
|
||||
* Do nothing, implement it to avoid null pointer error inside BluetoothAdapter
|
||||
*/
|
||||
@Implementation
|
||||
public List<Integer> getSupportedProfiles() {
|
||||
return new ArrayList<Integer>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.testutils.shadow;
|
||||
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(LocalBluetoothAdapter.class)
|
||||
public class ShadowLocalBluetoothAdapter {
|
||||
|
||||
private static String sName;
|
||||
private boolean isBluetoothEnabled = true;
|
||||
|
||||
public static void setName(String name) {
|
||||
sName = name;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public String getName() {
|
||||
return sName;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean isEnabled() {
|
||||
return isBluetoothEnabled;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean enable() {
|
||||
isBluetoothEnabled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean disable() {
|
||||
isBluetoothEnabled = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +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.testutils.shadow;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settingslib.bluetooth.BluetoothEventManager;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(LocalBluetoothProfileManager.class)
|
||||
public class ShadowLocalBluetoothProfileManager {
|
||||
|
||||
public void __constructor__(Context context,
|
||||
LocalBluetoothAdapter adapter,
|
||||
CachedBluetoothDeviceManager deviceManager,
|
||||
BluetoothEventManager eventManager) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ public class WifiSliceBuilderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWifiSlice_correctData() {
|
||||
public void getWifiSlice_correctSliceContent() {
|
||||
final Slice wifiSlice = WifiSliceBuilder.getSlice(mContext);
|
||||
final SliceMetadata metadata = SliceMetadata.from(mContext, wifiSlice);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user