Snap for 6607158 from b57bd4d8cd to mainline-release
Change-Id: I577de6243175c5f63c467fe83db511b783fe038c
This commit is contained in:
@@ -219,7 +219,7 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".Settings$ConnectedDeviceDashboardActivity"
|
android:name=".Settings$ConnectedDeviceDashboardActivity"
|
||||||
android:label="@string/connected_devices_dashboard_title"
|
android:label="@string/connected_devices_dashboard_title"
|
||||||
android:icon="@drawable/ic_devices_other">
|
android:icon="@drawable/ic_homepage_connected_device">
|
||||||
<intent-filter android:priority="1">
|
<intent-filter android:priority="1">
|
||||||
<action android:name="android.settings.BLUETOOTH_SETTINGS" />
|
<action android:name="android.settings.BLUETOOTH_SETTINGS" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
@@ -254,7 +254,7 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name="Settings$WifiSettingsActivity"
|
android:name="Settings$WifiSettingsActivity"
|
||||||
android:label="@string/wifi_settings"
|
android:label="@string/wifi_settings"
|
||||||
android:icon="@drawable/ic_settings_wireless"
|
android:icon="@drawable/ic_homepage_network"
|
||||||
android:configChanges="orientation|keyboardHidden|screenSize">
|
android:configChanges="orientation|keyboardHidden|screenSize">
|
||||||
<intent-filter android:priority="1">
|
<intent-filter android:priority="1">
|
||||||
<action android:name="android.settings.WIFI_SETTINGS" />
|
<action android:name="android.settings.WIFI_SETTINGS" />
|
||||||
@@ -273,7 +273,7 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name="Settings$WifiSettings2Activity"
|
android:name="Settings$WifiSettings2Activity"
|
||||||
android:label="@string/wifi_settings"
|
android:label="@string/wifi_settings"
|
||||||
android:icon="@drawable/ic_settings_wireless"
|
android:icon="@drawable/ic_homepage_network"
|
||||||
android:configChanges="orientation|keyboardHidden|screenSize">
|
android:configChanges="orientation|keyboardHidden|screenSize">
|
||||||
<intent-filter android:priority="1">
|
<intent-filter android:priority="1">
|
||||||
<action android:name="android.settings.WIFI_SETTINGS2" />
|
<action android:name="android.settings.WIFI_SETTINGS2" />
|
||||||
@@ -492,7 +492,7 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name="Settings$TetherSettingsActivity"
|
android:name="Settings$TetherSettingsActivity"
|
||||||
android:label="@string/tether_settings_title_all"
|
android:label="@string/tether_settings_title_all"
|
||||||
android:icon="@drawable/ic_settings_wireless">
|
android:icon="@drawable/ic_homepage_network">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<action android:name="android.settings.TETHER_SETTINGS" />
|
<action android:name="android.settings.TETHER_SETTINGS" />
|
||||||
@@ -738,7 +738,7 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name="Settings$ZenModeSettingsActivity"
|
android:name="Settings$ZenModeSettingsActivity"
|
||||||
android:label="@string/zen_mode_settings_title"
|
android:label="@string/zen_mode_settings_title"
|
||||||
android:icon="@drawable/ic_notifications"
|
android:icon="@drawable/ic_homepage_notification"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter android:priority="1">
|
<intent-filter android:priority="1">
|
||||||
<action android:name="android.settings.ZEN_MODE_SETTINGS" />
|
<action android:name="android.settings.ZEN_MODE_SETTINGS" />
|
||||||
@@ -909,7 +909,7 @@
|
|||||||
android:name="Settings$NightDisplaySettingsActivity"
|
android:name="Settings$NightDisplaySettingsActivity"
|
||||||
android:label="@string/night_display_title"
|
android:label="@string/night_display_title"
|
||||||
android:enabled="@*android:bool/config_nightDisplayAvailable"
|
android:enabled="@*android:bool/config_nightDisplayAvailable"
|
||||||
android:icon="@drawable/ic_settings_night_display">
|
android:icon="@drawable/ic_homepage_night_display">
|
||||||
<intent-filter android:priority="32">
|
<intent-filter android:priority="32">
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="com.android.settings.SHORTCUT" />
|
<category android:name="com.android.settings.SHORTCUT" />
|
||||||
@@ -1225,7 +1225,7 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name="Settings$LocationSettingsActivity"
|
android:name="Settings$LocationSettingsActivity"
|
||||||
android:label="@string/location_settings_title"
|
android:label="@string/location_settings_title"
|
||||||
android:icon="@drawable/ic_settings_location"
|
android:icon="@drawable/ic_homepage_location"
|
||||||
android:configChanges="orientation|keyboardHidden|screenSize">
|
android:configChanges="orientation|keyboardHidden|screenSize">
|
||||||
<intent-filter android:priority="1">
|
<intent-filter android:priority="1">
|
||||||
<action android:name="android.settings.LOCATION_SOURCE_SETTINGS" />
|
<action android:name="android.settings.LOCATION_SOURCE_SETTINGS" />
|
||||||
@@ -2179,7 +2179,7 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name="Settings$PowerUsageSummaryActivity"
|
android:name="Settings$PowerUsageSummaryActivity"
|
||||||
android:label="@string/power_usage_summary_title"
|
android:label="@string/power_usage_summary_title"
|
||||||
android:icon="@drawable/ic_settings_battery">
|
android:icon="@drawable/ic_homepage_battery">
|
||||||
<intent-filter android:priority="1">
|
<intent-filter android:priority="1">
|
||||||
<action android:name="android.intent.action.POWER_USAGE_SUMMARY" />
|
<action android:name="android.intent.action.POWER_USAGE_SUMMARY" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
|||||||
@@ -2321,6 +2321,38 @@
|
|||||||
column="13"/>
|
column="13"/>
|
||||||
</issue>
|
</issue>
|
||||||
|
|
||||||
|
<issue
|
||||||
|
id="HardCodedColor"
|
||||||
|
severity="Error"
|
||||||
|
message="Avoid using hardcoded color"
|
||||||
|
category="Correctness"
|
||||||
|
priority="4"
|
||||||
|
summary="Using hardcoded color"
|
||||||
|
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||||
|
errorLine1=" android:color="@color/homepage_generic_icon_background" />"
|
||||||
|
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||||
|
<location
|
||||||
|
file="res/drawable/ic_homepage_night_display.xml"
|
||||||
|
line="24"
|
||||||
|
column="13"/>
|
||||||
|
</issue>
|
||||||
|
|
||||||
|
<issue
|
||||||
|
id="HardCodedColor"
|
||||||
|
severity="Error"
|
||||||
|
message="Avoid using hardcoded color"
|
||||||
|
category="Correctness"
|
||||||
|
priority="4"
|
||||||
|
summary="Using hardcoded color"
|
||||||
|
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||||
|
errorLine1=" android:color="@color/homepage_generic_icon_background" />"
|
||||||
|
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||||
|
<location
|
||||||
|
file="res/drawable/ic_homepage_notification.xml"
|
||||||
|
line="24"
|
||||||
|
column="13"/>
|
||||||
|
</issue>
|
||||||
|
|
||||||
<issue
|
<issue
|
||||||
id="HardCodedColor"
|
id="HardCodedColor"
|
||||||
severity="Error"
|
severity="Error"
|
||||||
|
|||||||
33
res/drawable/ic_homepage_night_display.xml
Normal file
33
res/drawable/ic_homepage_night_display.xml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2020 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item>
|
||||||
|
<com.android.settingslib.widget.AdaptiveIconShapeDrawable
|
||||||
|
android:width="@dimen/dashboard_tile_image_size"
|
||||||
|
android:height="@dimen/dashboard_tile_image_size"
|
||||||
|
android:color="@color/homepage_generic_icon_background" />
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:width="@dimen/dashboard_tile_foreground_image_size"
|
||||||
|
android:height="@dimen/dashboard_tile_foreground_image_size"
|
||||||
|
android:start="@dimen/dashboard_tile_foreground_image_inset"
|
||||||
|
android:top="@dimen/dashboard_tile_foreground_image_inset"
|
||||||
|
android:drawable="@drawable/ic_settings_night_display_white" />
|
||||||
|
</layer-list>
|
||||||
33
res/drawable/ic_homepage_notification.xml
Normal file
33
res/drawable/ic_homepage_notification.xml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2020 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item>
|
||||||
|
<com.android.settingslib.widget.AdaptiveIconShapeDrawable
|
||||||
|
android:width="@dimen/dashboard_tile_image_size"
|
||||||
|
android:height="@dimen/dashboard_tile_image_size"
|
||||||
|
android:color="@color/homepage_generic_icon_background" />
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:width="@dimen/dashboard_tile_foreground_image_size"
|
||||||
|
android:height="@dimen/dashboard_tile_foreground_image_size"
|
||||||
|
android:start="@dimen/dashboard_tile_foreground_image_inset"
|
||||||
|
android:top="@dimen/dashboard_tile_foreground_image_inset"
|
||||||
|
android:drawable="@drawable/ic_notifications_white" />
|
||||||
|
</layer-list>
|
||||||
19
res/drawable/ic_notifications_white.xml
Normal file
19
res/drawable/ic_notifications_white.xml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2020 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<com.android.settings.widget.TintDrawable
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:drawable="@drawable/ic_notifications"
|
||||||
|
android:tint="?android:attr/colorPrimary" />
|
||||||
19
res/drawable/ic_settings_night_display_white.xml
Normal file
19
res/drawable/ic_settings_night_display_white.xml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2020 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<com.android.settings.widget.TintDrawable
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:drawable="@drawable/ic_settings_night_display"
|
||||||
|
android:tint="?android:attr/colorPrimary" />
|
||||||
@@ -8806,6 +8806,9 @@
|
|||||||
<!-- [CHAR LIMIT=NONE] App notification settings: link to app notification settings-->
|
<!-- [CHAR LIMIT=NONE] App notification settings: link to app notification settings-->
|
||||||
<string name="app_settings_link">Additional settings in the app</string>
|
<string name="app_settings_link">Additional settings in the app</string>
|
||||||
|
|
||||||
|
<!-- [CHAR LIMIT=NONE] Apps & notification settings: summary on the link to notification settings-->
|
||||||
|
<string name="notification_screen_summary">Notification history, bubbles, recently sent</string>
|
||||||
|
|
||||||
<!-- [CHAR LIMIT=45] App notification listing summary, blocked apps -->
|
<!-- [CHAR LIMIT=45] App notification listing summary, blocked apps -->
|
||||||
<string name="app_notification_listing_summary_zero">On for all apps</string>
|
<string name="app_notification_listing_summary_zero">On for all apps</string>
|
||||||
<!-- [CHAR LIMIT=45] App notification listing summary, blocked apps -->
|
<!-- [CHAR LIMIT=45] App notification listing summary, blocked apps -->
|
||||||
|
|||||||
@@ -57,9 +57,9 @@
|
|||||||
<Preference
|
<Preference
|
||||||
android:key="configure_notification_settings"
|
android:key="configure_notification_settings"
|
||||||
android:title="@string/configure_notification_settings"
|
android:title="@string/configure_notification_settings"
|
||||||
|
android:summary="@string/notification_screen_summary"
|
||||||
android:order="-440"
|
android:order="-440"
|
||||||
android:fragment="com.android.settings.notification.ConfigureNotificationSettings"
|
android:fragment="com.android.settings.notification.ConfigureNotificationSettings"/>
|
||||||
settings:controller="com.android.settings.notification.ConfigureNotificationPreferenceController"/>
|
|
||||||
|
|
||||||
<!-- Notifications (appears before manage_perms), default apps (appears after) -->
|
<!-- Notifications (appears before manage_perms), default apps (appears after) -->
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.settings.accessibility;
|
package com.android.settings.accessibility;
|
||||||
|
|
||||||
|
import static com.android.settings.Utils.isNightMode;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
@@ -113,8 +115,7 @@ public class BalanceSeekBar extends SeekBar {
|
|||||||
res.getDimensionPixelSize(R.dimen.balance_seekbar_center_marker_width),
|
res.getDimensionPixelSize(R.dimen.balance_seekbar_center_marker_width),
|
||||||
res.getDimensionPixelSize(R.dimen.balance_seekbar_center_marker_height));
|
res.getDimensionPixelSize(R.dimen.balance_seekbar_center_marker_height));
|
||||||
mCenterMarkerPaint = new Paint();
|
mCenterMarkerPaint = new Paint();
|
||||||
// TODO use a more suitable colour?
|
mCenterMarkerPaint.setColor(isNightMode(context) ? Color.WHITE : Color.BLACK);
|
||||||
mCenterMarkerPaint.setColor(Color.BLACK);
|
|
||||||
mCenterMarkerPaint.setStyle(Paint.Style.FILL);
|
mCenterMarkerPaint.setStyle(Paint.Style.FILL);
|
||||||
// Remove the progress colour
|
// Remove the progress colour
|
||||||
setProgressTintList(ColorStateList.valueOf(Color.TRANSPARENT));
|
setProgressTintList(ColorStateList.valueOf(Color.TRANSPARENT));
|
||||||
|
|||||||
@@ -29,5 +29,4 @@ public class FeatureFlags {
|
|||||||
public static final String CONTROLLER_ENHANCEMENT = "settings_controller_loading_enhancement";
|
public static final String CONTROLLER_ENHANCEMENT = "settings_controller_loading_enhancement";
|
||||||
public static final String CONDITIONAL_CARDS = "settings_conditionals";
|
public static final String CONDITIONAL_CARDS = "settings_conditionals";
|
||||||
public static final String TETHER_ALL_IN_ONE = "settings_tether_all_in_one";
|
public static final String TETHER_ALL_IN_ONE = "settings_tether_all_in_one";
|
||||||
public static final String CONTEXTUAL_HOME2 = "settings_contextual_home2";
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,14 +19,11 @@ package com.android.settings.homepage.contextualcards;
|
|||||||
import static com.android.settings.homepage.contextualcards.ContextualCardLoader.CARD_CONTENT_LOADER_ID;
|
import static com.android.settings.homepage.contextualcards.ContextualCardLoader.CARD_CONTENT_LOADER_ID;
|
||||||
import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.STICKY_VALUE;
|
import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.STICKY_VALUE;
|
||||||
import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE;
|
import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE;
|
||||||
import static com.android.settings.slices.CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI;
|
|
||||||
import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI;
|
|
||||||
|
|
||||||
import static java.util.stream.Collectors.groupingBy;
|
import static java.util.stream.Collectors.groupingBy;
|
||||||
|
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
@@ -55,7 +52,6 @@ import com.android.settingslib.core.lifecycle.events.OnStart;
|
|||||||
import com.android.settingslib.core.lifecycle.events.OnStop;
|
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -85,8 +81,6 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
|
|||||||
static final String KEY_CONTEXTUAL_CARDS = "key_contextual_cards";
|
static final String KEY_CONTEXTUAL_CARDS = "key_contextual_cards";
|
||||||
|
|
||||||
private static final String TAG = "ContextualCardManager";
|
private static final String TAG = "ContextualCardManager";
|
||||||
private static final List<Uri> STICKY_CARDS =
|
|
||||||
Arrays.asList(CONTEXTUAL_WIFI_SLICE_URI, BLUETOOTH_DEVICES_SLICE_URI);
|
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final Lifecycle mLifecycle;
|
private final Lifecycle mLifecycle;
|
||||||
@@ -364,30 +358,12 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
|
|||||||
|
|
||||||
private List<ContextualCard> getCardsWithStickyViewType(List<ContextualCard> cards) {
|
private List<ContextualCard> getCardsWithStickyViewType(List<ContextualCard> cards) {
|
||||||
final List<ContextualCard> result = new ArrayList<>(cards);
|
final List<ContextualCard> result = new ArrayList<>(cards);
|
||||||
int replaceCount = 0;
|
|
||||||
for (int index = 0; index < result.size(); index++) {
|
for (int index = 0; index < result.size(); index++) {
|
||||||
final ContextualCard card = cards.get(index);
|
final ContextualCard card = cards.get(index);
|
||||||
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2)) {
|
|
||||||
if (card.getCategory() == STICKY_VALUE) {
|
if (card.getCategory() == STICKY_VALUE) {
|
||||||
result.set(index, card.mutate().setViewType(
|
result.set(index, card.mutate().setViewType(
|
||||||
SliceContextualCardRenderer.VIEW_TYPE_STICKY).build());
|
SliceContextualCardRenderer.VIEW_TYPE_STICKY).build());
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (replaceCount > STICKY_CARDS.size() - 1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (card.getCardType() != ContextualCard.CardType.SLICE) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (STICKY_CARDS.contains(card.getSliceUri())) {
|
|
||||||
result.set(index, card.mutate().setViewType(
|
|
||||||
SliceContextualCardRenderer.VIEW_TYPE_STICKY).build());
|
|
||||||
replaceCount++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2019 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.notification;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.core.BasePreferenceController;
|
|
||||||
|
|
||||||
public class ConfigureNotificationPreferenceController extends BasePreferenceController {
|
|
||||||
|
|
||||||
private NotificationBackend mBackend;
|
|
||||||
|
|
||||||
public ConfigureNotificationPreferenceController(Context context, String key) {
|
|
||||||
super(context, key);
|
|
||||||
mBackend = new NotificationBackend();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getAvailabilityStatus() {
|
|
||||||
return AVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getSummary() {
|
|
||||||
final int blockedAppCount = mBackend.getBlockedAppCount();
|
|
||||||
if (blockedAppCount == 0) {
|
|
||||||
return mContext.getText(R.string.app_notification_listing_summary_zero);
|
|
||||||
}
|
|
||||||
return mContext.getResources().getQuantityString(
|
|
||||||
R.plurals.app_notification_listing_summary_others,
|
|
||||||
blockedAppCount, blockedAppCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,6 +20,7 @@ import android.app.Application;
|
|||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.core.text.BidiFormatter;
|
import androidx.core.text.BidiFormatter;
|
||||||
@@ -152,6 +153,7 @@ public class ZenModeAddBypassingAppsPreferenceController extends AbstractPrefere
|
|||||||
.setDestination(AppChannelsBypassingDndSettings.class.getName())
|
.setDestination(AppChannelsBypassingDndSettings.class.getName())
|
||||||
.setArguments(args)
|
.setArguments(args)
|
||||||
.setResultListener(mHostFragment, 0)
|
.setResultListener(mHostFragment, 0)
|
||||||
|
.setUserHandle(new UserHandle(UserHandle.getUserId(entry.info.uid)))
|
||||||
.setSourceMetricsCategory(
|
.setSourceMetricsCategory(
|
||||||
SettingsEnums.NOTIFICATION_ZEN_MODE_OVERRIDING_APP)
|
SettingsEnums.NOTIFICATION_ZEN_MODE_OVERRIDING_APP)
|
||||||
.launch();
|
.launch();
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ public class SettingsSliceProvider extends SliceProvider {
|
|||||||
.createWifiCallingPreferenceSlice(sliceUri);
|
.createWifiCallingPreferenceSlice(sliceUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);
|
final SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);
|
||||||
if (cachedSliceData == null) {
|
if (cachedSliceData == null) {
|
||||||
loadSliceInBackground(sliceUri);
|
loadSliceInBackground(sliceUri);
|
||||||
return getSliceStub(sliceUri);
|
return getSliceStub(sliceUri);
|
||||||
@@ -466,14 +466,14 @@ public class SettingsSliceProvider extends SliceProvider {
|
|||||||
final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance(
|
final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance(
|
||||||
getContext(), sliceable, uri);
|
getContext(), sliceable, uri);
|
||||||
mPinnedWorkers.put(uri, worker);
|
mPinnedWorkers.put(uri, worker);
|
||||||
worker.onSlicePinned();
|
worker.pin();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopBackgroundWorker(Uri uri) {
|
private void stopBackgroundWorker(Uri uri) {
|
||||||
final SliceBackgroundWorker worker = mPinnedWorkers.get(uri);
|
final SliceBackgroundWorker worker = mPinnedWorkers.get(uri);
|
||||||
if (worker != null) {
|
if (worker != null) {
|
||||||
Log.d(TAG, "Stopping background worker for: " + uri);
|
Log.d(TAG, "Stopping background worker for: " + uri);
|
||||||
worker.onSliceUnpinned();
|
worker.unpin();
|
||||||
mPinnedWorkers.remove(uri);
|
mPinnedWorkers.remove(uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ import android.annotation.MainThread;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.HandlerThread;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.Process;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -47,6 +53,8 @@ public abstract class SliceBackgroundWorker<E> implements Closeable {
|
|||||||
|
|
||||||
private static final String TAG = "SliceBackgroundWorker";
|
private static final String TAG = "SliceBackgroundWorker";
|
||||||
|
|
||||||
|
private static final long SLICE_UPDATE_THROTTLE_INTERVAL = 300L;
|
||||||
|
|
||||||
private static final Map<Uri, SliceBackgroundWorker> LIVE_WORKERS = new ArrayMap<>();
|
private static final Map<Uri, SliceBackgroundWorker> LIVE_WORKERS = new ArrayMap<>();
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
@@ -164,6 +172,75 @@ public abstract class SliceBackgroundWorker<E> implements Closeable {
|
|||||||
* Notify that data was updated and attempt to sync changes to the Slice.
|
* Notify that data was updated and attempt to sync changes to the Slice.
|
||||||
*/
|
*/
|
||||||
protected final void notifySliceChange() {
|
protected final void notifySliceChange() {
|
||||||
mContext.getContentResolver().notifyChange(mUri, null);
|
NotifySliceChangeHandler.getInstance().updateSlice(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pin() {
|
||||||
|
onSlicePinned();
|
||||||
|
}
|
||||||
|
|
||||||
|
void unpin() {
|
||||||
|
onSliceUnpinned();
|
||||||
|
NotifySliceChangeHandler.getInstance().cancelSliceUpdate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NotifySliceChangeHandler extends Handler {
|
||||||
|
|
||||||
|
private static final int MSG_UPDATE_SLICE = 1000;
|
||||||
|
|
||||||
|
private static NotifySliceChangeHandler sHandler;
|
||||||
|
|
||||||
|
private final Map<Uri, Long> mLastUpdateTimeLookup = new ArrayMap<>();
|
||||||
|
|
||||||
|
private static NotifySliceChangeHandler getInstance() {
|
||||||
|
if (sHandler == null) {
|
||||||
|
final HandlerThread workerThread = new HandlerThread("NotifySliceChangeHandler",
|
||||||
|
Process.THREAD_PRIORITY_BACKGROUND);
|
||||||
|
workerThread.start();
|
||||||
|
sHandler = new NotifySliceChangeHandler(workerThread.getLooper());
|
||||||
|
}
|
||||||
|
return sHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NotifySliceChangeHandler(Looper looper) {
|
||||||
|
super(looper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
if (msg.what != MSG_UPDATE_SLICE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final SliceBackgroundWorker worker = (SliceBackgroundWorker) msg.obj;
|
||||||
|
final Uri uri = worker.getUri();
|
||||||
|
final Context context = worker.getContext();
|
||||||
|
mLastUpdateTimeLookup.put(uri, SystemClock.uptimeMillis());
|
||||||
|
context.getContentResolver().notifyChange(uri, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateSlice(SliceBackgroundWorker worker) {
|
||||||
|
if (hasMessages(MSG_UPDATE_SLICE, worker)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Message message = obtainMessage(MSG_UPDATE_SLICE, worker);
|
||||||
|
final long lastUpdateTime = mLastUpdateTimeLookup.getOrDefault(worker.getUri(), 0L);
|
||||||
|
if (lastUpdateTime == 0L) {
|
||||||
|
// Postpone the first update triggering by onSlicePinned() to avoid being too close
|
||||||
|
// to the first Slice bind.
|
||||||
|
sendMessageDelayed(message, SLICE_UPDATE_THROTTLE_INTERVAL);
|
||||||
|
} else if (SystemClock.uptimeMillis() - lastUpdateTime
|
||||||
|
> SLICE_UPDATE_THROTTLE_INTERVAL) {
|
||||||
|
sendMessage(message);
|
||||||
|
} else {
|
||||||
|
sendMessageAtTime(message, lastUpdateTime + SLICE_UPDATE_THROTTLE_INTERVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancelSliceUpdate(SliceBackgroundWorker worker) {
|
||||||
|
removeMessages(MSG_UPDATE_SLICE, worker);
|
||||||
|
mLastUpdateTimeLookup.remove(worker.getUri());
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,9 +220,11 @@ public class SliceBuilderUtils {
|
|||||||
|
|
||||||
public static Intent getContentIntent(Context context, SliceData sliceData) {
|
public static Intent getContentIntent(Context context, SliceData sliceData) {
|
||||||
final Uri contentUri = new Uri.Builder().appendPath(sliceData.getKey()).build();
|
final Uri contentUri = new Uri.Builder().appendPath(sliceData.getKey()).build();
|
||||||
|
final String screenTitle = TextUtils.isEmpty(sliceData.getScreenTitle()) ? null
|
||||||
|
: sliceData.getScreenTitle().toString();
|
||||||
final Intent intent = buildSearchResultPageIntent(context,
|
final Intent intent = buildSearchResultPageIntent(context,
|
||||||
sliceData.getFragmentClassName(), sliceData.getKey(),
|
sliceData.getFragmentClassName(), sliceData.getKey(),
|
||||||
sliceData.getScreenTitle().toString(), 0 /* TODO */);
|
screenTitle, 0 /* TODO */);
|
||||||
intent.setClassName(context.getPackageName(), SubSettings.class.getName());
|
intent.setClassName(context.getPackageName(), SubSettings.class.getName());
|
||||||
intent.setData(contentUri);
|
intent.setData(contentUri);
|
||||||
return intent;
|
return intent;
|
||||||
@@ -399,7 +401,8 @@ public class SliceBuilderUtils {
|
|||||||
|
|
||||||
keywords.add(data.getTitle());
|
keywords.add(data.getTitle());
|
||||||
|
|
||||||
if (!TextUtils.equals(data.getTitle(), data.getScreenTitle())) {
|
if (!TextUtils.isEmpty(data.getScreenTitle())
|
||||||
|
&& !TextUtils.equals(data.getTitle(), data.getScreenTitle())) {
|
||||||
keywords.add(data.getScreenTitle().toString());
|
keywords.add(data.getScreenTitle().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -610,7 +610,6 @@ public class ContextualCardManagerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getCardsWithViewType_hasOneStickySlice_shouldHaveOneStickyCard() {
|
public void getCardsWithViewType_hasOneStickySlice_shouldHaveOneStickyCard() {
|
||||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, true);
|
|
||||||
final List<ContextualCard> cards = new ArrayList<>();
|
final List<ContextualCard> cards = new ArrayList<>();
|
||||||
cards.add(buildContextualCard(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString()));
|
cards.add(buildContextualCard(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString()));
|
||||||
cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString()));
|
cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString()));
|
||||||
@@ -627,89 +626,6 @@ public class ContextualCardManagerTest {
|
|||||||
assertThat(result.get(1).getViewType()).isEqualTo(VIEW_TYPE_FULL_WIDTH);
|
assertThat(result.get(1).getViewType()).isEqualTo(VIEW_TYPE_FULL_WIDTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getCardsWithViewType_hasWifiSlice_shouldHaveOneStickyCard() {
|
|
||||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, false);
|
|
||||||
final List<ContextualCard> cards = new ArrayList<>();
|
|
||||||
cards.add(buildContextualCard(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString()));
|
|
||||||
cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString()));
|
|
||||||
final List<Integer> categories = Arrays.asList(
|
|
||||||
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
|
|
||||||
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE
|
|
||||||
);
|
|
||||||
final List<ContextualCard> cardListWithWifi = buildCategoriedCards(cards, categories);
|
|
||||||
|
|
||||||
final List<ContextualCard> result = mManager.getCardsWithViewType(cardListWithWifi);
|
|
||||||
|
|
||||||
assertThat(result).hasSize(cards.size());
|
|
||||||
assertThat(result.get(0).getViewType()).isEqualTo(VIEW_TYPE_STICKY);
|
|
||||||
assertThat(result.get(1).getViewType()).isEqualTo(VIEW_TYPE_FULL_WIDTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getCardsWithViewType_hasBluetoothDeviceSlice_shouldHaveOneStickyCard() {
|
|
||||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, false);
|
|
||||||
final List<ContextualCard> cards = new ArrayList<>();
|
|
||||||
cards.add(buildContextualCard(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI.toString()));
|
|
||||||
cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString()));
|
|
||||||
final List<Integer> categories = Arrays.asList(
|
|
||||||
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
|
|
||||||
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE
|
|
||||||
);
|
|
||||||
final List<ContextualCard> cardListWithBT = buildCategoriedCards(cards, categories);
|
|
||||||
|
|
||||||
final List<ContextualCard> result = mManager.getCardsWithViewType(cardListWithBT);
|
|
||||||
|
|
||||||
assertThat(result).hasSize(cards.size());
|
|
||||||
assertThat(result.get(0).getViewType()).isEqualTo(VIEW_TYPE_STICKY);
|
|
||||||
assertThat(result.get(1).getViewType()).isEqualTo(VIEW_TYPE_FULL_WIDTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getCardsWithViewType_hasWifiAndBtDeviceSlice_shouldHaveTwoStickyCards() {
|
|
||||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, false);
|
|
||||||
final List<ContextualCard> cards = new ArrayList<>();
|
|
||||||
cards.add(buildContextualCard(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString()));
|
|
||||||
cards.add(buildContextualCard(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI.toString()));
|
|
||||||
cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString()));
|
|
||||||
final List<Integer> categories = Arrays.asList(
|
|
||||||
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
|
|
||||||
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
|
|
||||||
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE
|
|
||||||
);
|
|
||||||
final List<ContextualCard> cardListWithWifiBT = buildCategoriedCards(cards, categories);
|
|
||||||
|
|
||||||
final List<ContextualCard> result = mManager.getCardsWithViewType(cardListWithWifiBT);
|
|
||||||
|
|
||||||
assertThat(result).hasSize(cards.size());
|
|
||||||
assertThat(result.stream()
|
|
||||||
.filter(card -> card.getViewType() == VIEW_TYPE_STICKY)
|
|
||||||
.count())
|
|
||||||
.isEqualTo(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getCardsWithViewType_noWifiOrBtDeviceSlice_shouldNotHaveStickyCard() {
|
|
||||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, false);
|
|
||||||
final List<Integer> categories = Arrays.asList(
|
|
||||||
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
|
|
||||||
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
|
|
||||||
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
|
|
||||||
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
|
|
||||||
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE
|
|
||||||
);
|
|
||||||
final List<ContextualCard> cardListWithoutWifiBT =
|
|
||||||
buildCategoriedCards(getContextualCardList(), categories);
|
|
||||||
|
|
||||||
final List<ContextualCard> result = mManager.getCardsWithViewType(cardListWithoutWifiBT);
|
|
||||||
|
|
||||||
assertThat(result).hasSize(cardListWithoutWifiBT.size());
|
|
||||||
assertThat(result.stream()
|
|
||||||
.filter(card -> card.getViewType() == VIEW_TYPE_STICKY)
|
|
||||||
.count())
|
|
||||||
.isEqualTo(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getCardsToKeep_hasSavedCard_shouldResetSavedCards() {
|
public void getCardsToKeep_hasSavedCard_shouldResetSavedCards() {
|
||||||
final List<String> savedCardNames = new ArrayList<>();
|
final List<String> savedCardNames = new ArrayList<>();
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import android.content.ContentResolver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import com.android.settings.slices.ShadowSliceBackgroundWorker;
|
||||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -35,7 +36,7 @@ import org.robolectric.RuntimeEnvironment;
|
|||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@Config(shadows = {ShadowBluetoothAdapter.class})
|
@Config(shadows = {ShadowBluetoothAdapter.class, ShadowSliceBackgroundWorker.class})
|
||||||
public class BluetoothUpdateWorkerTest {
|
public class BluetoothUpdateWorkerTest {
|
||||||
|
|
||||||
private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");
|
private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import android.media.MediaRoute2ProviderService;
|
|||||||
import android.media.RoutingSessionInfo;
|
import android.media.RoutingSessionInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import com.android.settings.slices.ShadowSliceBackgroundWorker;
|
||||||
import com.android.settings.testutils.shadow.ShadowAudioManager;
|
import com.android.settings.testutils.shadow.ShadowAudioManager;
|
||||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||||
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||||
@@ -57,7 +58,7 @@ import java.util.List;
|
|||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@Config(shadows = {ShadowAudioManager.class, ShadowBluetoothAdapter.class,
|
@Config(shadows = {ShadowAudioManager.class, ShadowBluetoothAdapter.class,
|
||||||
ShadowBluetoothUtils.class})
|
ShadowBluetoothUtils.class, ShadowSliceBackgroundWorker.class})
|
||||||
public class MediaDeviceUpdateWorkerTest {
|
public class MediaDeviceUpdateWorkerTest {
|
||||||
|
|
||||||
private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");
|
private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import android.media.session.MediaSessionManager;
|
|||||||
import android.media.session.PlaybackState;
|
import android.media.session.PlaybackState;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import com.android.settings.slices.ShadowSliceBackgroundWorker;
|
||||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||||
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||||
import com.android.settingslib.bluetooth.BluetoothEventManager;
|
import com.android.settingslib.bluetooth.BluetoothEventManager;
|
||||||
@@ -59,7 +60,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@Config(shadows = {ShadowBluetoothAdapter.class, ShadowBluetoothUtils.class})
|
@Config(shadows = {ShadowBluetoothAdapter.class, ShadowBluetoothUtils.class,
|
||||||
|
ShadowSliceBackgroundWorker.class})
|
||||||
public class MediaOutputIndicatorWorkerTest {
|
public class MediaOutputIndicatorWorkerTest {
|
||||||
private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");
|
private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");
|
||||||
private static final String TEST_PACKAGE_NAME = "com.android.test";
|
private static final String TEST_PACKAGE_NAME = "com.android.test";
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2019 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.notification;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import com.android.settings.testutils.shadow.ShadowNotificationBackend;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.robolectric.RobolectricTestRunner;
|
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
import org.robolectric.annotation.Config;
|
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
|
||||||
@Config(shadows = ShadowNotificationBackend.class)
|
|
||||||
public class ConfigureNotificationPreferenceControllerTest {
|
|
||||||
|
|
||||||
private ConfigureNotificationPreferenceController mController;
|
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
mContext = RuntimeEnvironment.application;
|
|
||||||
mController = new ConfigureNotificationPreferenceController(mContext, "key");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getSummary_noBlockedApps() {
|
|
||||||
ShadowNotificationBackend.setBlockedAppCount(0);
|
|
||||||
|
|
||||||
assertThat(mController.getSummary().toString()).contains("On");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getSummary_someBlockedApps() {
|
|
||||||
ShadowNotificationBackend.setBlockedAppCount(5);
|
|
||||||
|
|
||||||
assertThat(mController.getSummary().toString()).contains("Off");
|
|
||||||
assertThat(mController.getSummary().toString()).contains("5");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.slices;
|
||||||
|
|
||||||
|
import org.robolectric.annotation.Implementation;
|
||||||
|
import org.robolectric.annotation.Implements;
|
||||||
|
import org.robolectric.annotation.RealObject;
|
||||||
|
|
||||||
|
@Implements(SliceBackgroundWorker.class)
|
||||||
|
public class ShadowSliceBackgroundWorker {
|
||||||
|
|
||||||
|
@RealObject
|
||||||
|
private SliceBackgroundWorker mRealWorker;
|
||||||
|
|
||||||
|
@Implementation
|
||||||
|
protected final void notifySliceChange() {
|
||||||
|
mRealWorker.getContext().getContentResolver().notifyChange(mRealWorker.getUri(), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,6 +43,7 @@ import android.net.wifi.WifiManager;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
|
||||||
|
import com.android.settings.slices.ShadowSliceBackgroundWorker;
|
||||||
import com.android.settings.testutils.shadow.ShadowWifiManager;
|
import com.android.settings.testutils.shadow.ShadowWifiManager;
|
||||||
import com.android.settingslib.wifi.AccessPoint;
|
import com.android.settingslib.wifi.AccessPoint;
|
||||||
import com.android.settingslib.wifi.WifiTracker;
|
import com.android.settingslib.wifi.WifiTracker;
|
||||||
@@ -63,10 +64,8 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@Config(shadows = {
|
@Config(shadows = {ShadowSliceBackgroundWorker.class, ShadowWifiManager.class,
|
||||||
ShadowWifiManager.class,
|
WifiScanWorkerTest.ShadowWifiTracker.class})
|
||||||
WifiScanWorkerTest.ShadowWifiTracker.class,
|
|
||||||
})
|
|
||||||
public class WifiScanWorkerTest {
|
public class WifiScanWorkerTest {
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ import android.content.pm.ActivityInfo;
|
|||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.net.TetheringManager;
|
import android.net.TetheringManager;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -78,13 +77,11 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
|
|||||||
private static final String TEST_RESPONSE_ACTION = "testProvisioningResponseAction";
|
private static final String TEST_RESPONSE_ACTION = "testProvisioningResponseAction";
|
||||||
private static final String TEST_NO_UI_ACTION = "testNoUiProvisioningRequestAction";
|
private static final String TEST_NO_UI_ACTION = "testNoUiProvisioningRequestAction";
|
||||||
private static final int BOGUS_RECEIVER_RESULT = -5;
|
private static final int BOGUS_RECEIVER_RESULT = -5;
|
||||||
private static final int TEST_CHECK_PERIOD = 100;
|
|
||||||
private static final int MS_PER_HOUR = 60 * 60 * 1000;
|
private static final int MS_PER_HOUR = 60 * 60 * 1000;
|
||||||
private static final int SHORT_TIMEOUT = 100;
|
private static final int SHORT_TIMEOUT = 100;
|
||||||
private static final int PROVISION_TIMEOUT = 1000;
|
private static final int PROVISION_TIMEOUT = 1000;
|
||||||
|
|
||||||
private TetherService mService;
|
private TetherService mService;
|
||||||
private MockResources mResources;
|
|
||||||
private MockTetherServiceWrapper mWrapper;
|
private MockTetherServiceWrapper mWrapper;
|
||||||
int mLastReceiverResultCode = BOGUS_RECEIVER_RESULT;
|
int mLastReceiverResultCode = BOGUS_RECEIVER_RESULT;
|
||||||
private int mLastTetherRequestType = TETHERING_INVALID;
|
private int mLastTetherRequestType = TETHERING_INVALID;
|
||||||
@@ -109,7 +106,6 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
|
|||||||
super.setUp();
|
super.setUp();
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
mResources = new MockResources();
|
|
||||||
mContext = new TestContextWrapper(getContext());
|
mContext = new TestContextWrapper(getContext());
|
||||||
setContext(mContext);
|
setContext(mContext);
|
||||||
|
|
||||||
@@ -302,41 +298,12 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MockResources extends android.test.mock.MockResources {
|
|
||||||
@Override
|
|
||||||
public int getInteger(int id) {
|
|
||||||
switch(id) {
|
|
||||||
case com.android.internal.R.integer.config_mobile_hotspot_provision_check_period:
|
|
||||||
return TEST_CHECK_PERIOD;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getString(int id) {
|
|
||||||
switch(id) {
|
|
||||||
case com.android.internal.R.string.config_mobile_hotspot_provision_response:
|
|
||||||
return TEST_RESPONSE_ACTION;
|
|
||||||
case com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui:
|
|
||||||
return TEST_NO_UI_ACTION;
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestContextWrapper extends ContextWrapper {
|
private class TestContextWrapper extends ContextWrapper {
|
||||||
|
|
||||||
public TestContextWrapper(Context base) {
|
public TestContextWrapper(Context base) {
|
||||||
super(base);
|
super(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Resources getResources() {
|
|
||||||
return mResources;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SharedPreferences getSharedPreferences(String name, int mode) {
|
public SharedPreferences getSharedPreferences(String name, int mode) {
|
||||||
// Stub out prefs to control the persisted tether type list.
|
// Stub out prefs to control the persisted tether type list.
|
||||||
|
|||||||
Reference in New Issue
Block a user