DO NOT MERGE Add DND Settings suggestion

Test: SettingsSuggestionsTest, ZenOnboardingActivityTest
Change-Id: Ie78c9cf8287ee56bc4596efe20d27f8eb432ab6c
Bug: 78445134
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 060429e..d55493c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -743,6 +743,27 @@
         </activity>
 
         <activity
+            android:name=".notification.ZenSuggestionActivity"
+            android:label="@string/zen_mode_settings_title"
+            android:icon="@drawable/ic_zen"
+            android:theme="@android:style/Theme.NoDisplay">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.android.settings.suggested.category.ZEN" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.android.settings.suggested.category.FIRST_IMPRESSION" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.dismiss"
+                       android:value="0" />
+            <meta-data android:name="com.android.settings.title"
+                       android:resource="@string/zen_suggestion_title" />
+            <meta-data android:name="com.android.settings.summary"
+                       android:resource="@string/zen_suggestion_summary" />
+        </activity>
+
+        <activity
             android:name=".notification.ZenOnboardingActivity"
             android:label="@string/zen_onboarding_dnd_visual_disturbances_header"
             android:icon="@drawable/ic_settings_notifications"
@@ -755,7 +776,6 @@
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>
-
         <activity
             android:name="Settings$ZenModeAutomationSettingsActivity"
             android:label="@string/zen_mode_automation_settings_title"
diff --git a/res/drawable/ic_zen.xml b/res/drawable/ic_zen.xml
index 8c50d5d..2c55e02 100644
--- a/res/drawable/ic_zen.xml
+++ b/res/drawable/ic_zen.xml
@@ -14,13 +14,13 @@
      limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:viewportHeight="24.0"
-    android:viewportWidth="24.0"
-    android:height="24dp"
-    android:width="24dp" >
+        android:viewportHeight="24.0"
+        android:viewportWidth="24.0"
+        android:height="24dp"
+        android:width="24dp" >
 
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4 11H8c-.55 0-1-.45-1-1s.45-1 1-1h8c.55 0 1 .45 1 1s-.45 1-1 1z" />
+        android:fillColor="?android:attr/colorControlActivated"
+        android:pathData="M 12 2 C 6.48 2 2 6.48 2 12 s 4.48 10 10 10 10 -4.48 10 -10 S 17.52 2 12 2 z m 4 11 H 8 c -.55 0 -1 -.45 -1 -1 s .45 -1 1 -1 h 8c.55 0 1 .45 1 1 s -.45 1 -1 1z" />
 
 </vector>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8bdfb5f..da95791 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9874,6 +9874,12 @@
     <!-- Help URI, smart battery page [DO NOT TRANSLATE] -->
     <string name="help_uri_smart_battery_settings" translatable="false"></string>
 
+    <!-- Title label for dnd suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] -->
+    <string name="zen_suggestion_title">Update Do Not Disturb</string>
+
+    <!-- Summary label for dnd suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] -->
+    <string name="zen_suggestion_summary">Hide notifications to stay focused</string>
+
     <!-- Title label for new device suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] -->
     <string name="new_device_suggestion_title">What\'s new and exciting?</string>
 
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
index d0c0b25..257e8c3 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
@@ -22,7 +22,6 @@
 import android.content.SharedPreferences;
 import android.service.settings.suggestions.Suggestion;
 import android.support.annotation.NonNull;
-import android.support.annotation.VisibleForTesting;
 import android.util.Log;
 import android.util.Pair;
 
@@ -32,6 +31,8 @@
 import com.android.settings.display.NightDisplayPreferenceController;
 import com.android.settings.fingerprint.FingerprintEnrollSuggestionActivity;
 import com.android.settings.fingerprint.FingerprintSuggestionActivity;
+import com.android.settings.notification.ZenOnboardingActivity;
+import com.android.settings.notification.ZenSuggestionActivity;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.password.ScreenLockSuggestionActivity;
 import com.android.settings.support.NewDeviceIntroSuggestionActivity;
@@ -88,6 +89,8 @@
             return NightDisplayPreferenceController.isSuggestionComplete(context);
         } else if (className.equals(NewDeviceIntroSuggestionActivity.class.getName())) {
             return NewDeviceIntroSuggestionActivity.isSuggestionComplete(context);
+        } else if (className.equals(ZenSuggestionActivity.class.getName())) {
+            return ZenOnboardingActivity.isSuggestionComplete(context);
         }
         return false;
     }
