Snap for 6607158 from b57bd4d8cd to mainline-release

Change-Id: I577de6243175c5f63c467fe83db511b783fe038c
This commit is contained in:
android-build-team Robot
2020-06-19 07:03:55 +00:00
24 changed files with 284 additions and 275 deletions

View File

@@ -219,7 +219,7 @@
<activity
android:name=".Settings$ConnectedDeviceDashboardActivity"
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">
<action android:name="android.settings.BLUETOOTH_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
@@ -254,7 +254,7 @@
<activity
android:name="Settings$WifiSettingsActivity"
android:label="@string/wifi_settings"
android:icon="@drawable/ic_settings_wireless"
android:icon="@drawable/ic_homepage_network"
android:configChanges="orientation|keyboardHidden|screenSize">
<intent-filter android:priority="1">
<action android:name="android.settings.WIFI_SETTINGS" />
@@ -273,7 +273,7 @@
<activity
android:name="Settings$WifiSettings2Activity"
android:label="@string/wifi_settings"
android:icon="@drawable/ic_settings_wireless"
android:icon="@drawable/ic_homepage_network"
android:configChanges="orientation|keyboardHidden|screenSize">
<intent-filter android:priority="1">
<action android:name="android.settings.WIFI_SETTINGS2" />
@@ -492,7 +492,7 @@
<activity
android:name="Settings$TetherSettingsActivity"
android:label="@string/tether_settings_title_all"
android:icon="@drawable/ic_settings_wireless">
android:icon="@drawable/ic_homepage_network">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.settings.TETHER_SETTINGS" />
@@ -738,7 +738,7 @@
<activity
android:name="Settings$ZenModeSettingsActivity"
android:label="@string/zen_mode_settings_title"
android:icon="@drawable/ic_notifications"
android:icon="@drawable/ic_homepage_notification"
android:exported="true">
<intent-filter android:priority="1">
<action android:name="android.settings.ZEN_MODE_SETTINGS" />
@@ -909,7 +909,7 @@
android:name="Settings$NightDisplaySettingsActivity"
android:label="@string/night_display_title"
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">
<action android:name="android.intent.action.MAIN" />
<category android:name="com.android.settings.SHORTCUT" />
@@ -1225,7 +1225,7 @@
<activity
android:name="Settings$LocationSettingsActivity"
android:label="@string/location_settings_title"
android:icon="@drawable/ic_settings_location"
android:icon="@drawable/ic_homepage_location"
android:configChanges="orientation|keyboardHidden|screenSize">
<intent-filter android:priority="1">
<action android:name="android.settings.LOCATION_SOURCE_SETTINGS" />
@@ -2179,7 +2179,7 @@
<activity
android:name="Settings$PowerUsageSummaryActivity"
android:label="@string/power_usage_summary_title"
android:icon="@drawable/ic_settings_battery">
android:icon="@drawable/ic_homepage_battery">
<intent-filter android:priority="1">
<action android:name="android.intent.action.POWER_USAGE_SUMMARY" />
<category android:name="android.intent.category.DEFAULT" />

View File

@@ -2321,6 +2321,38 @@
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.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" android:color=&quot;@color/homepage_generic_icon_background&quot; />"
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.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" android:color=&quot;@color/homepage_generic_icon_background&quot; />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/drawable/ic_homepage_notification.xml"
line="24"
column="13"/>
</issue>
<issue
id="HardCodedColor"
severity="Error"

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

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

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

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

View File

@@ -8806,6 +8806,9 @@
<!-- [CHAR LIMIT=NONE] App notification settings: link to app notification settings-->
<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 -->
<string name="app_notification_listing_summary_zero">On for all apps</string>
<!-- [CHAR LIMIT=45] App notification listing summary, blocked apps -->

View File

@@ -57,9 +57,9 @@
<Preference
android:key="configure_notification_settings"
android:title="@string/configure_notification_settings"
android:summary="@string/notification_screen_summary"
android:order="-440"
android:fragment="com.android.settings.notification.ConfigureNotificationSettings"
settings:controller="com.android.settings.notification.ConfigureNotificationPreferenceController"/>
android:fragment="com.android.settings.notification.ConfigureNotificationSettings"/>
<!-- Notifications (appears before manage_perms), default apps (appears after) -->
<PreferenceCategory

