blob: c477abc986b6fd6d966fde05b8e3da3e3b953a36 [file] [log] [blame]
Yi Jiang76054942019-04-16 14:51:11 -07001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.settings.homepage.contextualcards.slices;
18
Yi Jiang068062d2019-06-04 20:14:10 -070019import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
Yi Jiang76054942019-04-16 14:51:11 -070020import static com.android.settings.display.AdaptiveSleepPreferenceController.PREF_NAME;
21import static com.android.settings.display.AdaptiveSleepPreferenceController.isControllerAvailable;
22import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_ADAPTIVE_SLEEP_URI;
23
24import android.app.PendingIntent;
25import android.app.settings.SettingsEnums;
26import android.content.Context;
27import android.content.Intent;
28import android.net.Uri;
Yi Jiang811908f2019-07-15 17:14:33 -070029import android.provider.Settings;
Yi Jiang76054942019-04-16 14:51:11 -070030
31import androidx.core.graphics.drawable.IconCompat;
32import androidx.slice.Slice;
33import androidx.slice.builders.ListBuilder;
34import androidx.slice.builders.SliceAction;
35
36import com.android.settings.R;
37import com.android.settings.SubSettings;
38import com.android.settings.display.AdaptiveSleepSettings;
39import com.android.settings.slices.CustomSliceable;
40import com.android.settings.slices.SliceBuilderUtils;
41
42import com.google.common.annotations.VisibleForTesting;
43
44import java.util.concurrent.TimeUnit;
45
46public class ContextualAdaptiveSleepSlice implements CustomSliceable {
47 private static final String TAG = "ContextualAdaptiveSleepSlice";
48 private static final long DEFAULT_SETUP_TIME = 0;
49 private Context mContext;
50
51 @VisibleForTesting
52 static final long DEFERRED_TIME_DAYS = TimeUnit.DAYS.toMillis(14);
53 @VisibleForTesting
54 static final String PREF_KEY_SETUP_TIME = "adaptive_sleep_setup_time";
55
56 public static final String PREF_KEY_INTERACTED = "adaptive_sleep_interacted";
57 public static final String PREF = "adaptive_sleep_slice";
58
59 public ContextualAdaptiveSleepSlice(Context context) {
60 mContext = context;
61 }
62
63 @Override
64 public Slice getSlice() {
65 final long setupTime = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE).getLong(
66 PREF_KEY_SETUP_TIME, DEFAULT_SETUP_TIME);
67 if (setupTime == DEFAULT_SETUP_TIME) {
68 // Set the first setup time.
69 mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE)
70 .edit()
71 .putLong(PREF_KEY_SETUP_TIME, System.currentTimeMillis())
72 .apply();
73 return null;
74 }
75
Yi Jiang811908f2019-07-15 17:14:33 -070076 // Display the contextual card only if all the following 4 conditions hold:
77 // 1. The Screen Attention is available in Settings.
Yi Jiang76054942019-04-16 14:51:11 -070078 // 2. The device is not recently set up.
79 // 3. Current user hasn't opened Screen Attention's settings page before.
Yi Jiang811908f2019-07-15 17:14:33 -070080 // 4. Screen Attention is off.
81 if (isSettingsAvailable() && !isUserInteracted() && !isRecentlySetup() && !isTurnedOn()) {
Yi Jiang76054942019-04-16 14:51:11 -070082 final IconCompat icon = IconCompat.createWithResource(mContext,
83 R.drawable.ic_settings_adaptive_sleep);
84 final CharSequence title = mContext.getText(R.string.adaptive_sleep_title);
Yi Jiang9df180a2019-06-04 12:08:42 -070085 final CharSequence subtitle = mContext.getText(
86 R.string.adaptive_sleep_contextual_slice_summary);
Yi Jiang76054942019-04-16 14:51:11 -070087
88 final SliceAction pAction = SliceAction.createDeeplink(getPrimaryAction(),
89 icon,
90 ListBuilder.ICON_IMAGE,
91 title);
92 final ListBuilder listBuilder = new ListBuilder(mContext,
93 CONTEXTUAL_ADAPTIVE_SLEEP_URI,
94 ListBuilder.INFINITY)
Yi Jiang068062d2019-06-04 20:14:10 -070095 .setAccentColor(COLOR_NOT_TINTED)
Yi Jiang76054942019-04-16 14:51:11 -070096 .addRow(new ListBuilder.RowBuilder()
97 .setTitleItem(icon, ListBuilder.ICON_IMAGE)
98 .setTitle(title)
99 .setSubtitle(subtitle)
100 .setPrimaryAction(pAction));
101 return listBuilder.build();
102 } else {
103 return null;
104 }
105 }
106
107 @Override
108 public Uri getUri() {
109 return CONTEXTUAL_ADAPTIVE_SLEEP_URI;
110 }
111
112 @Override
113 public Intent getIntent() {
114 final CharSequence screenTitle = mContext.getText(R.string.adaptive_sleep_title);
115 final Uri contentUri = new Uri.Builder().appendPath(PREF_NAME).build();
116 return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
117 AdaptiveSleepSettings.class.getName(), PREF_NAME, screenTitle.toString(),
118 SettingsEnums.SLICE).setClassName(mContext.getPackageName(),
119 SubSettings.class.getName()).setData(contentUri);
120 }
121
122 private PendingIntent getPrimaryAction() {
123 final Intent intent = getIntent();
124 return PendingIntent.getActivity(mContext, 0 /* requestCode */, intent, 0 /* flags */);
125 }
126
127 /**
Yi Jiang811908f2019-07-15 17:14:33 -0700128 * @return {@code true} if the feature is turned on for the device, otherwise {@code false}
129 */
130 private boolean isTurnedOn() {
131 return Settings.System.getInt(
132 mContext.getContentResolver(), Settings.System.ADAPTIVE_SLEEP, 0) != 0;
133 }
134
135 /**
Yi Jiang76054942019-04-16 14:51:11 -0700136 * @return {@code true} if the current user has opened the Screen Attention settings page
137 * before, otherwise {@code false}.
138 */
139 private boolean isUserInteracted() {
140 return mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE).getBoolean(
141 PREF_KEY_INTERACTED, false);
142 }
143
144 /**
145 * The device is recently set up means its first settings-open time is within 2 weeks ago.
146 *
147 * @return {@code true} if the device is recently set up, otherwise {@code false}.
148 */
149 private boolean isRecentlySetup() {
150 final long endTime = System.currentTimeMillis() - DEFERRED_TIME_DAYS;
151 final long firstSetupTime = mContext.getSharedPreferences(PREF,
152 Context.MODE_PRIVATE).getLong(PREF_KEY_SETUP_TIME, DEFAULT_SETUP_TIME);
153 return firstSetupTime > endTime;
154 }
155
156 /**
157 * Check whether the screen attention settings is enabled. Contextual card will only appear
158 * when the screen attention settings is available.
159 *
160 * @return {@code true} if screen attention settings is enabled, otherwise {@code false}
161 */
162 @VisibleForTesting
163 boolean isSettingsAvailable() {
Yi Jiang068062d2019-06-04 20:14:10 -0700164 return isControllerAvailable(mContext) == AVAILABLE_UNSEARCHABLE;
Yi Jiang76054942019-04-16 14:51:11 -0700165 }
166}