diff --git a/src/com/android/settings/notification/ZenModeBackend.java b/src/com/android/settings/notification/ZenModeBackend.java
index d579256..9e2b650 100644
--- a/src/com/android/settings/notification/ZenModeBackend.java
+++ b/src/com/android/settings/notification/ZenModeBackend.java
@@ -135,6 +135,9 @@
     }
 
     protected void saveVisualEffectsPolicy(int category, boolean suppress) {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.ZEN_SETTINGS_UPDATED, 1);
+
         int suppressedEffects = getNewSuppressedEffects(suppress, category);
         savePolicy(mPolicy.priorityCategories, mPolicy.priorityCallSenders,
                 mPolicy.priorityMessageSenders, suppressedEffects);
diff --git a/src/com/android/settings/notification/ZenOnboardingActivity.java b/src/com/android/settings/notification/ZenOnboardingActivity.java
index 9d71f54..ff86ef6 100644
--- a/src/com/android/settings/notification/ZenOnboardingActivity.java
+++ b/src/com/android/settings/notification/ZenOnboardingActivity.java
@@ -19,16 +19,33 @@
 import android.app.Activity;
 import android.app.NotificationManager;
 import android.app.NotificationManager.Policy;
+import android.content.Context;
+import android.content.SharedPreferences;
 import android.os.Bundle;
-import android.support.annotation.VisibleForTesting;
+import android.provider.Settings;
+import android.text.format.DateUtils;
+import android.util.Log;
 import android.view.View;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
+import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
+import com.android.settings.overlay.FeatureFactory;
 
 public class ZenOnboardingActivity extends Activity {
 
+    private static final String TAG = "ZenOnboardingActivity";
+
+    @VisibleForTesting
+    static final String PREF_KEY_SUGGGESTION_FIRST_DISPLAY_TIME =
+            "pref_zen_suggestion_first_display_time_ms";
+    @VisibleForTesting
+    static final String PREF_KEY_SUGGESTION_VIEWED = "pref_zen_suggestion_viewed";
+    @VisibleForTesting
+    static final long ALWAYS_SHOW_THRESHOLD = DateUtils.DAY_IN_MILLIS * 14;
+
     private NotificationManager mNm;
     private MetricsLogger mMetrics;
 
@@ -38,6 +55,10 @@
         setNotificationManager(getSystemService(NotificationManager.class));
         setMetricsLogger(new MetricsLogger());
 
+        Context context = getApplicationContext();
+        Settings.Global.putInt(context.getContentResolver(),
+                Settings.Global.ZEN_SETTINGS_SUGGESTION_VIEWED, 1);
+
         setupUI();
     }
 
@@ -60,20 +81,79 @@
 
     public void close(View button) {
         mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_KEEP_CURRENT_SETTINGS);
+
+        Settings.Global.putInt(getApplicationContext().getContentResolver(),
+                Settings.Global.ZEN_SETTINGS_UPDATED, 1);
+
         finishAndRemoveTask();
     }
 
     public void save(View button) {
         mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_OK);
-        Policy policy = mNm.getNotificationPolicy();
+        NotificationManager.Policy policy = mNm.getNotificationPolicy();
 
-        Policy newPolicy = new NotificationManager.Policy(
+        NotificationManager.Policy newPolicy = new NotificationManager.Policy(
                 Policy.PRIORITY_CATEGORY_REPEAT_CALLERS | policy.priorityCategories,
                 Policy.PRIORITY_SENDERS_STARRED,
                 policy.priorityMessageSenders,
-                Policy.getAllSuppressedVisualEffects());
+                NotificationManager.Policy.getAllSuppressedVisualEffects());
         mNm.setNotificationPolicy(newPolicy);
 
+        Settings.Global.putInt(getApplicationContext().getContentResolver(),
+                Settings.Global.ZEN_SETTINGS_UPDATED, 1);
+
         finishAndRemoveTask();
     }