View File

@@ -16,6 +16,8 @@
package com.android.settings.accessibility;
import static com.android.settings.Utils.isNightMode;
import android.content.Context;
import android.content.res.ColorStateList;
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_height));
mCenterMarkerPaint = new Paint();
// TODO use a more suitable colour?
mCenterMarkerPaint.setColor(Color.BLACK);
mCenterMarkerPaint.setColor(isNightMode(context) ? Color.WHITE : Color.BLACK);
mCenterMarkerPaint.setStyle(Paint.Style.FILL);
// Remove the progress colour
setProgressTintList(ColorStateList.valueOf(Color.TRANSPARENT));

View File

@@ -29,5 +29,4 @@ public class FeatureFlags {
public static final String CONTROLLER_ENHANCEMENT = "settings_controller_loading_enhancement";
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 CONTEXTUAL_HOME2 = "settings_contextual_home2";
}

View File

@@ -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.intelligence.ContextualCardProto.ContextualCard.Category.STICKY_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 android.app.settings.SettingsEnums;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
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 java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -85,8 +81,6 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
static final String KEY_CONTEXTUAL_CARDS = "key_contextual_cards";
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 Lifecycle mLifecycle;
@@ -364,29 +358,11 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
private List<ContextualCard> getCardsWithStickyViewType(List<ContextualCard> cards) {
final List<ContextualCard> result = new ArrayList<>(cards);
int replaceCount = 0;
for (int index = 0; index < result.size(); index++) {
final ContextualCard card = cards.get(index);
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2)) {
if (card.getCategory() == STICKY_VALUE) {
result.set(index, card.mutate().setViewType(
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())) {
if (card.getCategory() == STICKY_VALUE) {
result.set(index, card.mutate().setViewType(
SliceContextualCardRenderer.VIEW_TYPE_STICKY).build());
replaceCount++;
}
}
return result;

View File

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

View File

@@ -20,6 +20,7 @@ import android.app.Application;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
import android.os.UserHandle;
import androidx.annotation.VisibleForTesting;
import androidx.core.text.BidiFormatter;
@@ -152,6 +153,7 @@ public class ZenModeAddBypassingAppsPreferenceController extends AbstractPrefere
.setDestination(AppChannelsBypassingDndSettings.class.getName())
.setArguments(args)
.setResultListener(mHostFragment, 0)
.setUserHandle(new UserHandle(UserHandle.getUserId(entry.info.uid)))
.setSourceMetricsCategory(
SettingsEnums.NOTIFICATION_ZEN_MODE_OVERRIDING_APP)
.launch();

View File

@@ -243,7 +243,7 @@ public class SettingsSliceProvider extends SliceProvider {
.createWifiCallingPreferenceSlice(sliceUri);
}
SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);
final SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);
if (cachedSliceData == null) {
loadSliceInBackground(sliceUri);
return getSliceStub(sliceUri);
@@ -466,14 +466,14 @@ public class SettingsSliceProvider extends SliceProvider {
final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance(
getContext(), sliceable, uri);
mPinnedWorkers.put(uri, worker);
worker.onSlicePinned();
worker.pin();
}
private void stopBackgroundWorker(Uri uri) {
final SliceBackgroundWorker worker = mPinnedWorkers.get(uri);
if (worker != null) {
Log.d(TAG, "Stopping background worker for: " + uri);
worker.onSliceUnpinned();
worker.unpin();
mPinnedWorkers.remove(uri);
}
}

View File

@@ -20,6 +20,12 @@ import android.annotation.MainThread;
import android.annotation.Nullable;
import android.content.Context;
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.Log;
@@ -47,6 +53,8 @@ public abstract class SliceBackgroundWorker<E> implements Closeable {
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 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.
*/
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());
}
};
}

View File

