diff --git a/AndroidManifest.xml b/AndroidManifest.xml index bd04d89eeb2..4ce8f362198 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -219,7 +219,7 @@ + android:icon="@drawable/ic_homepage_connected_device"> @@ -254,7 +254,7 @@ @@ -273,7 +273,7 @@ @@ -492,7 +492,7 @@ + android:icon="@drawable/ic_homepage_network"> @@ -738,7 +738,7 @@ @@ -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"> @@ -1225,7 +1225,7 @@ @@ -2179,7 +2179,7 @@ + android:icon="@drawable/ic_homepage_battery"> diff --git a/color-check-baseline.xml b/color-check-baseline.xml index 75f46e5eff9..f959f918a74 100644 --- a/color-check-baseline.xml +++ b/color-check-baseline.xml @@ -2321,6 +2321,38 @@ column="13"/> + + + + + + + + + + + + + + + + + + diff --git a/res/drawable/ic_homepage_notification.xml b/res/drawable/ic_homepage_notification.xml new file mode 100644 index 00000000000..d8c8d6dcf3c --- /dev/null +++ b/res/drawable/ic_homepage_notification.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_notifications_white.xml b/res/drawable/ic_notifications_white.xml new file mode 100644 index 00000000000..1a37b56c062 --- /dev/null +++ b/res/drawable/ic_notifications_white.xml @@ -0,0 +1,19 @@ + + diff --git a/res/drawable/ic_settings_night_display_white.xml b/res/drawable/ic_settings_night_display_white.xml new file mode 100644 index 00000000000..8424b31295c --- /dev/null +++ b/res/drawable/ic_settings_night_display_white.xml @@ -0,0 +1,19 @@ + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 847335750f8..1b653594aac 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8806,6 +8806,9 @@ Additional settings in the app + + Notification history, bubbles, recently sent + On for all apps diff --git a/res/xml/app_and_notification.xml b/res/xml/app_and_notification.xml index 98b98442b21..bd2e85ce127 100644 --- a/res/xml/app_and_notification.xml +++ b/res/xml/app_and_notification.xml @@ -57,9 +57,9 @@ + android:fragment="com.android.settings.notification.ConfigureNotificationSettings"/> 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 getCardsWithStickyViewType(List cards) { final List 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; diff --git a/src/com/android/settings/notification/ConfigureNotificationPreferenceController.java b/src/com/android/settings/notification/ConfigureNotificationPreferenceController.java deleted file mode 100644 index 3aa1008e03e..00000000000 --- a/src/com/android/settings/notification/ConfigureNotificationPreferenceController.java +++ /dev/null @@ -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); - } -} \ No newline at end of file diff --git a/src/com/android/settings/notification/zen/ZenModeAddBypassingAppsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeAddBypassingAppsPreferenceController.java index 15a46fe1e1e..a861ab27673 100644 --- a/src/com/android/settings/notification/zen/ZenModeAddBypassingAppsPreferenceController.java +++ b/src/com/android/settings/notification/zen/ZenModeAddBypassingAppsPreferenceController.java @@ -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(); diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java index 6c245ce80b4..75061a5dac5 100644 --- a/src/com/android/settings/slices/SettingsSliceProvider.java +++ b/src/com/android/settings/slices/SettingsSliceProvider.java @@ -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); } } diff --git a/src/com/android/settings/slices/SliceBackgroundWorker.java b/src/com/android/settings/slices/SliceBackgroundWorker.java index 6bafc00f9fc..6eb154e9558 100644 --- a/src/com/android/settings/slices/SliceBackgroundWorker.java +++ b/src/com/android/settings/slices/SliceBackgroundWorker.java @@ -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 implements Closeable { private static final String TAG = "SliceBackgroundWorker"; + private static final long SLICE_UPDATE_THROTTLE_INTERVAL = 300L; + private static final Map LIVE_WORKERS = new ArrayMap<>(); private final Context mContext; @@ -164,6 +172,75 @@ public abstract class SliceBackgroundWorker 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 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()); + } + }; } diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java index 391e9fdf741..552927e1da2 100644 --- a/src/com/android/settings/slices/SliceBuilderUtils.java +++ b/src/com/android/settings/slices/SliceBuilderUtils.java @@ -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()); } diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java index 127b9e29466..69333d7ad9d 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java @@ -610,7 +610,6 @@ public class ContextualCardManagerTest { @Test public void getCardsWithViewType_hasOneStickySlice_shouldHaveOneStickyCard() { - FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, true); final List 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 cards = new ArrayList<>(); - cards.add(buildContextualCard(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString())); - cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString())); - final List categories = Arrays.asList( - ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE, - ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE - ); - final List cardListWithWifi = buildCategoriedCards(cards, categories); - - final List 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 cards = new ArrayList<>(); - cards.add(buildContextualCard(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI.toString())); - cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString())); - final List categories = Arrays.asList( - ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE, - ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE - ); - final List cardListWithBT = buildCategoriedCards(cards, categories); - - final List 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 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 categories = Arrays.asList( - ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE, - ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE, - ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE - ); - final List cardListWithWifiBT = buildCategoriedCards(cards, categories); - - final List 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 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 cardListWithoutWifiBT = - buildCategoriedCards(getContextualCardList(), categories); - - final List 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 savedCardNames = new ArrayList<>(); diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothUpdateWorkerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothUpdateWorkerTest.java index 4da5c094f13..e34737b7d85 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothUpdateWorkerTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothUpdateWorkerTest.java @@ -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"); diff --git a/tests/robotests/src/com/android/settings/media/MediaDeviceUpdateWorkerTest.java b/tests/robotests/src/com/android/settings/media/MediaDeviceUpdateWorkerTest.java index 624bbd8101f..be86b6e3984 100644 --- a/tests/robotests/src/com/android/settings/media/MediaDeviceUpdateWorkerTest.java +++ b/tests/robotests/src/com/android/settings/media/MediaDeviceUpdateWorkerTest.java @@ -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"); diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java index 0aec9529b3c..423c7acf098 100644 --- a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java +++ b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java @@ -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"; diff --git a/tests/robotests/src/com/android/settings/notification/ConfigureNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ConfigureNotificationPreferenceControllerTest.java deleted file mode 100644 index 83fe07a89c9..00000000000 --- a/tests/robotests/src/com/android/settings/notification/ConfigureNotificationPreferenceControllerTest.java +++ /dev/null @@ -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"); - } -} diff --git a/tests/robotests/src/com/android/settings/slices/ShadowSliceBackgroundWorker.java b/tests/robotests/src/com/android/settings/slices/ShadowSliceBackgroundWorker.java new file mode 100644 index 00000000000..7bf8358a850 --- /dev/null +++ b/tests/robotests/src/com/android/settings/slices/ShadowSliceBackgroundWorker.java @@ -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); + } +} diff --git a/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java b/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java index d40331c3332..33195438fe0 100644 --- a/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java @@ -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; diff --git a/tests/unit/src/com/android/settings/wifi/tether/TetherServiceTest.java b/tests/unit/src/com/android/settings/wifi/tether/TetherServiceTest.java index be030bf7dac..9d9cc340a8b 100644 --- a/tests/unit/src/com/android/settings/wifi/tether/TetherServiceTest.java +++ b/tests/unit/src/com/android/settings/wifi/tether/TetherServiceTest.java @@ -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 { 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 { super.setUp(); MockitoAnnotations.initMocks(this); - mResources = new MockResources(); mContext = new TestContextWrapper(getContext()); setContext(mContext); @@ -302,41 +298,12 @@ public class TetherServiceTest extends ServiceTestCase { } } - 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.