+
+    public static boolean isSuggestionComplete(Context context) {
+        if (wasZenUpdated(context)) {
+            return true;
+        }
+
+        if (showSuggestion(context) || withinShowTimeThreshold(context)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private static boolean wasZenUpdated(Context context) {
+        // ZEN_SETTINGS_UPDATED is true for:
+        // - fresh P+ device
+        // - if zen visual effects values were changed by the user in Settings
+        return Settings.Global.getInt(context.getContentResolver(),
+                Settings.Global.ZEN_SETTINGS_UPDATED, 0) != 0;
+    }
+
+    private static boolean showSuggestion(Context context) {
+        // SHOW_ZEN_SETTINGS_SUGGESTION is by default true, but false when:
+        // - user manually turns on dnd
+
+        // SHOW_ZEN_SETTINGS_SUGGESTION is also true when:
+        // - automatic rule has started DND and user has not seen the first use dialog
+        return Settings.Global.getInt(context.getContentResolver(),
+                Settings.Global.SHOW_ZEN_SETTINGS_SUGGESTION, 0) != 0;
+
+    }
+
+    private static boolean withinShowTimeThreshold(Context context) {
+        final SuggestionFeatureProvider featureProvider = FeatureFactory.getFactory(context)
+                .getSuggestionFeatureProvider(context);
+        final SharedPreferences prefs = featureProvider.getSharedPrefs(context);
+        final long currentTimeMs = System.currentTimeMillis();
+        final long firstDisplayTimeMs;
+
+        if (!prefs.contains(PREF_KEY_SUGGGESTION_FIRST_DISPLAY_TIME)) {
+            firstDisplayTimeMs = currentTimeMs;
+            prefs.edit().putLong(PREF_KEY_SUGGGESTION_FIRST_DISPLAY_TIME, currentTimeMs).commit();
+        } else {
+            firstDisplayTimeMs = prefs.getLong(PREF_KEY_SUGGGESTION_FIRST_DISPLAY_TIME, -1);
+        }
+
+        final long showTimeMs = firstDisplayTimeMs + ALWAYS_SHOW_THRESHOLD;
+        final boolean stillShow = currentTimeMs < showTimeMs;
+
+        Log.d(TAG, "still show zen suggestion based on time: " + stillShow);
+        return stillShow;
+    }
 }
diff --git a/src/com/android/settings/notification/ZenSuggestionActivity.java b/src/com/android/settings/notification/ZenSuggestionActivity.java
new file mode 100644
index 0000000..9d2148c
--- /dev/null
+++ b/src/com/android/settings/notification/ZenSuggestionActivity.java
@@ -0,0 +1,24 @@
+package com.android.settings.notification;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.Settings;
+
+public class ZenSuggestionActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // start up zen settings activity
+        Intent settingsIntent = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
+        startActivity(settingsIntent);
+
+        // start up onboarding activity
+        Intent onboardingActivity = new Intent(Settings.ZEN_MODE_ONBOARDING);
+        startActivity(onboardingActivity);
+
+        finish();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java b/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java
index 7bc9371..b4d3700 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java
@@ -29,6 +29,12 @@
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
 
+import static com.android.settings.notification.ZenOnboardingActivity.ALWAYS_SHOW_THRESHOLD;
+import static com.android.settings.notification.ZenOnboardingActivity.PREF_KEY_SUGGESTION_VIEWED;
+import static com.android.settings.notification.ZenOnboardingActivity
+        .PREF_KEY_SUGGGESTION_FIRST_DISPLAY_TIME;
+import static com.android.settings.notification.ZenOnboardingActivity.isSuggestionComplete;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -39,20 +45,22 @@
 import android.app.NotificationManager;
 import android.app.NotificationManager.Policy;
 import android.content.Context;
+import android.content.SharedPreferences;
+import android.provider.Settings;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Answers;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 public class ZenOnboardingActivityTest {
@@ -64,6 +72,9 @@
 
     ZenOnboardingActivity mActivity;
 
+    private Context mContext;
+    private FakeFeatureFactory mFeatureFactory;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -75,6 +86,11 @@
         mActivity.setMetricsLogger(mMetricsLogger);
 
         mActivity.setupUI();
+
+        mContext = RuntimeEnvironment.application;
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
+        when(mFeatureFactory.suggestionsFeatureProvider.getSharedPrefs(any(Context.class)))
+                .thenReturn(getSharedPreferences());
     }
 
     @Test
@@ -124,4 +140,73 @@
 
         verify(mNm, never()).setNotificationPolicy(any());
     }