@@ -220,9 +220,11 @@ public class SliceBuilderUtils {
public static Intent getContentIntent(Context context, SliceData sliceData) {
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,
sliceData.getFragmentClassName(), sliceData.getKey(),
sliceData.getScreenTitle().toString(), 0 /* TODO */);
screenTitle, 0 /* TODO */);
intent.setClassName(context.getPackageName(), SubSettings.class.getName());
intent.setData(contentUri);
return intent;
@@ -399,7 +401,8 @@ public class SliceBuilderUtils {
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());
}

View File

@@ -610,7 +610,6 @@ public class ContextualCardManagerTest {
@Test
public void getCardsWithViewType_hasOneStickySlice_shouldHaveOneStickyCard() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, true);
final List<ContextualCard> cards = new ArrayList<>();
cards.add(buildContextualCard(CustomSliceRegistry.CONTEXTUAL_WIFI_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);
}
@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
public void getCardsToKeep_hasSavedCard_shouldResetSavedCards() {
final List<String> savedCardNames = new ArrayList<>();

View File

@@ -25,6 +25,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import com.android.settings.slices.ShadowSliceBackgroundWorker;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import org.junit.Before;
@@ -35,7 +36,7 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowBluetoothAdapter.class})
@Config(shadows = {ShadowBluetoothAdapter.class, ShadowSliceBackgroundWorker.class})
public class BluetoothUpdateWorkerTest {
private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");

View File

@@ -34,6 +34,7 @@ import android.media.MediaRoute2ProviderService;
import android.media.RoutingSessionInfo;
import android.net.Uri;
import com.android.settings.slices.ShadowSliceBackgroundWorker;
import com.android.settings.testutils.shadow.ShadowAudioManager;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
@@ -57,7 +58,7 @@ import java.util.List;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowAudioManager.class, ShadowBluetoothAdapter.class,
ShadowBluetoothUtils.class})
ShadowBluetoothUtils.class, ShadowSliceBackgroundWorker.class})
public class MediaDeviceUpdateWorkerTest {
private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");

View File

@@ -39,6 +39,7 @@ import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
import android.net.Uri;
import com.android.settings.slices.ShadowSliceBackgroundWorker;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settingslib.bluetooth.BluetoothEventManager;
@@ -59,7 +60,8 @@ import java.util.ArrayList;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowBluetoothAdapter.class, ShadowBluetoothUtils.class})
@Config(shadows = {ShadowBluetoothAdapter.class, ShadowBluetoothUtils.class,
ShadowSliceBackgroundWorker.class})
public class MediaOutputIndicatorWorkerTest {
private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");
private static final String TEST_PACKAGE_NAME = "com.android.test";

View File

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

View File

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

View File

@@ -43,6 +43,7 @@ import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.UserHandle;
import com.android.settings.slices.ShadowSliceBackgroundWorker;
import com.android.settings.testutils.shadow.ShadowWifiManager;
import com.android.settingslib.wifi.AccessPoint;
import com.android.settingslib.wifi.WifiTracker;
@@ -63,10 +64,8 @@ import java.util.Arrays;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {
ShadowWifiManager.class,
WifiScanWorkerTest.ShadowWifiTracker.class,
})
@Config(shadows = {ShadowSliceBackgroundWorker.class, ShadowWifiManager.class,
WifiScanWorkerTest.ShadowWifiTracker.class})
public class WifiScanWorkerTest {
private Context mContext;

View File

@@ -50,7 +50,6 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.net.TetheringManager;
import android.net.wifi.WifiManager;
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_NO_UI_ACTION = "testNoUiProvisioningRequestAction";
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 SHORT_TIMEOUT = 100;
private static final int PROVISION_TIMEOUT = 1000;
private TetherService mService;
private MockResources mResources;
private MockTetherServiceWrapper mWrapper;
int mLastReceiverResultCode = BOGUS_RECEIVER_RESULT;
private int mLastTetherRequestType = TETHERING_INVALID;
@@ -109,7 +106,6 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
super.setUp();
MockitoAnnotations.initMocks(this);
mResources = new MockResources();
mContext = new TestContextWrapper(getContext());
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 {
public TestContextWrapper(Context base) {
super(base);
}
@Override
public Resources getResources() {
return mResources;
}
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
// Stub out prefs to control the persisted tether type list.