2 * Copyright (C) 2018 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.settings.notification;
19 import android.app.Activity;
20 import android.app.NotificationManager;
21 import android.app.NotificationManager.Policy;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.SharedPreferences;
25 import android.os.Bundle;
26 import android.provider.Settings;
27 import android.text.format.DateUtils;
28 import android.util.Log;
29 import android.view.View;
30 import android.widget.RadioButton;
32 import com.android.internal.logging.MetricsLogger;
33 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
34 import com.android.settings.R;
35 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
36 import com.android.settings.overlay.FeatureFactory;
38 import androidx.annotation.VisibleForTesting;
40 public class ZenOnboardingActivity extends Activity {
42 private static final String TAG = "ZenOnboardingActivity";
45 static final String PREF_KEY_SUGGESTION_FIRST_DISPLAY_TIME =
46 "pref_zen_suggestion_first_display_time_ms";
48 static final long ALWAYS_SHOW_THRESHOLD = DateUtils.DAY_IN_MILLIS * 14;
51 View mKeepCurrentSetting;
52 RadioButton mNewSettingButton;
53 RadioButton mKeepCurrentSettingButton;
55 private NotificationManager mNm;
56 private MetricsLogger mMetrics;
59 protected void onCreate(Bundle savedInstanceState) {
60 super.onCreate(savedInstanceState);
61 setNotificationManager(getSystemService(NotificationManager.class));
62 setMetricsLogger(new MetricsLogger());
64 Context context = getApplicationContext();
65 Settings.Global.putInt(context.getContentResolver(),
66 Settings.Global.ZEN_SETTINGS_SUGGESTION_VIEWED, 1);
72 protected void setupUI() {
73 setContentView(R.layout.zen_onboarding);
75 mNewSetting = findViewById(R.id.zen_onboarding_new_setting);
76 mKeepCurrentSetting = findViewById(R.id.zen_onboarding_current_setting);
77 mNewSettingButton = findViewById(R.id.zen_onboarding_new_setting_button);
78 mKeepCurrentSettingButton = findViewById(R.id.zen_onboarding_current_setting_button);
80 View.OnClickListener newSettingClickListener = new View.OnClickListener() {
82 public void onClick(View v) {
83 mKeepCurrentSettingButton.setChecked(false);
84 mNewSettingButton.setChecked(true);
88 View.OnClickListener currentSettingClickListener = new View.OnClickListener() {
90 public void onClick(View v) {
91 mKeepCurrentSettingButton.setChecked(true);
92 mNewSettingButton.setChecked(false);
96 mNewSetting.setOnClickListener(newSettingClickListener);
97 mNewSettingButton.setOnClickListener(newSettingClickListener);
99 mKeepCurrentSetting.setOnClickListener(currentSettingClickListener);
100 mKeepCurrentSettingButton.setOnClickListener(currentSettingClickListener);
102 mKeepCurrentSettingButton.setChecked(true);
103 mMetrics.visible(MetricsEvent.SETTINGS_ZEN_ONBOARDING);
107 protected void setNotificationManager(NotificationManager nm) {
112 protected void setMetricsLogger(MetricsLogger ml) {
116 public void launchSettings(View button) {
117 mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_SETTINGS);
118 Intent settings = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
119 settings.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
120 startActivity(settings);
123 public void save(View button) {
124 NotificationManager.Policy policy = mNm.getNotificationPolicy();
126 if (mNewSettingButton.isChecked()) {
127 NotificationManager.Policy newPolicy = new NotificationManager.Policy(
128 Policy.PRIORITY_CATEGORY_REPEAT_CALLERS | policy.priorityCategories,
129 Policy.PRIORITY_SENDERS_STARRED,
130 policy.priorityMessageSenders,
131 NotificationManager.Policy.getAllSuppressedVisualEffects());
132 mNm.setNotificationPolicy(newPolicy);
133 mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_OK);
135 mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_KEEP_CURRENT_SETTINGS);
138 Settings.Global.putInt(getApplicationContext().getContentResolver(),
139 Settings.Global.ZEN_SETTINGS_UPDATED, 1);
141 finishAndRemoveTask();
144 public static boolean isSuggestionComplete(Context context) {
145 if (wasZenUpdated(context)) {
149 if (showSuggestion(context) || withinShowTimeThreshold(context)) {
156 private static boolean wasZenUpdated(Context context) {
157 // ZEN_SETTINGS_UPDATED is true for:
159 // - if zen visual effects values were changed by the user in Settings
160 NotificationManager nm = context.getSystemService(NotificationManager.class);
161 if (NotificationManager.Policy.areAllVisualEffectsSuppressed(
162 nm.getNotificationPolicy().suppressedVisualEffects)) {
163 Settings.Global.putInt(context.getContentResolver(),
164 Settings.Global.ZEN_SETTINGS_UPDATED, 1);
166 return Settings.Global.getInt(context.getContentResolver(),
167 Settings.Global.ZEN_SETTINGS_UPDATED, 0) != 0;
170 private static boolean showSuggestion(Context context) {
171 // SHOW_ZEN_SETTINGS_SUGGESTION is by default true, but false when:
172 // - user manually turns on dnd
174 // SHOW_ZEN_SETTINGS_SUGGESTION is also true when:
175 // - automatic rule has started DND and user has not seen the first use dialog
176 return Settings.Global.getInt(context.getContentResolver(),
177 Settings.Global.SHOW_ZEN_SETTINGS_SUGGESTION, 0) != 0;
181 private static boolean withinShowTimeThreshold(Context context) {
182 final SuggestionFeatureProvider featureProvider = FeatureFactory.getFactory(context)
183 .getSuggestionFeatureProvider(context);
184 final SharedPreferences prefs = featureProvider.getSharedPrefs(context);
185 final long currentTimeMs = System.currentTimeMillis();
186 final long firstDisplayTimeMs;
188 if (!prefs.contains(PREF_KEY_SUGGESTION_FIRST_DISPLAY_TIME)) {
189 firstDisplayTimeMs = currentTimeMs;
190 prefs.edit().putLong(PREF_KEY_SUGGESTION_FIRST_DISPLAY_TIME, currentTimeMs).commit();
192 firstDisplayTimeMs = prefs.getLong(PREF_KEY_SUGGESTION_FIRST_DISPLAY_TIME, -1);
195 final long showTimeMs = firstDisplayTimeMs + ALWAYS_SHOW_THRESHOLD;
196 final boolean stillShow = currentTimeMs < showTimeMs;
198 Log.d(TAG, "still show zen suggestion based on time: " + stillShow + " showTimeMs="