+
+    @Test
+    public void isSuggestionComplete_zenUpdated() {
+        setZenUpdated(true);
+        setShowSettingsSuggestion(false);
+        setWithinTimeThreshold(true);
+        assertThat(isSuggestionComplete(mContext)).isTrue();
+    }
+
+    @Test
+    public void isSuggestionComplete_withinTimeThreshold() {
+        setZenUpdated(false);
+        setShowSettingsSuggestion(false);
+        setWithinTimeThreshold(true);
+        assertThat(isSuggestionComplete(mContext)).isFalse();
+    }
+
+    @Test
+    public void isSuggestionComplete_showSettingsSuggestionTrue() {
+        setZenUpdated(false);
+        setShowSettingsSuggestion(true);
+        setWithinTimeThreshold(false);
+        assertThat(isSuggestionComplete(mContext)).isFalse();
+    }
+
+    @Test
+    public void isSuggestionComplete_showSettingsSuggestionFalse_notWithinTimeThreshold() {
+        setZenUpdated(false);
+        setShowSettingsSuggestion(false);
+        setWithinTimeThreshold(false);
+        assertThat(isSuggestionComplete(mContext)).isTrue();
+    }
+
+    private void setZenUpdated(boolean updated) {
+        int zenUpdated = 0;
+        if (updated) {
+            zenUpdated = 1;
+        }
+
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.ZEN_SETTINGS_UPDATED, zenUpdated);
+    }
+
+    private void setWithinTimeThreshold(boolean withinTime) {
+        long firstTime = System.currentTimeMillis();
+
+        if (withinTime) {
+            firstTime -= ALWAYS_SHOW_THRESHOLD / 2;
+        } else {
+            firstTime -= ALWAYS_SHOW_THRESHOLD * 2;
+        }
+
+        getSharedPreferences().edit().putLong(PREF_KEY_SUGGGESTION_FIRST_DISPLAY_TIME,
+               firstTime).commit();
+    }
+
+    private void setShowSettingsSuggestion(boolean show) {
+        int showZenSuggestion = 0;
+        if (show) {
+            showZenSuggestion = 1;
+        }
+
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.SHOW_ZEN_SETTINGS_SUGGESTION, showZenSuggestion);
+    }
+
+    private SharedPreferences getSharedPreferences() {
+        return mContext.getSharedPreferences("test_zen_sugg", Context.MODE_PRIVATE);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/suggestions/SettingsSuggestionsTest.java b/tests/robotests/src/com/android/settings/suggestions/SettingsSuggestionsTest.java
index bb14667..c6583c7 100644
--- a/tests/robotests/src/com/android/settings/suggestions/SettingsSuggestionsTest.java
+++ b/tests/robotests/src/com/android/settings/suggestions/SettingsSuggestionsTest.java
@@ -30,6 +30,8 @@
 import com.android.settings.Settings;
 import com.android.settings.fingerprint.FingerprintEnrollSuggestionActivity;
 import com.android.settings.fingerprint.FingerprintSuggestionActivity;
+import com.android.settings.notification.ZenOnboardingActivity;
+import com.android.settings.notification.ZenSuggestionActivity;
 import com.android.settings.support.NewDeviceIntroSuggestionActivity;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.wallpaper.WallpaperSuggestionActivity;
@@ -83,6 +85,14 @@
     }
 
     @Test
+    public void zenSuggestion_isValid() {
+        assertSuggestionEquals(
+                ZenSuggestionActivity.class.getName(),
+                R.string.zen_suggestion_title,
+                R.string.zen_suggestion_summary);
+    }
+
+    @Test
     public void newDeviceIntroSuggestion_isValid() {
         assertSuggestionEquals(
             NewDeviceIntroSuggestionActivity.class.getName(),
diff --git a/tests/robotests/src/com/android/settings/support/NewDeviceIntroSuggestionActivityTest.java b/tests/robotests/src/com/android/settings/support/NewDeviceIntroSuggestionActivityTest.java
index 1597568..286676d 100644
--- a/tests/robotests/src/com/android/settings/support/NewDeviceIntroSuggestionActivityTest.java
+++ b/tests/robotests/src/com/android/settings/support/NewDeviceIntroSuggestionActivityTest.java
@@ -78,7 +78,7 @@
         final long currentTime = System.currentTimeMillis();
 
         getSharedPreferences().edit().putLong(PREF_KEY_SUGGGESTION_FIRST_DISPLAY_TIME,
-                currentTime - 2 * PERMANENT_DISMISS_THRESHOLD);
+                currentTime - 2 * PERMANENT_DISMISS_THRESHOLD).commit();
         assertThat(isSuggestionComplete(mContext)).isTrue();
     }