Adds contextual cards for screen attention in Settings Homepage
Bug: 128527964 Test: atest ContextualAdaptiveSleepSliceTest, maually verified. Change-Id: Ifaea7d8d4391e91cf6cbde38a2506728f55913d8
This commit is contained in:
31
res/drawable/ic_settings_adaptive_sleep.xml
Normal file
31
res/drawable/ic_settings_adaptive_sleep.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<!--
|
||||
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
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M10.67,21H7v-1h3.13c-0.27-0.63-0.46-1.3-0.56-2H7V6h10v3.5c0.69,0,1.36,0.1,2,0.28V3 c0-1.1-0.9-1.99-2-1.99L7,1C5.9,1,5,1.9,5,3v18c0,1.1,0.9,2,2,2h5.52C11.79,22.45,11.16,21.77,10.67,21z M7,3h10v1H7V3z" />
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M17,12.5c2.48,0,4.5,2.02,4.5,4.5s-2.02,4.5-4.5,4.5s-4.5-2.02-4.5-4.5S14.52,12.5,17,12.5 M17,11 c-3.31,0-6,2.69-6,6s2.69,6,6,6c3.31,0,6-2.69,6-6S20.31,11,17,11L17,11z" />
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M17,14v3l-2.12,2.12C15.42,19.66,16.17,20,17,20c1.66,0,3-1.34,3-3S18.66,14,17,14z" />
|
||||
</vector>
|
@@ -2833,7 +2833,7 @@
|
||||
<!-- Setting option summary when adaptive sleep is off [CHAR LIMIT=NONE] -->
|
||||
<string name="adaptive_sleep_summary_off">Off</string>
|
||||
<!-- Description about the feature adaptive sleep [CHAR LIMIT=NONE]-->
|
||||
<string name="adaptive_sleep_description">Prevents your screen from turning off if you’re looking at it.</string>
|
||||
<string name="adaptive_sleep_description">Keep screen on when viewing it</string>
|
||||
<!-- Description feature's privacy sensitive details to make sure users understand what feature users, what it saves/sends etc [CHAR LIMIT=NONE]-->
|
||||
<string name="adaptive_sleep_privacy">Screen attention uses the front camera to see if someone is looking at the screen. It works on device, and images are never stored or sent to Google.</string>
|
||||
|
||||
|
@@ -25,9 +25,9 @@ import com.android.settings.core.TogglePreferenceController;
|
||||
|
||||
|
||||
public class AdaptiveSleepPreferenceController extends TogglePreferenceController {
|
||||
|
||||
private final String SYSTEM_KEY = ADAPTIVE_SLEEP;
|
||||
private final int DEFAULT_VALUE = 0;
|
||||
public static final String PREF_NAME = "adaptive_sleep";
|
||||
private static final String SYSTEM_KEY = ADAPTIVE_SLEEP;
|
||||
private static final int DEFAULT_VALUE = 0;
|
||||
|
||||
final boolean hasSufficientPermissions;
|
||||
|
||||
@@ -35,9 +35,7 @@ public class AdaptiveSleepPreferenceController extends TogglePreferenceControlle
|
||||
super(context, key);
|
||||
|
||||
final PackageManager packageManager = mContext.getPackageManager();
|
||||
final String attentionPackage = packageManager.getAttentionServicePackageName();
|
||||
hasSufficientPermissions = attentionPackage != null && packageManager.checkPermission(
|
||||
Manifest.permission.CAMERA, attentionPackage) == PackageManager.PERMISSION_GRANTED;
|
||||
hasSufficientPermissions = hasSufficientPermission(packageManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,7 +44,6 @@ public class AdaptiveSleepPreferenceController extends TogglePreferenceControlle
|
||||
SYSTEM_KEY, DEFAULT_VALUE) != DEFAULT_VALUE;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean setChecked(boolean isChecked) {
|
||||
Settings.System.putInt(mContext.getContentResolver(), SYSTEM_KEY,
|
||||
@@ -57,10 +54,7 @@ public class AdaptiveSleepPreferenceController extends TogglePreferenceControlle
|
||||
@Override
|
||||
@AvailabilityStatus
|
||||
public int getAvailabilityStatus() {
|
||||
return mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_adaptive_sleep_available)
|
||||
? AVAILABLE_UNSEARCHABLE
|
||||
: UNSUPPORTED_ON_DEVICE;
|
||||
return isControllerAvailable(mContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -69,4 +63,17 @@ public class AdaptiveSleepPreferenceController extends TogglePreferenceControlle
|
||||
? R.string.adaptive_sleep_summary_on
|
||||
: R.string.adaptive_sleep_summary_off);
|
||||
}
|
||||
|
||||
public static int isControllerAvailable(Context context) {
|
||||
return context.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_adaptive_sleep_available)
|
||||
? AVAILABLE_UNSEARCHABLE
|
||||
: UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
private static boolean hasSufficientPermission(PackageManager packageManager) {
|
||||
final String attentionPackage = packageManager.getAttentionServicePackageName();
|
||||
return attentionPackage != null && packageManager.checkPermission(
|
||||
Manifest.permission.CAMERA, attentionPackage) == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
}
|
||||
|
@@ -16,10 +16,15 @@
|
||||
|
||||
package com.android.settings.display;
|
||||
|
||||
import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF;
|
||||
import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF_KEY_INTERACTED;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
@@ -40,8 +45,15 @@ public class AdaptiveSleepSettings extends DashboardFragment {
|
||||
super.onCreate(icicle);
|
||||
final FooterPreference footerPreference =
|
||||
mFooterPreferenceMixin.createFooterPreference();
|
||||
final Context context = getContext();
|
||||
|
||||
footerPreference.setIcon(R.drawable.ic_privacy_shield_24dp);
|
||||
footerPreference.setTitle(R.string.adaptive_sleep_privacy);
|
||||
|
||||
context.getSharedPreferences(PREF, Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
.putBoolean(PREF_KEY_INTERACTED, true)
|
||||
.apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -64,12 +64,21 @@ public class SettingsContextualCardProvider extends ContextualCardProvider {
|
||||
.setCardName(contextualNotificationChannelSliceUri)
|
||||
.setCardCategory(ContextualCard.Category.POSSIBLE)
|
||||
.build();
|
||||
final String contextualAdaptiveSleepSliceUri =
|
||||
CustomSliceRegistry.CONTEXTUAL_ADAPTIVE_SLEEP_URI.toString();
|
||||
final ContextualCard contextualAdaptiveSleepCard =
|
||||
ContextualCard.newBuilder()
|
||||
.setSliceUri(contextualAdaptiveSleepSliceUri)
|
||||
.setCardName(contextualAdaptiveSleepSliceUri)
|
||||
.setCardCategory(ContextualCard.Category.DEFAULT)
|
||||
.build();
|
||||
final ContextualCardList cards = ContextualCardList.newBuilder()
|
||||
.addCard(wifiCard)
|
||||
.addCard(connectedDeviceCard)
|
||||
.addCard(lowStorageCard)
|
||||
.addCard(batteryFixCard)
|
||||
.addCard(notificationChannelCard)
|
||||
.addCard(contextualAdaptiveSleepCard)
|
||||
.build();
|
||||
|
||||
return cards;
|
||||
|
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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.homepage.contextualcards.slices;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.display.AdaptiveSleepPreferenceController.PREF_NAME;
|
||||
import static com.android.settings.display.AdaptiveSleepPreferenceController.isControllerAvailable;
|
||||
import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_ADAPTIVE_SLEEP_URI;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SubSettings;
|
||||
import com.android.settings.display.AdaptiveSleepSettings;
|
||||
import com.android.settings.slices.CustomSliceable;
|
||||
import com.android.settings.slices.SliceBuilderUtils;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ContextualAdaptiveSleepSlice implements CustomSliceable {
|
||||
private static final String TAG = "ContextualAdaptiveSleepSlice";
|
||||
private static final long DEFAULT_SETUP_TIME = 0;
|
||||
private Context mContext;
|
||||
|
||||
@VisibleForTesting
|
||||
static final long DEFERRED_TIME_DAYS = TimeUnit.DAYS.toMillis(14);
|
||||
@VisibleForTesting
|
||||
static final String PREF_KEY_SETUP_TIME = "adaptive_sleep_setup_time";
|
||||
|
||||
public static final String PREF_KEY_INTERACTED = "adaptive_sleep_interacted";
|
||||
public static final String PREF = "adaptive_sleep_slice";
|
||||
|
||||
public ContextualAdaptiveSleepSlice(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Slice getSlice() {
|
||||
final long setupTime = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE).getLong(
|
||||
PREF_KEY_SETUP_TIME, DEFAULT_SETUP_TIME);
|
||||
if (setupTime == DEFAULT_SETUP_TIME) {
|
||||
// Set the first setup time.
|
||||
mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
.putLong(PREF_KEY_SETUP_TIME, System.currentTimeMillis())
|
||||
.apply();
|
||||
return null;
|
||||
}
|
||||
|
||||
// Display the contextual card only if all the following 3 conditions hold:
|
||||
// 1. The Screen Attention is enabled in Settings.
|
||||
// 2. The device is not recently set up.
|
||||
// 3. Current user hasn't opened Screen Attention's settings page before.
|
||||
if (isSettingsAvailable() && !isUserInteracted() && !isRecentlySetup()) {
|
||||
final IconCompat icon = IconCompat.createWithResource(mContext,
|
||||
R.drawable.ic_settings_adaptive_sleep);
|
||||
final CharSequence title = mContext.getText(R.string.adaptive_sleep_title);
|
||||
final CharSequence subtitle = mContext.getText(R.string.adaptive_sleep_description);
|
||||
|
||||
final SliceAction pAction = SliceAction.createDeeplink(getPrimaryAction(),
|
||||
icon,
|
||||
ListBuilder.ICON_IMAGE,
|
||||
title);
|
||||
final ListBuilder listBuilder = new ListBuilder(mContext,
|
||||
CONTEXTUAL_ADAPTIVE_SLEEP_URI,
|
||||
ListBuilder.INFINITY)
|
||||
.addRow(new ListBuilder.RowBuilder()
|
||||
.setTitleItem(icon, ListBuilder.ICON_IMAGE)
|
||||
.setTitle(title)
|
||||
.setSubtitle(subtitle)
|
||||
.setPrimaryAction(pAction));
|
||||
return listBuilder.build();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri getUri() {
|
||||
return CONTEXTUAL_ADAPTIVE_SLEEP_URI;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent getIntent() {
|
||||
final CharSequence screenTitle = mContext.getText(R.string.adaptive_sleep_title);
|
||||
final Uri contentUri = new Uri.Builder().appendPath(PREF_NAME).build();
|
||||
return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
|
||||
AdaptiveSleepSettings.class.getName(), PREF_NAME, screenTitle.toString(),
|
||||
SettingsEnums.SLICE).setClassName(mContext.getPackageName(),
|
||||
SubSettings.class.getName()).setData(contentUri);
|
||||
}
|
||||
|
||||
private PendingIntent getPrimaryAction() {
|
||||
final Intent intent = getIntent();
|
||||
return PendingIntent.getActivity(mContext, 0 /* requestCode */, intent, 0 /* flags */);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the current user has opened the Screen Attention settings page
|
||||
* before, otherwise {@code false}.
|
||||
*/
|
||||
private boolean isUserInteracted() {
|
||||
return mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE).getBoolean(
|
||||
PREF_KEY_INTERACTED, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* The device is recently set up means its first settings-open time is within 2 weeks ago.
|
||||
*
|
||||
* @return {@code true} if the device is recently set up, otherwise {@code false}.
|
||||
*/
|
||||
private boolean isRecentlySetup() {
|
||||
final long endTime = System.currentTimeMillis() - DEFERRED_TIME_DAYS;
|
||||
final long firstSetupTime = mContext.getSharedPreferences(PREF,
|
||||
Context.MODE_PRIVATE).getLong(PREF_KEY_SETUP_TIME, DEFAULT_SETUP_TIME);
|
||||
return firstSetupTime > endTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the screen attention settings is enabled. Contextual card will only appear
|
||||
* when the screen attention settings is available.
|
||||
*
|
||||
* @return {@code true} if screen attention settings is enabled, otherwise {@code false}
|
||||
*/
|
||||
@VisibleForTesting
|
||||
boolean isSettingsAvailable() {
|
||||
return isControllerAvailable(mContext) == AVAILABLE;
|
||||
}
|
||||
}
|
@@ -26,6 +26,7 @@ import android.util.ArrayMap;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.display.AdaptiveSleepPreferenceController;
|
||||
import com.android.settings.flashlight.FlashlightSlice;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
|
||||
import com.android.settings.homepage.contextualcards.deviceinfo.DataUsageSlice;
|
||||
@@ -34,6 +35,7 @@ import com.android.settings.homepage.contextualcards.deviceinfo.EmergencyInfoSli
|
||||
import com.android.settings.homepage.contextualcards.deviceinfo.StorageSlice;
|
||||
import com.android.settings.homepage.contextualcards.slices.BatteryFixSlice;
|
||||
import com.android.settings.homepage.contextualcards.slices.BluetoothDevicesSlice;
|
||||
import com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice;
|
||||
import com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice;
|
||||
import com.android.settings.homepage.contextualcards.slices.LowStorageSlice;
|
||||
import com.android.settings.homepage.contextualcards.slices.NotificationChannelSlice;
|
||||
@@ -64,6 +66,16 @@ public class CustomSliceRegistry {
|
||||
.appendPath(SettingsSlicesContract.KEY_AIRPLANE_MODE)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Uri for Contextual Adaptive Sleep Slice
|
||||
*/
|
||||
public static final Uri CONTEXTUAL_ADAPTIVE_SLEEP_URI = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.appendPath(SettingsSlicesContract.PATH_SETTING_INTENT)
|
||||
.appendPath(AdaptiveSleepPreferenceController.PREF_NAME)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Uri for Battery Fix Slice.
|
||||
*/
|
||||
@@ -328,6 +340,7 @@ public class CustomSliceRegistry {
|
||||
|
||||
sUriToSlice.put(BATTERY_FIX_SLICE_URI, BatteryFixSlice.class);
|
||||
sUriToSlice.put(BLUETOOTH_DEVICES_SLICE_URI, BluetoothDevicesSlice.class);
|
||||
sUriToSlice.put(CONTEXTUAL_ADAPTIVE_SLEEP_URI, ContextualAdaptiveSleepSlice.class);
|
||||
sUriToSlice.put(CONTEXTUAL_NOTIFICATION_CHANNEL_SLICE_URI,
|
||||
ContextualNotificationChannelSlice.class);
|
||||
sUriToSlice.put(CONTEXTUAL_WIFI_SLICE_URI, ContextualWifiSlice.class);
|
||||
@@ -337,12 +350,12 @@ public class CustomSliceRegistry {
|
||||
sUriToSlice.put(FLASHLIGHT_SLICE_URI, FlashlightSlice.class);
|
||||
sUriToSlice.put(LOCATION_SLICE_URI, LocationSlice.class);
|
||||
sUriToSlice.put(LOW_STORAGE_SLICE_URI, LowStorageSlice.class);
|
||||
sUriToSlice.put(MEDIA_OUTPUT_INDICATOR_SLICE_URI, MediaOutputIndicatorSlice.class);
|
||||
sUriToSlice.put(MEDIA_OUTPUT_SLICE_URI, MediaOutputSlice.class);
|
||||
sUriToSlice.put(MOBILE_DATA_SLICE_URI, MobileDataSlice.class);
|
||||
sUriToSlice.put(NOTIFICATION_CHANNEL_SLICE_URI, NotificationChannelSlice.class);
|
||||
sUriToSlice.put(STORAGE_SLICE_URI, StorageSlice.class);
|
||||
sUriToSlice.put(WIFI_SLICE_URI, WifiSlice.class);
|
||||
sUriToSlice.put(MEDIA_OUTPUT_SLICE_URI, MediaOutputSlice.class);
|
||||
sUriToSlice.put(MEDIA_OUTPUT_INDICATOR_SLICE_URI, MediaOutputIndicatorSlice.class);
|
||||
}
|
||||
|
||||
public static Class<? extends CustomSliceable> getSliceClassByUri(Uri uri) {
|
||||
|
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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.homepage.contextualcards.slices;
|
||||
|
||||
import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.DEFERRED_TIME_DAYS;
|
||||
import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF;
|
||||
import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF_KEY_SETUP_TIME;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceProvider;
|
||||
import androidx.slice.widget.SliceLiveData;
|
||||
|
||||
import com.android.settings.slices.CustomSliceRegistry;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class ContextualAdaptiveSleepSliceTest {
|
||||
|
||||
private static final String pkgName = "adaptive_sleep";
|
||||
private Context mContext;
|
||||
private ContextualAdaptiveSleepSlice mContextualAdaptiveSleepSlice;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private SharedPreferences mSharedPreferences;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mContextualAdaptiveSleepSlice = spy(new ContextualAdaptiveSleepSlice(mContext));
|
||||
|
||||
doReturn(mPackageManager).when(mContext).getPackageManager();
|
||||
doReturn(mSharedPreferences).when(mContext).getSharedPreferences(eq(PREF), anyInt());
|
||||
doReturn(true).when(mContextualAdaptiveSleepSlice).isSettingsAvailable();
|
||||
doReturn(pkgName).when(mPackageManager).getAttentionServicePackageName();
|
||||
doReturn(-DEFERRED_TIME_DAYS).when(mSharedPreferences).getLong(eq(PREF_KEY_SETUP_TIME),
|
||||
anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUri_shouldReturnContextualAdaptiveSleepSliceUri() {
|
||||
final Uri uri = mContextualAdaptiveSleepSlice.getUri();
|
||||
|
||||
assertThat(uri).isEqualTo(CustomSliceRegistry.CONTEXTUAL_ADAPTIVE_SLEEP_URI);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSlice_ShowIfFeatureIsAvailable() {
|
||||
final Slice slice = mContextualAdaptiveSleepSlice.getSlice();
|
||||
|
||||
assertThat(slice).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSlice_DoNotShowIfFeatureIsUnavailable() {
|
||||
doReturn(false).when(mContextualAdaptiveSleepSlice).isSettingsAvailable();
|
||||
|
||||
final Slice slice = mContextualAdaptiveSleepSlice.getSlice();
|
||||
|
||||
assertThat(slice).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSlice_ShowIfNotRecentlySetup() {
|
||||
final Slice slice = mContextualAdaptiveSleepSlice.getSlice();
|
||||
|
||||
assertThat(slice).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSlice_DoNotShowIfRecentlySetup() {
|
||||
doReturn(System.currentTimeMillis()).when(mSharedPreferences).getLong(
|
||||
eq(PREF_KEY_SETUP_TIME), anyLong());
|
||||
|
||||
final Slice slice = mContextualAdaptiveSleepSlice.getSlice();
|
||||
|
||||
assertThat(slice).isNull();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user