diff --git a/Android.bp b/Android.bp
index db94eec..5730600 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12,15 +12,26 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+android_library {
+    name: "ExtServices-core",
+     srcs: [
+         "src/**/*.java",
+     ],
+     resource_dirs: [
+         "res",
+     ],
+
+     manifest: "AndroidManifest.xml",
+}
+
 android_app {
     name: "ExtServices",
     srcs: ["src/**/*.java"],
     platform_apis: true,
     certificate: "platform",
-    aaptflags: ["--shared-lib"],
-    export_package_resources: true,
     optimize: {
         proguard_flags_files: ["proguard.proguard"],
     },
     privileged: true,
+    min_sdk_version: "28",
 }
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 45e557c..c3f6a65 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -17,11 +17,21 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     package="android.ext.services"
-    android:versionCode="1"
-    android:versionName="1"
+    android:versionCode="290000000"
+    android:versionName="2019-09"
     coreApp="true">
 
     <uses-permission android:name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE" />
+    <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
+
+    <uses-permission android:name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE" />
+    <uses-permission android:name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+
+    <uses-sdk
+        android:minSdkVersion="29"
+        android:targetSdkVersion="29"
+    />
 
     <application android:label="@string/app_name"
         android:defaultToDeviceProtectedStorage="true"
@@ -35,9 +45,8 @@
         </service>
 
         <service android:name=".resolver.LRResolverRankerService"
-                 android:permission="android.permission.BIND_RESOLVER_RANKER_SERVICE"
-                 android:priority="-1" >
-            <intent-filter>
+                 android:permission="android.permission.BIND_RESOLVER_RANKER_SERVICE">
+            <intent-filter android:priority="-1">
                 <action android:name="android.service.resolver.ResolverRankerService" />
             </intent-filter>
         </service>
@@ -64,6 +73,24 @@
                 android:resource="@array/autofill_field_classification_available_algorithms" />
         </service>
 
+        <service android:name=".sms.FinancialSmsServiceImpl"
+                 android:permission="android.permission.BIND_FINANCIAL_SMS_SERVICE">
+            <intent-filter>
+                <action android:name="android.service.sms.action.FINANCIAL_SERVICE_INTENT" />
+            </intent-filter>
+        </service>
+
+        <service android:name=".watchdog.ExplicitHealthCheckServiceImpl"
+                 android:permission="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE">
+            <intent-filter>
+                <action android:name="android.service.watchdog.ExplicitHealthCheckService" />
+            </intent-filter>
+        </service>
+
+        <activity android:name=".notification.CopyCodeActivity"
+                  android:exported="false"
+                  android:theme="@android:style/Theme.NoDisplay"/>
+
         <library android:name="android.ext.services"/>
     </application>
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 72647ab..58deb11 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -17,11 +17,17 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name">Android Services Library</string>
 
-    <string name="notification_assistant">Notification Assistant</string>
-    <string name="prompt_block_reason">Too many dismissals:views</string>
+    <string name="notification_assistant">Android Adaptive Notifications</string>
 
     <string name="autofill_field_classification_default_algorithm">EDIT_DISTANCE</string>
     <string-array name="autofill_field_classification_available_algorithms">
         <item>EDIT_DISTANCE</item>
+        <item>EXACT_MATCH</item>
     </string-array>
+
+    <!-- Action chip to copy a one time code to the user's clipboard [CHAR LIMIT=NONE]-->
+    <string name="copy_code_desc">Copy \u201c<xliff:g id="code" example="12345">%1$s</xliff:g>\u201c</string>
+    <!-- Toast to display when text is copied to the device clipboard [CHAR LIMIT=64]-->
+    <string name="code_copied_to_clipboard">Code copied</string>
+
 </resources>
diff --git a/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java b/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java
index 9ba7e09..e379db8 100644
--- a/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java
+++ b/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java
@@ -15,8 +15,6 @@
  */
 package android.ext.services.autofill;
 
-import static android.ext.services.autofill.EditDistanceScorer.DEFAULT_ALGORITHM;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Bundle;
@@ -26,27 +24,72 @@
 
 import com.android.internal.util.ArrayUtils;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 public class AutofillFieldClassificationServiceImpl extends AutofillFieldClassificationService {
 
     private static final String TAG = "AutofillFieldClassificationServiceImpl";
 
+    private static final String DEFAULT_ALGORITHM = REQUIRED_ALGORITHM_EDIT_DISTANCE;
+
     @Nullable
     @Override
-    public float[][] onGetScores(@Nullable String algorithmName,
-            @Nullable Bundle algorithmArgs, @NonNull List<AutofillValue> actualValues,
-            @NonNull List<String> userDataValues) {
+    /** @hide */
+    public float[][] onCalculateScores(@NonNull List<AutofillValue> actualValues,
+            @NonNull List<String> userDataValues, @NonNull List<String> categoryIds,
+            @Nullable String defaultAlgorithm, @Nullable Bundle defaultArgs,
+            @Nullable Map algorithms, @Nullable Map args) {
         if (ArrayUtils.isEmpty(actualValues) || ArrayUtils.isEmpty(userDataValues)) {
-            Log.w(TAG, "getScores(): empty currentvalues (" + actualValues + ") or userValues ("
-                    + userDataValues + ")");
+            Log.w(TAG, "calculateScores(): empty currentvalues (" + actualValues
+                    + ") or userValues (" + userDataValues + ")");
             return null;
         }
-        if (algorithmName != null && !algorithmName.equals(DEFAULT_ALGORITHM)) {
-            Log.w(TAG, "Ignoring invalid algorithm (" + algorithmName + ") and using "
-                    + DEFAULT_ALGORITHM + " instead");
-        }
 
-        return EditDistanceScorer.getScores(actualValues, userDataValues);
+        return calculateScores(actualValues, userDataValues, categoryIds, defaultAlgorithm,
+                defaultArgs, (HashMap<String, String>) algorithms,
+                (HashMap<String, Bundle>) args);
+    }
+
+    /** @hide */
+    public float[][] calculateScores(@NonNull List<AutofillValue> actualValues,
+            @NonNull List<String> userDataValues, @NonNull List<String> categoryIds,
+            @Nullable String defaultAlgorithm, @Nullable Bundle defaultArgs,
+            @Nullable HashMap<String, String> algorithms,
+            @Nullable HashMap<String, Bundle> args) {
+        final int actualValuesSize = actualValues.size();
+        final int userDataValuesSize = userDataValues.size();
+        final float[][] scores = new float[actualValuesSize][userDataValuesSize];
+
+        for (int j = 0; j < userDataValuesSize; j++) {
+            final String categoryId = categoryIds.get(j);
+            String algorithmName = defaultAlgorithm;
+            Bundle arg = defaultArgs;
+            if (algorithms != null && algorithms.containsKey(categoryId)) {
+                algorithmName = algorithms.get(categoryId);
+            }
+            if (args != null && args.containsKey(categoryId)) {
+                arg = args.get(categoryId);
+            }
+
+            if (algorithmName == null || (!algorithmName.equals(DEFAULT_ALGORITHM)
+                    && !algorithmName.equals(REQUIRED_ALGORITHM_EXACT_MATCH))) {
+                Log.w(TAG, "algorithmName is " + algorithmName + ", defaulting to "
+                        + DEFAULT_ALGORITHM);
+                algorithmName = DEFAULT_ALGORITHM;
+            }
+
+            for (int i = 0; i < actualValuesSize; i++) {
+                if (algorithmName.equals(DEFAULT_ALGORITHM)) {
+                    scores[i][j] = EditDistanceScorer.calculateScore(actualValues.get(i),
+                            userDataValues.get(j));
+                } else {
+                    scores[i][j] = ExactMatch.calculateScore(actualValues.get(i),
+                            userDataValues.get(j), arg);
+                }
+            }
+        }
+        return scores;
     }
 }
diff --git a/src/android/ext/services/autofill/EditDistanceScorer.java b/src/android/ext/services/autofill/EditDistanceScorer.java
index 302b160..5d14421 100644
--- a/src/android/ext/services/autofill/EditDistanceScorer.java
+++ b/src/android/ext/services/autofill/EditDistanceScorer.java
@@ -17,21 +17,15 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.util.Log;
 import android.view.autofill.AutofillValue;
 
 import com.android.internal.annotations.VisibleForTesting;
 
-import java.util.List;
-
 final class EditDistanceScorer {
 
     private static final String TAG = "EditDistanceScorer";
 
-    // TODO(b/70291841): STOPSHIP - set to false before launching
-    private static final boolean DEBUG = true;
-
-    static final String DEFAULT_ALGORITHM = "EDIT_DISTANCE";
+    private static final boolean DEBUG = false;
 
     /**
      * Gets the field classification score of 2 values based on the edit distance between them.
@@ -39,7 +33,8 @@
      * <p>The score is defined as: @(max_length - edit_distance) / max_length
      */
     @VisibleForTesting
-    static float getScore(@Nullable AutofillValue actualValue, @Nullable String userDataValue) {
+    static float calculateScore(@Nullable AutofillValue actualValue,
+            @Nullable String userDataValue) {
         if (actualValue == null || !actualValue.isText() || userDataValue == null) return 0;
 
         final String actualValueText = actualValue.getTextValue().toString();
@@ -87,7 +82,7 @@
      *     the edit distance is at least as big as the {@code max} parameter
      */
     // Note: copied verbatim from com.android.tools.lint.detector.api.LintUtils.java
-    private static int editDistance(@NonNull String s, @NonNull String t, int max) {
+    public static int editDistance(@NonNull String s, @NonNull String t, int max) {
         if (s.equals(t)) {
             return 0;
         }
@@ -123,26 +118,5 @@
 
         return d[m][n];
     }
-    /**
-     * Gets the scores in a batch.
-     */
-    static float[][] getScores(@NonNull List<AutofillValue> actualValues,
-            @NonNull List<String> userDataValues) {
-        final int actualValuesSize = actualValues.size();
-        final int userDataValuesSize = userDataValues.size();
-        if (DEBUG) {
-            Log.d(TAG, "getScores() will return a " + actualValuesSize + "x"
-                    + userDataValuesSize + " matrix for " + DEFAULT_ALGORITHM);
-        }
-        final float[][] scores = new float[actualValuesSize][userDataValuesSize];
-
-        for (int i = 0; i < actualValuesSize; i++) {
-            for (int j = 0; j < userDataValuesSize; j++) {
-                final float score = getScore(actualValues.get(i), userDataValues.get(j));
-                scores[i][j] = score;
-            }
-        }
-        return scores;
-    }
 
 }
diff --git a/src/android/ext/services/autofill/ExactMatch.java b/src/android/ext/services/autofill/ExactMatch.java
new file mode 100644
index 0000000..3e55c5c
--- /dev/null
+++ b/src/android/ext/services/autofill/ExactMatch.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 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 android.ext.services.autofill;
+
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.view.autofill.AutofillValue;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+final class ExactMatch {
+
+    /**
+     * Gets the field classification score of 2 values based on whether they are an exact match
+     *
+     * @return {@code 1.0} if the two values are an exact match, {@code 0.0} otherwise.
+     */
+    @VisibleForTesting
+    static float calculateScore(@Nullable AutofillValue actualValue,
+            @Nullable String userDataValue, @Nullable Bundle args) {
+        if (actualValue == null || !actualValue.isText() || userDataValue == null) return 0;
+
+        final String actualValueText = actualValue.getTextValue().toString();
+
+        final int suffixLength;
+        if (args != null) {
+            suffixLength = args.getInt("suffix", -1);
+
+            if (suffixLength < 0) {
+                throw new IllegalArgumentException("suffix argument is invalid");
+            }
+
+            final String actualValueSuffix;
+            if (suffixLength < actualValueText.length()) {
+                actualValueSuffix = actualValueText.substring(actualValueText.length()
+                        - suffixLength);
+            } else {
+                actualValueSuffix = actualValueText;
+            }
+
+            final String userDataValueSuffix;
+            if (suffixLength < userDataValue.length()) {
+                userDataValueSuffix = userDataValue.substring(userDataValue.length()
+                        - suffixLength);
+            } else {
+                userDataValueSuffix = userDataValue;
+            }
+
+            return (actualValueSuffix.equalsIgnoreCase(userDataValueSuffix)) ? 1 : 0;
+        } else {
+            return actualValueText.equalsIgnoreCase(userDataValue) ? 1 : 0;
+        }
+    }
+}
diff --git a/src/android/ext/services/notification/AgingHelper.java b/src/android/ext/services/notification/AgingHelper.java
new file mode 100644
index 0000000..31c9224
--- /dev/null
+++ b/src/android/ext/services/notification/AgingHelper.java
@@ -0,0 +1,172 @@
+/**
+ * Copyright (C) 2018 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 android.ext.services.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.ext.services.notification.NotificationCategorizer.Category;
+import android.net.Uri;
+import android.util.ArraySet;
+import android.util.Slog;
+
+import java.util.Set;
+
+public class AgingHelper {
+    private final static String TAG = "AgingHelper";
+    private final boolean DEBUG = false;
+
+    private static final String AGING_ACTION = AgingHelper.class.getSimpleName() + ".EVALUATE";
+    private static final int REQUEST_CODE_AGING = 1;
+    private static final String AGING_SCHEME = "aging";
+    private static final String EXTRA_KEY = "key";
+    private static final String EXTRA_CATEGORY = "category";
+
+    private static final int HOUR_MS = 1000 * 60 * 60;
+    private static final int TWO_HOURS_MS = 2 * HOUR_MS;
+
+    private Context mContext;
+    private NotificationCategorizer mNotificationCategorizer;
+    private AlarmManager mAm;
+    private Callback mCallback;
+
+    // The set of keys we've scheduled alarms for
+    private Set<String> mAging = new ArraySet<>();
+
+    public AgingHelper(Context context, NotificationCategorizer categorizer, Callback callback) {
+        mNotificationCategorizer = categorizer;
+        mContext = context;
+        mAm = mContext.getSystemService(AlarmManager.class);
+        mCallback = callback;
+
+        IntentFilter filter = new IntentFilter(AGING_ACTION);
+        filter.addDataScheme(AGING_SCHEME);
+        mContext.registerReceiver(mBroadcastReceiver, filter);
+    }
+
+    // NAS lifecycle methods
+
+    public void onNotificationSeen(NotificationEntry entry) {
+        // user has strong opinions about this notification. we can't down rank it, so don't bother.
+        if (entry.getChannel().hasUserSetImportance()) {
+            return;
+        }
+
+        @Category int category = mNotificationCategorizer.getCategory(entry);
+
+        // already very low
+        if (category == NotificationCategorizer.CATEGORY_MIN) {
+            return;
+        }
+
+        if (entry.hasSeen()) {
+            if (category == NotificationCategorizer.CATEGORY_ONGOING
+                    || category > NotificationCategorizer.CATEGORY_REMINDER) {
+                scheduleAging(entry.getSbn().getKey(), category, TWO_HOURS_MS);
+            } else {
+                scheduleAging(entry.getSbn().getKey(), category, HOUR_MS);
+            }
+
+            mAging.add(entry.getSbn().getKey());
+        }
+    }
+
+    public void onNotificationPosted(NotificationEntry entry) {
+        cancelAging(entry.getSbn().getKey());
+    }
+
+    public void onNotificationRemoved(String key) {
+        cancelAging(key);
+    }
+
+    public void onDestroy() {
+        mContext.unregisterReceiver(mBroadcastReceiver);
+    }
+
+    // Aging
+
+    private void scheduleAging(String key, @Category int category, long duration) {
+        if (mAging.contains(key)) {
+            // already scheduled. Don't reset aging just because the user saw the noti again.
+            return;
+        }
+        final PendingIntent pi = createPendingIntent(key, category);
+        long time = System.currentTimeMillis() + duration;
+        if (DEBUG) Slog.d(TAG, "Scheduling evaluate for " + key + " in ms: " + duration);
+        mAm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pi);
+    }
+
+    private void cancelAging(String key) {
+        final PendingIntent pi = createPendingIntent(key);
+        mAm.cancel(pi);
+        mAging.remove(key);
+    }
+
+    private Intent createBaseIntent(String key) {
+        return new Intent(AGING_ACTION)
+                .setData(new Uri.Builder().scheme(AGING_SCHEME).appendPath(key).build());
+    }
+
+    private Intent createAgingIntent(String key, @Category int category) {
+        Intent intent = createBaseIntent(key);
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
+                .putExtra(EXTRA_CATEGORY, category)
+                .putExtra(EXTRA_KEY, key);
+        return intent;
+    }
+
+    private PendingIntent createPendingIntent(String key, @Category int category) {
+        return PendingIntent.getBroadcast(mContext,
+                REQUEST_CODE_AGING,
+                createAgingIntent(key, category),
+                PendingIntent.FLAG_UPDATE_CURRENT);
+    }
+
+    private PendingIntent createPendingIntent(String key) {
+        return PendingIntent.getBroadcast(mContext,
+                REQUEST_CODE_AGING,
+                createBaseIntent(key),
+                PendingIntent.FLAG_UPDATE_CURRENT);
+    }
+
+    private void demote(String key, @Category int category) {
+        int newImportance = IMPORTANCE_MIN;
+        // TODO: Change "aged" importance based on category
+        mCallback.sendAdjustment(key, newImportance);
+    }
+
+    protected interface Callback {
+        void sendAdjustment(String key, int newImportance);
+    }
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (DEBUG) {
+                Slog.d(TAG, "Reposting notification");
+            }
+            if (AGING_ACTION.equals(intent.getAction())) {
+                demote(intent.getStringExtra(EXTRA_KEY), intent.getIntExtra(EXTRA_CATEGORY,
+                        NotificationCategorizer.CATEGORY_EVERYTHING_ELSE));
+            }
+        }
+    };
+}
diff --git a/src/android/ext/services/notification/Assistant.java b/src/android/ext/services/notification/Assistant.java
index f878822..d01878a 100644
--- a/src/android/ext/services/notification/Assistant.java
+++ b/src/android/ext/services/notification/Assistant.java
@@ -16,21 +16,25 @@
 
 package android.ext.services.notification;
 
+import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static android.service.notification.Adjustment.KEY_IMPORTANCE;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.app.ActivityThread;
 import android.app.INotificationManager;
-import android.content.ContentResolver;
+import android.app.Notification;
+import android.app.NotificationChannel;
 import android.content.Context;
-import android.database.ContentObserver;
-import android.ext.services.R;
-import android.net.Uri;
+import android.content.pm.IPackageManager;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Environment;
-import android.os.Handler;
+import android.os.UserHandle;
 import android.os.storage.StorageManager;
-import android.provider.Settings;
 import android.service.notification.Adjustment;
 import android.service.notification.NotificationAssistantService;
 import android.service.notification.NotificationStats;
@@ -41,6 +45,7 @@
 import android.util.Slog;
 import android.util.Xml;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.XmlUtils;
 
@@ -57,11 +62,15 @@
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 /**
  * Notification assistant that provides guidance on notification channel blocking
  */
+@SuppressLint("OverrideAbstract")
 public class Assistant extends NotificationAssistantService {
     private static final String TAG = "ExtAssistant";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -71,6 +80,7 @@
     private static final String ATT_KEY = "key";
     private static final int DB_VERSION = 1;
     private static final String ATTR_VERSION = "version";
+    private final ExecutorService mSingleThreadExecutor = Executors.newSingleThreadExecutor();
 
     private static final ArrayList<Integer> PREJUDICAL_DISMISSALS = new ArrayList<>();
     static {
@@ -78,17 +88,24 @@
         PREJUDICAL_DISMISSALS.add(REASON_LISTENER_CANCEL);
     }
 
-    private float mDismissToViewRatioLimit;
-    private int mStreakLimit;
+    private SmartActionsHelper mSmartActionsHelper;
+    private NotificationCategorizer mNotificationCategorizer;
 
     // key : impressions tracker
     // TODO: prune deleted channels and apps
-    final ArrayMap<String, ChannelImpressions> mkeyToImpressions = new ArrayMap<>();
-    // SBN key : channel id
-    ArrayMap<String, String> mLiveNotifications = new ArrayMap<>();
+    private final ArrayMap<String, ChannelImpressions> mkeyToImpressions = new ArrayMap<>();
+    // SBN key : entry
+    protected ArrayMap<String, NotificationEntry> mLiveNotifications = new ArrayMap<>();
 
     private Ranking mFakeRanking = null;
     private AtomicFile mFile = null;
+    private IPackageManager mPackageManager;
+
+    @VisibleForTesting
+    protected AssistantSettings.Factory mSettingsFactory = AssistantSettings.FACTORY;
+    @VisibleForTesting
+    protected AssistantSettings mSettings;
+    private SmsHelper mSmsHelper;
 
     public Assistant() {
     }
@@ -98,7 +115,23 @@
         super.onCreate();
         // Contexts are correctly hooked up by the creation step, which is required for the observer
         // to be hooked up/initialized.
-        new SettingsObserver(mHandler);
+        mPackageManager = ActivityThread.getPackageManager();
+        mSettings = mSettingsFactory.createAndRegister(mHandler,
+                getApplicationContext().getContentResolver(), getUserId(), this::updateThresholds);
+        mSmartActionsHelper = new SmartActionsHelper(getContext(), mSettings);
+        mNotificationCategorizer = new NotificationCategorizer();
+        mSmsHelper = new SmsHelper(this);
+        mSmsHelper.initialize();
+    }
+
+    @Override
+    public void onDestroy() {
+        // This null check is only for the unit tests as ServiceTestCase.tearDown calls onDestroy
+        // without having first called onCreate.
+        if (mSmsHelper != null) {
+            mSmsHelper.destroy();
+        }
+        super.onDestroy();
     }
 
     private void loadFile() {
@@ -145,7 +178,7 @@
         }
     }
 
-    private void saveFile() throws IOException {
+    private void saveFile() {
         AsyncTask.execute(() -> {
             final FileOutputStream stream;
             try {
@@ -186,26 +219,92 @@
 
     @Override
     public Adjustment onNotificationEnqueued(StatusBarNotification sbn) {
-        if (DEBUG) Log.i(TAG, "ENQUEUED " + sbn.getKey());
+        // we use the version with channel, so this is never called.
         return null;
     }
 
     @Override
+    public Adjustment onNotificationEnqueued(StatusBarNotification sbn,
+            NotificationChannel channel) {
+        if (DEBUG) Log.i(TAG, "ENQUEUED " + sbn.getKey() + " on " + channel.getId());
+        if (!isForCurrentUser(sbn)) {
+            return null;
+        }
+        mSingleThreadExecutor.submit(() -> {
+            NotificationEntry entry =
+                    new NotificationEntry(getContext(), mPackageManager, sbn, channel, mSmsHelper);
+            SmartActionsHelper.SmartSuggestions suggestions = mSmartActionsHelper.suggest(entry);
+            if (DEBUG) {
+                Log.d(TAG, String.format(
+                        "Creating Adjustment for %s, with %d actions, and %d replies.",
+                        sbn.getKey(), suggestions.actions.size(), suggestions.replies.size()));
+            }
+            Adjustment adjustment = createEnqueuedNotificationAdjustment(
+                    entry, suggestions.actions, suggestions.replies);
+            adjustNotification(adjustment);
+        });
+        return null;
+    }
+
+    /** A convenience helper for creating an adjustment for an SBN. */
+    @VisibleForTesting
+    @Nullable
+    Adjustment createEnqueuedNotificationAdjustment(
+            @NonNull NotificationEntry entry,
+            @NonNull ArrayList<Notification.Action> smartActions,
+            @NonNull ArrayList<CharSequence> smartReplies) {
+        Bundle signals = new Bundle();
+
+        if (!smartActions.isEmpty()) {
+            signals.putParcelableArrayList(Adjustment.KEY_CONTEXTUAL_ACTIONS, smartActions);
+        }
+        if (!smartReplies.isEmpty()) {
+            signals.putCharSequenceArrayList(Adjustment.KEY_TEXT_REPLIES, smartReplies);
+        }
+        if (mSettings.mNewInterruptionModel) {
+            if (mNotificationCategorizer.shouldSilence(entry)) {
+                final int importance = entry.getImportance() < IMPORTANCE_LOW
+                        ? entry.getImportance() : IMPORTANCE_LOW;
+                signals.putInt(KEY_IMPORTANCE, importance);
+            } else {
+                // Even if no change is made, send an identity adjustment for metric logging.
+                signals.putInt(KEY_IMPORTANCE, entry.getImportance());
+            }
+        }
+
+        return new Adjustment(
+                entry.getSbn().getPackageName(),
+                entry.getSbn().getKey(),
+                signals,
+                "",
+                entry.getSbn().getUserId());
+    }
+
+    @Override
     public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
         if (DEBUG) Log.i(TAG, "POSTED " + sbn.getKey());
         try {
+            if (!isForCurrentUser(sbn)) {
+                return;
+            }
             Ranking ranking = getRanking(sbn.getKey(), rankingMap);
             if (ranking != null && ranking.getChannel() != null) {
+                NotificationEntry entry = new NotificationEntry(getContext(), mPackageManager,
+                        sbn, ranking.getChannel(), mSmsHelper);
                 String key = getKey(
                         sbn.getPackageName(), sbn.getUserId(), ranking.getChannel().getId());
-                ChannelImpressions ci = mkeyToImpressions.getOrDefault(key,
-                        createChannelImpressionsWithThresholds());
-                if (ranking.getImportance() > IMPORTANCE_MIN && ci.shouldTriggerBlock()) {
+                boolean shouldTriggerBlock;
+                synchronized (mkeyToImpressions) {
+                    ChannelImpressions ci = mkeyToImpressions.getOrDefault(key,
+                            createChannelImpressionsWithThresholds());
+                    mkeyToImpressions.put(key, ci);
+                    shouldTriggerBlock = ci.shouldTriggerBlock();
+                }
+                if (ranking.getImportance() > IMPORTANCE_MIN && shouldTriggerBlock) {
                     adjustNotification(createNegativeAdjustment(
                             sbn.getPackageName(), sbn.getKey(), sbn.getUserId()));
                 }
-                mkeyToImpressions.put(key, ci);
-                mLiveNotifications.put(sbn.getKey(), ranking.getChannel().getId());
+                mLiveNotifications.put(sbn.getKey(), entry);
             }
         } catch (Throwable e) {
             Log.e(TAG, "Error occurred processing post", e);
@@ -216,13 +315,17 @@
     public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap,
             NotificationStats stats, int reason) {
         try {
+            if (!isForCurrentUser(sbn)) {
+                return;
+            }
+
             boolean updatedImpressions = false;
-            String channelId = mLiveNotifications.remove(sbn.getKey());
+            String channelId = mLiveNotifications.remove(sbn.getKey()).getChannel().getId();
             String key = getKey(sbn.getPackageName(), sbn.getUserId(), channelId);
             synchronized (mkeyToImpressions) {
                 ChannelImpressions ci = mkeyToImpressions.getOrDefault(key,
                         createChannelImpressionsWithThresholds());
-                if (stats.hasSeen()) {
+                if (stats != null && stats.hasSeen()) {
                     ci.incrementViews();
                     updatedImpressions = true;
                 }
@@ -249,7 +352,7 @@
                 saveFile();
             }
         } catch (Throwable e) {
-            Slog.e(TAG, "Error occurred processing removal", e);
+            Slog.e(TAG, "Error occurred processing removal of " + sbn, e);
         }
     }
 
@@ -259,6 +362,55 @@
     }
 
     @Override
+    public void onNotificationsSeen(List<String> keys) {
+    }
+
+    @Override
+    public void onNotificationExpansionChanged(@NonNull String key, boolean isUserAction,
+            boolean isExpanded) {
+        if (DEBUG) {
+            Log.d(TAG, "onNotificationExpansionChanged() called with: key = [" + key
+                    + "], isUserAction = [" + isUserAction + "], isExpanded = [" + isExpanded
+                    + "]");
+        }
+        NotificationEntry entry = mLiveNotifications.get(key);
+
+        if (entry != null) {
+            mSingleThreadExecutor.submit(
+                    () -> mSmartActionsHelper.onNotificationExpansionChanged(entry, isExpanded));
+        }
+    }
+
+    @Override
+    public void onNotificationDirectReplied(@NonNull String key) {
+        if (DEBUG) Log.i(TAG, "onNotificationDirectReplied " + key);
+        mSingleThreadExecutor.submit(() -> mSmartActionsHelper.onNotificationDirectReplied(key));
+    }
+
+    @Override
+    public void onSuggestedReplySent(@NonNull String key, @NonNull CharSequence reply,
+            @Source int source) {
+        if (DEBUG) {
+            Log.d(TAG, "onSuggestedReplySent() called with: key = [" + key + "], reply = [" + reply
+                    + "], source = [" + source + "]");
+        }
+        mSingleThreadExecutor.submit(
+                () -> mSmartActionsHelper.onSuggestedReplySent(key, reply, source));
+    }
+
+    @Override
+    public void onActionInvoked(@NonNull String key, @NonNull Notification.Action action,
+            @Source int source) {
+        if (DEBUG) {
+            Log.d(TAG,
+                    "onActionInvoked() called with: key = [" + key + "], action = [" + action.title
+                            + "], source = [" + source + "]");
+        }
+        mSingleThreadExecutor.submit(
+                () -> mSmartActionsHelper.onActionClicked(key, action, source));
+    }
+
+    @Override
     public void onListenerConnected() {
         if (DEBUG) Log.i(TAG, "CONNECTED");
         try {
@@ -275,6 +427,14 @@
         }
     }
 
+    @Override
+    public void onListenerDisconnected() {
+    }
+
+    private boolean isForCurrentUser(StatusBarNotification sbn) {
+        return sbn != null && sbn.getUserId() == UserHandle.myUserId();
+    }
+
     protected String getKey(String pkg, int userId, String channelId) {
         return pkg + "|" + userId + "|" + channelId;
     }
@@ -292,35 +452,45 @@
         if (DEBUG) Log.d(TAG, "User probably doesn't want " + key);
         Bundle signals = new Bundle();
         signals.putInt(Adjustment.KEY_USER_SENTIMENT, USER_SENTIMENT_NEGATIVE);
-        return new Adjustment(packageName, key,  signals,
-                getContext().getString(R.string.prompt_block_reason), user);
+        return new Adjustment(packageName, key,  signals, "", user);
     }
 
     // for testing
 
-    protected void setFile(AtomicFile file) {
+    @VisibleForTesting
+    public void setFile(AtomicFile file) {
         mFile = file;
     }
 
-    protected void setFakeRanking(Ranking ranking) {
+    @VisibleForTesting
+    public void setFakeRanking(Ranking ranking) {
         mFakeRanking = ranking;
     }
 
-    protected void setNoMan(INotificationManager noMan) {
+    @VisibleForTesting
+    public void setNoMan(INotificationManager noMan) {
         mNoMan = noMan;
     }
 
-    protected void setContext(Context context) {
+    @VisibleForTesting
+    public void setContext(Context context) {
         mSystemContext = context;
     }
 
-    protected ChannelImpressions getImpressions(String key) {
+    @VisibleForTesting
+    public void setPackageManager(IPackageManager pm) {
+        mPackageManager = pm;
+    }
+
+    @VisibleForTesting
+    public ChannelImpressions getImpressions(String key) {
         synchronized (mkeyToImpressions) {
             return mkeyToImpressions.get(key);
         }
     }
 
-    protected void insertImpressions(String key, ChannelImpressions ci) {
+    @VisibleForTesting
+    public void insertImpressions(String key, ChannelImpressions ci) {
         synchronized (mkeyToImpressions) {
             mkeyToImpressions.put(key, ci);
         }
@@ -328,55 +498,17 @@
 
     private ChannelImpressions createChannelImpressionsWithThresholds() {
         ChannelImpressions impressions = new ChannelImpressions();
-        impressions.updateThresholds(mDismissToViewRatioLimit, mStreakLimit);
+        impressions.updateThresholds(mSettings.mDismissToViewRatioLimit, mSettings.mStreakLimit);
         return impressions;
     }
 
-    /**
-     * Observer for updates on blocking helper threshold values.
-     */
-    private final class SettingsObserver extends ContentObserver {
-        private final Uri STREAK_LIMIT_URI =
-                Settings.Global.getUriFor(Settings.Global.BLOCKING_HELPER_STREAK_LIMIT);
-        private final Uri DISMISS_TO_VIEW_RATIO_LIMIT_URI =
-                Settings.Global.getUriFor(
-                        Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT);
-
-        public SettingsObserver(Handler handler) {
-            super(handler);
-            ContentResolver resolver = getApplicationContext().getContentResolver();
-            resolver.registerContentObserver(
-                    DISMISS_TO_VIEW_RATIO_LIMIT_URI, false, this, getUserId());
-            resolver.registerContentObserver(STREAK_LIMIT_URI, false, this, getUserId());
-
-            // Update all uris on creation.
-            update(null);
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            update(uri);
-        }
-
-        private void update(Uri uri) {
-            ContentResolver resolver = getApplicationContext().getContentResolver();
-            if (uri == null || DISMISS_TO_VIEW_RATIO_LIMIT_URI.equals(uri)) {
-                mDismissToViewRatioLimit = Settings.Global.getFloat(
-                        resolver, Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT,
-                        ChannelImpressions.DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT);
-            }
-            if (uri == null || STREAK_LIMIT_URI.equals(uri)) {
-                mStreakLimit = Settings.Global.getInt(
-                        resolver, Settings.Global.BLOCKING_HELPER_STREAK_LIMIT,
-                        ChannelImpressions.DEFAULT_STREAK_LIMIT);
-            }
-
-            // Update all existing channel impression objects with any new limits/thresholds.
-            synchronized (mkeyToImpressions) {
-                for (ChannelImpressions channelImpressions: mkeyToImpressions.values()) {
-                    channelImpressions.updateThresholds(mDismissToViewRatioLimit, mStreakLimit);
-                }
+    private void updateThresholds() {
+        // Update all existing channel impression objects with any new limits/thresholds.
+        synchronized (mkeyToImpressions) {
+            for (ChannelImpressions channelImpressions: mkeyToImpressions.values()) {
+                channelImpressions.updateThresholds(
+                        mSettings.mDismissToViewRatioLimit, mSettings.mStreakLimit);
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/android/ext/services/notification/AssistantSettings.java b/src/android/ext/services/notification/AssistantSettings.java
new file mode 100644
index 0000000..296db46
--- /dev/null
+++ b/src/android/ext/services/notification/AssistantSettings.java
@@ -0,0 +1,176 @@
+/**
+ * Copyright (C) 2018 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 android.ext.services.notification;
+
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.DeviceConfig;
+import android.provider.Settings;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+
+/**
+ * Observes the settings for {@link Assistant}.
+ */
+final class AssistantSettings extends ContentObserver {
+    private static final String LOG_TAG = "AssistantSettings";
+    public static Factory FACTORY = AssistantSettings::createAndRegister;
+    private static final boolean DEFAULT_GENERATE_REPLIES = true;
+    private static final boolean DEFAULT_GENERATE_ACTIONS = true;
+    private static final int DEFAULT_NEW_INTERRUPTION_MODEL_INT = 1;
+    private static final int DEFAULT_MAX_MESSAGES_TO_EXTRACT = 5;
+    @VisibleForTesting
+    static final int DEFAULT_MAX_SUGGESTIONS = 3;
+
+    private static final Uri STREAK_LIMIT_URI =
+            Settings.Global.getUriFor(Settings.Global.BLOCKING_HELPER_STREAK_LIMIT);
+    private static final Uri DISMISS_TO_VIEW_RATIO_LIMIT_URI =
+            Settings.Global.getUriFor(
+                    Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT);
+    private static final Uri NOTIFICATION_NEW_INTERRUPTION_MODEL_URI =
+            Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL);
+
+    private final ContentResolver mResolver;
+    private final int mUserId;
+
+    private final Handler mHandler;
+
+    @VisibleForTesting
+    protected final Runnable mOnUpdateRunnable;
+
+    // Actual configuration settings.
+    float mDismissToViewRatioLimit;
+    int mStreakLimit;
+    boolean mGenerateReplies = DEFAULT_GENERATE_REPLIES;
+    boolean mGenerateActions = DEFAULT_GENERATE_ACTIONS;
+    boolean mNewInterruptionModel;
+    int mMaxMessagesToExtract = DEFAULT_MAX_MESSAGES_TO_EXTRACT;
+    int mMaxSuggestions = DEFAULT_MAX_SUGGESTIONS;
+
+    private AssistantSettings(Handler handler, ContentResolver resolver, int userId,
+            Runnable onUpdateRunnable) {
+        super(handler);
+        mHandler = handler;
+        mResolver = resolver;
+        mUserId = userId;
+        mOnUpdateRunnable = onUpdateRunnable;
+    }
+
+    private static AssistantSettings createAndRegister(
+            Handler handler, ContentResolver resolver, int userId, Runnable onUpdateRunnable) {
+        AssistantSettings assistantSettings =
+                new AssistantSettings(handler, resolver, userId, onUpdateRunnable);
+        assistantSettings.register();
+        assistantSettings.registerDeviceConfigs();
+        return assistantSettings;
+    }
+
+    /**
+     * Creates an instance but doesn't register it as an observer.
+     */
+    @VisibleForTesting
+    protected static AssistantSettings createForTesting(
+            Handler handler, ContentResolver resolver, int userId, Runnable onUpdateRunnable) {
+        return new AssistantSettings(handler, resolver, userId, onUpdateRunnable);
+    }
+
+    private void register() {
+        mResolver.registerContentObserver(
+                DISMISS_TO_VIEW_RATIO_LIMIT_URI, false, this, mUserId);
+        mResolver.registerContentObserver(STREAK_LIMIT_URI, false, this, mUserId);
+
+        // Update all uris on creation.
+        update(null);
+    }
+
+    private void registerDeviceConfigs() {
+        DeviceConfig.addOnPropertiesChangedListener(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                this::postToHandler,
+                (properties) -> onDeviceConfigPropertiesChanged(properties.getNamespace()));
+
+        // Update the fields in this class from the current state of the device config.
+        updateFromDeviceConfigFlags();
+    }
+
+    private void postToHandler(Runnable r) {
+        this.mHandler.post(r);
+    }
+
+    @VisibleForTesting
+    void onDeviceConfigPropertiesChanged(String namespace) {
+        if (!DeviceConfig.NAMESPACE_SYSTEMUI.equals(namespace)) {
+            Log.e(LOG_TAG, "Received update from DeviceConfig for unrelated namespace: "
+                    + namespace);
+            return;
+        }
+
+        updateFromDeviceConfigFlags();
+    }
+
+    private void updateFromDeviceConfigFlags() {
+        mGenerateReplies = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES, DEFAULT_GENERATE_REPLIES);
+
+        mGenerateActions = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS, DEFAULT_GENERATE_ACTIONS);
+
+        mMaxMessagesToExtract = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_MAX_MESSAGES_TO_EXTRACT,
+                DEFAULT_MAX_MESSAGES_TO_EXTRACT);
+
+        mMaxSuggestions = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_MAX_SUGGESTIONS, DEFAULT_MAX_SUGGESTIONS);
+
+        mOnUpdateRunnable.run();
+    }
+
+    @Override
+    public void onChange(boolean selfChange, Uri uri) {
+        update(uri);
+    }
+
+    private void update(Uri uri) {
+        if (uri == null || DISMISS_TO_VIEW_RATIO_LIMIT_URI.equals(uri)) {
+            mDismissToViewRatioLimit = Settings.Global.getFloat(
+                    mResolver, Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT,
+                    ChannelImpressions.DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT);
+        }
+        if (uri == null || STREAK_LIMIT_URI.equals(uri)) {
+            mStreakLimit = Settings.Global.getInt(
+                    mResolver, Settings.Global.BLOCKING_HELPER_STREAK_LIMIT,
+                    ChannelImpressions.DEFAULT_STREAK_LIMIT);
+        }
+        if (uri == null || NOTIFICATION_NEW_INTERRUPTION_MODEL_URI.equals(uri)) {
+            int mNewInterruptionModelInt = Settings.Secure.getInt(
+                    mResolver, Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL,
+                    DEFAULT_NEW_INTERRUPTION_MODEL_INT);
+            mNewInterruptionModel = mNewInterruptionModelInt == 1;
+        }
+
+        mOnUpdateRunnable.run();
+    }
+
+    public interface Factory {
+        AssistantSettings createAndRegister(Handler handler, ContentResolver resolver, int userId,
+                Runnable onUpdateRunnable);
+    }
+}
diff --git a/src/android/ext/services/notification/ChannelImpressions.java b/src/android/ext/services/notification/ChannelImpressions.java
index 29ee920..ca3daad 100644
--- a/src/android/ext/services/notification/ChannelImpressions.java
+++ b/src/android/ext/services/notification/ChannelImpressions.java
@@ -37,6 +37,8 @@
     static final String ATT_DISMISSALS = "dismisses";
     static final String ATT_VIEWS = "views";
     static final String ATT_STREAK = "streak";
+    static final String ATT_SENT = "sent";
+    static final String ATT_INTERRUPTIVE = "interruptive";
 
     private int mDismissals = 0;
     private int mViews = 0;
diff --git a/src/android/ext/services/notification/CopyCodeActivity.java b/src/android/ext/services/notification/CopyCodeActivity.java
new file mode 100644
index 0000000..6708d4d
--- /dev/null
+++ b/src/android/ext/services/notification/CopyCodeActivity.java
@@ -0,0 +1,54 @@
+/*
+ * 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 android.ext.services.notification;
+
+import android.app.Activity;
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Intent;
+import android.ext.services.R;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.widget.Toast;
+
+/**
+ * An activity that copies text in the Bundle.
+ */
+public class CopyCodeActivity extends Activity {
+    private static final String TAG = "CopyCodeActivity";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        handleIntent();
+        finish();
+    }
+
+    private void handleIntent() {
+        String code = getIntent().getStringExtra(Intent.EXTRA_TEXT);
+        if (TextUtils.isEmpty(code)) {
+            Log.w(TAG, "handleIntent: empty code");
+            return;
+        }
+        ClipboardManager clipboardManager = getSystemService(ClipboardManager.class);
+        ClipData clipData = ClipData.newPlainText(null, code);
+        clipboardManager.setPrimaryClip(clipData);
+        Toast.makeText(getApplicationContext(), R.string.code_copied_to_clipboard,
+                Toast.LENGTH_SHORT).show();
+    }
+}
diff --git a/src/android/ext/services/notification/EntityTypeCounter.java b/src/android/ext/services/notification/EntityTypeCounter.java
new file mode 100644
index 0000000..50cb0ab
--- /dev/null
+++ b/src/android/ext/services/notification/EntityTypeCounter.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright (C) 2018 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 android.ext.services.notification;
+
+import android.annotation.NonNull;
+import android.util.ArrayMap;
+import android.view.textclassifier.TextClassifier;
+import android.view.textclassifier.TextLinks;
+
+/**
+ * Counts the entity types for smart actions. Some entity types are considered the same
+ * type, like {@link TextClassifier#TYPE_DATE} and {@link TextClassifier#TYPE_DATE_TIME}.
+ */
+class EntityTypeCounter {
+
+    private static final ArrayMap<String, String> ENTITY_TYPE_MAPPING = new ArrayMap<>();
+
+    static {
+        ENTITY_TYPE_MAPPING.put(TextClassifier.TYPE_DATE_TIME, TextClassifier.TYPE_DATE);
+    }
+
+    private final ArrayMap<String, Integer> mEntityTypeCount = new ArrayMap<>();
+
+
+    void increment(@NonNull String entityType) {
+        entityType = convertToBaseEntityType(entityType);
+        if (mEntityTypeCount.containsKey(entityType)) {
+            mEntityTypeCount.put(entityType, mEntityTypeCount.get(entityType) + 1);
+        } else {
+            mEntityTypeCount.put(entityType, 1);
+        }
+    }
+
+    int getCount(@NonNull String entityType) {
+        entityType = convertToBaseEntityType(entityType);
+        return mEntityTypeCount.getOrDefault(entityType, 0);
+    }
+
+    @NonNull
+    private String convertToBaseEntityType(@NonNull String entityType) {
+        return ENTITY_TYPE_MAPPING.getOrDefault(entityType, entityType);
+    }
+
+    /**
+     * Given the links extracted from a piece of text, returns the frequency of each entity
+     * type.
+     */
+    @NonNull
+    static EntityTypeCounter fromTextLinks(@NonNull TextLinks links) {
+        EntityTypeCounter counter = new EntityTypeCounter();
+        for (TextLinks.TextLink link : links.getLinks()) {
+            if (link.getEntityCount() == 0) {
+                continue;
+            }
+            String entityType = link.getEntity(0);
+            counter.increment(entityType);
+        }
+        return counter;
+    }
+}
diff --git a/src/android/ext/services/notification/NotificationCategorizer.java b/src/android/ext/services/notification/NotificationCategorizer.java
new file mode 100644
index 0000000..f95891c
--- /dev/null
+++ b/src/android/ext/services/notification/NotificationCategorizer.java
@@ -0,0 +1,109 @@
+/**
+ * Copyright (C) 2018 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 android.ext.services.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+
+import android.annotation.IntDef;
+import android.app.Notification;
+import android.media.AudioAttributes;
+import android.os.Process;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Default categorizer for incoming notifications; used to determine what notifications
+ * should be silenced.
+ */
+// TODO: stop using @hide methods
+public class NotificationCategorizer {
+
+    protected static final int CATEGORY_MIN = -3;
+    protected static final int CATEGORY_EVERYTHING_ELSE = -2;
+    protected static final int CATEGORY_ONGOING = -1;
+    protected static final int CATEGORY_SYSTEM_LOW = 0;
+    protected static final int CATEGORY_EVENT = 1;
+    protected static final int CATEGORY_REMINDER = 2;
+    protected static final int CATEGORY_SYSTEM = 3;
+    protected static final int CATEGORY_PEOPLE = 4;
+    protected static final int CATEGORY_ALARM = 5;
+    protected static final int CATEGORY_CALL = 6;
+    protected static final int CATEGORY_HIGH = 7;
+
+    /** @hide */
+    @IntDef(prefix = { "CATEGORY_" }, value = {
+            CATEGORY_MIN, CATEGORY_EVERYTHING_ELSE, CATEGORY_ONGOING, CATEGORY_CALL,
+            CATEGORY_SYSTEM_LOW, CATEGORY_EVENT, CATEGORY_REMINDER, CATEGORY_SYSTEM,
+            CATEGORY_PEOPLE, CATEGORY_ALARM, CATEGORY_HIGH
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Category {}
+
+    public boolean shouldSilence(NotificationEntry entry) {
+        return shouldSilence(getCategory(entry));
+    }
+
+    @VisibleForTesting
+    boolean shouldSilence(int category) {
+        return category < CATEGORY_EVENT;
+    }
+
+    public int getCategory(NotificationEntry entry) {
+        if (entry.getChannel() == null) {
+            return CATEGORY_EVERYTHING_ELSE;
+        }
+        if (entry.getChannel().getImportance() == IMPORTANCE_MIN) {
+            return CATEGORY_MIN;
+        }
+        if (entry.isCategory(Notification.CATEGORY_REMINDER)) {
+            return CATEGORY_REMINDER;
+        }
+        if (entry.isCategory(Notification.CATEGORY_EVENT)) {
+            return CATEGORY_EVENT;
+        }
+        if (entry.isCategory(Notification.CATEGORY_ALARM)
+                || entry.isAudioAttributesUsage(AudioAttributes.USAGE_ALARM)) {
+            return CATEGORY_ALARM;
+        }
+        // TODO: check for default phone app
+        if (entry.isCategory(Notification.CATEGORY_CALL)) {
+            return CATEGORY_CALL;
+        }
+        if (entry.involvesPeople()) {
+            return CATEGORY_PEOPLE;
+        }
+        // TODO: is from signature app
+        if (entry.getSbn().getUid() < Process.FIRST_APPLICATION_UID) {
+            if (entry.getImportance() >= IMPORTANCE_DEFAULT) {
+                return CATEGORY_SYSTEM;
+            } else {
+                return CATEGORY_SYSTEM_LOW;
+            }
+        }
+        if (entry.getChannel().getImportance() == IMPORTANCE_HIGH) {
+            return CATEGORY_HIGH;
+        }
+        if (entry.isOngoing()) {
+            return CATEGORY_ONGOING;
+        }
+        return CATEGORY_EVERYTHING_ELSE;
+    }
+}
diff --git a/src/android/ext/services/notification/NotificationEntry.java b/src/android/ext/services/notification/NotificationEntry.java
new file mode 100644
index 0000000..1ffbac9
--- /dev/null
+++ b/src/android/ext/services/notification/NotificationEntry.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2018 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 android.ext.services.notification;
+
+import static android.app.Notification.CATEGORY_MESSAGE;
+import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.Person;
+import android.app.RemoteInput;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Icon;
+import android.media.AudioAttributes;
+import android.media.AudioSystem;
+import android.os.Build;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.service.notification.StatusBarNotification;
+import android.util.Log;
+import android.util.SparseArray;
+
+import java.util.ArrayList;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Holds data about notifications.
+ */
+public class NotificationEntry {
+    static final String TAG = "NotificationEntry";
+
+    // Copied from hidden definitions in Notification.TvExtender
+    private static final String EXTRA_TV_EXTENDER = "android.tv.EXTENSIONS";
+
+    private final Context mContext;
+    private final StatusBarNotification mSbn;
+    private final IPackageManager mPackageManager;
+    private int mTargetSdkVersion = Build.VERSION_CODES.N_MR1;
+    private final boolean mPreChannelsNotification;
+    private final AudioAttributes mAttributes;
+    private final NotificationChannel mChannel;
+    private final int mImportance;
+    private boolean mSeen;
+    private boolean mIsShowActionEventLogged;
+    private final SmsHelper mSmsHelper;
+
+    private final Object mLock = new Object();
+
+    public NotificationEntry(Context applicationContext, IPackageManager packageManager,
+            StatusBarNotification sbn, NotificationChannel channel, SmsHelper smsHelper) {
+        mContext = applicationContext;
+        mSbn = cloneStatusBarNotificationLight(sbn);
+        mChannel = channel;
+        mPackageManager = packageManager;
+        mPreChannelsNotification = isPreChannelsNotification();
+        mAttributes = calculateAudioAttributes();
+        mImportance = calculateInitialImportance();
+        mSmsHelper = smsHelper;
+    }
+
+    /** Adapted from {@code Notification.lightenPayload}. */
+    @SuppressWarnings("nullness")
+    private static void lightenNotificationPayload(Notification notification) {
+        notification.tickerView = null;
+        notification.contentView = null;
+        notification.bigContentView = null;
+        notification.headsUpContentView = null;
+        notification.largeIcon = null;
+        if (notification.extras != null && !notification.extras.isEmpty()) {
+            final Set<String> keyset = notification.extras.keySet();
+            final int keysetSize = keyset.size();
+            final String[] keys = keyset.toArray(new String[keysetSize]);
+            for (int i = 0; i < keysetSize; i++) {
+                final String key = keys[i];
+                if (EXTRA_TV_EXTENDER.equals(key)
+                        || Notification.EXTRA_MESSAGES.equals(key)
+                        || Notification.EXTRA_MESSAGING_PERSON.equals(key)
+                        || Notification.EXTRA_PEOPLE_LIST.equals(key)) {
+                    continue;
+                }
+                final Object obj = notification.extras.get(key);
+                if (obj != null
+                        && (obj instanceof Parcelable
+                        || obj instanceof Parcelable[]
+                        || obj instanceof SparseArray
+                        || obj instanceof ArrayList)) {
+                    notification.extras.remove(key);
+                }
+            }
+        }
+    }
+
+    /** An interpretation of {@code Notification.cloneInto} with heavy=false. */
+    private Notification cloneNotificationLight(Notification notification) {
+        // We can't just use clone() here because the only way to remove the icons is with the
+        // builder, which we can only create with a Context.
+        Notification lightNotification =
+                Notification.Builder.recoverBuilder(mContext, notification)
+                        .setSmallIcon(0)
+                        .setLargeIcon((Icon) null)
+                        .build();
+        lightenNotificationPayload(lightNotification);
+        return lightNotification;
+    }
+
+    /** Adapted from {@code StatusBarNotification.cloneLight}. */
+    public StatusBarNotification cloneStatusBarNotificationLight(StatusBarNotification sbn) {
+        return new StatusBarNotification(
+                sbn.getPackageName(),
+                sbn.getOpPkg(),
+                sbn.getId(),
+                sbn.getTag(),
+                sbn.getUid(),
+                /*initialPid=*/ 0,
+                /*score=*/ 0,
+                cloneNotificationLight(sbn.getNotification()),
+                sbn.getUser(),
+                sbn.getPostTime());
+    }
+
+    private boolean isPreChannelsNotification() {
+        try {
+            ApplicationInfo info = mPackageManager.getApplicationInfo(
+                    mSbn.getPackageName(), PackageManager.MATCH_ALL,
+                    mSbn.getUserId());
+            if (info != null) {
+                mTargetSdkVersion = info.targetSdkVersion;
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Couldn't look up " + mSbn.getPackageName());
+        }
+        if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(getChannel().getId())) {
+            if (mTargetSdkVersion < Build.VERSION_CODES.O) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private AudioAttributes calculateAudioAttributes() {
+        final Notification n = getNotification();
+        AudioAttributes attributes = getChannel().getAudioAttributes();
+        if (attributes == null) {
+            attributes = Notification.AUDIO_ATTRIBUTES_DEFAULT;
+        }
+
+        if (mPreChannelsNotification
+                && (getChannel().getUserLockedFields()
+                & NotificationChannel.USER_LOCKED_SOUND) == 0) {
+            if (n.audioAttributes != null) {
+                // prefer audio attributes to stream type
+                attributes = n.audioAttributes;
+            } else if (n.audioStreamType >= 0
+                    && n.audioStreamType < AudioSystem.getNumStreamTypes()) {
+                // the stream type is valid, use it
+                attributes = new AudioAttributes.Builder()
+                        .setInternalLegacyStreamType(n.audioStreamType)
+                        .build();
+            } else if (n.audioStreamType != AudioSystem.STREAM_DEFAULT) {
+                Log.w(TAG, String.format("Invalid stream type: %d", n.audioStreamType));
+            }
+        }
+        return attributes;
+    }
+
+    private int calculateInitialImportance() {
+        final Notification n = getNotification();
+        int importance = getChannel().getImportance();
+        int requestedImportance = IMPORTANCE_DEFAULT;
+
+        // Migrate notification flags to scores
+        if ((n.flags & Notification.FLAG_HIGH_PRIORITY) != 0) {
+            n.priority = Notification.PRIORITY_MAX;
+        }
+
+        n.priority = clamp(n.priority, Notification.PRIORITY_MIN,
+                Notification.PRIORITY_MAX);
+        switch (n.priority) {
+            case Notification.PRIORITY_MIN:
+                requestedImportance = IMPORTANCE_MIN;
+                break;
+            case Notification.PRIORITY_LOW:
+                requestedImportance = IMPORTANCE_LOW;
+                break;
+            case Notification.PRIORITY_DEFAULT:
+                requestedImportance = IMPORTANCE_DEFAULT;
+                break;
+            case Notification.PRIORITY_HIGH:
+            case Notification.PRIORITY_MAX:
+                requestedImportance = IMPORTANCE_HIGH;
+                break;
+        }
+
+        if (mPreChannelsNotification
+                && (importance == IMPORTANCE_UNSPECIFIED
+                || (getChannel().getUserLockedFields()
+                & USER_LOCKED_IMPORTANCE) == 0)) {
+            if (n.fullScreenIntent != null) {
+                requestedImportance = IMPORTANCE_HIGH;
+            }
+            importance = requestedImportance;
+        }
+
+        return importance;
+    }
+
+    public boolean isCategory(String category) {
+        return Objects.equals(getNotification().category, category);
+    }
+
+    /**
+     * Similar to {@link #isCategory(String)}, but checking the public version of the notification,
+     * if available.
+     */
+    public boolean isPublicVersionCategory(String category) {
+        Notification publicVersion = getNotification().publicVersion;
+        if (publicVersion == null) {
+            return false;
+        }
+        return Objects.equals(publicVersion.category, category);
+    }
+
+    public boolean isAudioAttributesUsage(int usage) {
+        return mAttributes != null && mAttributes.getUsage() == usage;
+    }
+
+    private boolean hasPerson() {
+        // TODO: cache favorite and recent contacts to check contact affinity
+        ArrayList<Person> people = getNotification().extras.getParcelableArrayList(
+                Notification.EXTRA_PEOPLE_LIST);
+        return people != null && !people.isEmpty();
+    }
+
+    protected boolean hasStyle(Class targetStyle) {
+        Class<? extends Notification.Style> style = getNotification().getNotificationStyle();
+        return targetStyle.equals(style);
+    }
+
+    protected boolean isOngoing() {
+        return (getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
+    }
+
+    protected boolean involvesPeople() {
+        return isMessaging()
+                || hasStyle(Notification.InboxStyle.class)
+                || hasPerson()
+                || isDefaultSmsApp();
+    }
+
+    private boolean isDefaultSmsApp() {
+        ComponentName defaultSmsApp = mSmsHelper.getDefaultSmsApplication();
+        if (defaultSmsApp == null) {
+            return false;
+        }
+        return mSbn.getPackageName().equals(defaultSmsApp.getPackageName());
+    }
+
+    protected boolean isMessaging() {
+        return isCategory(CATEGORY_MESSAGE)
+                || isPublicVersionCategory(CATEGORY_MESSAGE)
+                || hasStyle(Notification.MessagingStyle.class);
+    }
+
+    public boolean hasInlineReply() {
+        Notification.Action[] actions = getNotification().actions;
+        if (actions == null) {
+            return false;
+        }
+        for (Notification.Action action : actions) {
+            RemoteInput[] remoteInputs = action.getRemoteInputs();
+            if (remoteInputs == null) {
+                continue;
+            }
+            for (RemoteInput remoteInput : remoteInputs) {
+                if (remoteInput.getAllowFreeFormInput()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public void setSeen() {
+        synchronized (mLock) {
+            mSeen = true;
+        }
+    }
+
+    public void setShowActionEventLogged() {
+        synchronized (mLock) {
+            mIsShowActionEventLogged = true;
+        }
+    }
+
+    public boolean hasSeen() {
+        synchronized (mLock) {
+            return mSeen;
+        }
+    }
+
+    public boolean isShowActionEventLogged() {
+        synchronized (mLock) {
+            return mIsShowActionEventLogged;
+        }
+    }
+
+    public StatusBarNotification getSbn() {
+        return mSbn;
+    }
+
+    public Notification getNotification() {
+        return getSbn().getNotification();
+    }
+
+    public NotificationChannel getChannel() {
+        return mChannel;
+    }
+
+    public int getImportance() {
+        return mImportance;
+    }
+
+    private int clamp(int x, int low, int high) {
+        return (x < low) ? low : ((x > high) ? high : x);
+    }
+}
diff --git a/src/android/ext/services/notification/SmartActionsHelper.java b/src/android/ext/services/notification/SmartActionsHelper.java
new file mode 100644
index 0000000..93c522e
--- /dev/null
+++ b/src/android/ext/services/notification/SmartActionsHelper.java
@@ -0,0 +1,502 @@
+/**
+ * Copyright (C) 2018 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 android.ext.services.notification;
+
+import android.annotation.Nullable;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.app.Person;
+import android.app.RemoteAction;
+import android.app.RemoteInput;
+import android.content.Context;
+import android.content.Intent;
+import android.ext.services.R;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.os.Process;
+import android.service.notification.NotificationAssistantService;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.LruCache;
+import android.util.Pair;
+import android.view.textclassifier.ConversationAction;
+import android.view.textclassifier.ConversationActions;
+import android.view.textclassifier.TextClassificationContext;
+import android.view.textclassifier.TextClassificationManager;
+import android.view.textclassifier.TextClassifier;
+import android.view.textclassifier.TextClassifierEvent;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Generates suggestions from incoming notifications.
+ *
+ * Methods in this class should be called in a single worker thread.
+ */
+public class SmartActionsHelper {
+    static final String ENTITIES_EXTRAS = "entities-extras";
+    static final String KEY_ACTION_TYPE = "action_type";
+    static final String KEY_ACTION_SCORE = "action_score";
+    static final String KEY_TEXT = "text";
+    // If a notification has any of these flags set, it's inelgibile for actions being added.
+    private static final int FLAG_MASK_INELGIBILE_FOR_ACTIONS =
+            Notification.FLAG_ONGOING_EVENT
+                    | Notification.FLAG_FOREGROUND_SERVICE
+                    | Notification.FLAG_GROUP_SUMMARY
+                    | Notification.FLAG_NO_CLEAR;
+    private static final int MAX_RESULT_ID_TO_CACHE = 20;
+
+    private static final List<String> HINTS =
+            Collections.singletonList(ConversationActions.Request.HINT_FOR_NOTIFICATION);
+    private static final ConversationActions EMPTY_CONVERSATION_ACTIONS =
+            new ConversationActions(Collections.emptyList(), null);
+
+    private Context mContext;
+    private TextClassificationManager mTextClassificationManager;
+    private AssistantSettings mSettings;
+    private LruCache<String, Session> mSessionCache = new LruCache<>(MAX_RESULT_ID_TO_CACHE);
+
+    SmartActionsHelper(Context context, AssistantSettings settings) {
+        mContext = context;
+        mTextClassificationManager = mContext.getSystemService(TextClassificationManager.class);
+        mSettings = settings;
+    }
+
+    SmartSuggestions suggest(NotificationEntry entry) {
+        // Whenever suggest() is called on a notification, its previous session is ended.
+        mSessionCache.remove(entry.getSbn().getKey());
+
+        boolean eligibleForReplyAdjustment =
+                mSettings.mGenerateReplies && isEligibleForReplyAdjustment(entry);
+        boolean eligibleForActionAdjustment =
+                mSettings.mGenerateActions && isEligibleForActionAdjustment(entry);
+
+        ConversationActions conversationActionsResult =
+                suggestConversationActions(
+                        entry,
+                        eligibleForReplyAdjustment,
+                        eligibleForActionAdjustment);
+
+        String resultId = conversationActionsResult.getId();
+        List<ConversationAction> conversationActions =
+                conversationActionsResult.getConversationActions();
+
+        ArrayList<CharSequence> replies = new ArrayList<>();
+        Map<CharSequence, Float> repliesScore = new ArrayMap<>();
+        for (ConversationAction conversationAction : conversationActions) {
+            CharSequence textReply = conversationAction.getTextReply();
+            if (TextUtils.isEmpty(textReply)) {
+                continue;
+            }
+            replies.add(textReply);
+            repliesScore.put(textReply, conversationAction.getConfidenceScore());
+        }
+
+        ArrayList<Notification.Action> actions = new ArrayList<>();
+        for (ConversationAction conversationAction : conversationActions) {
+            if (!TextUtils.isEmpty(conversationAction.getTextReply())) {
+                continue;
+            }
+            Notification.Action notificationAction;
+            if (conversationAction.getAction() == null) {
+                notificationAction =
+                        createNotificationActionWithoutRemoteAction(conversationAction);
+            } else {
+                notificationAction = createNotificationActionFromRemoteAction(
+                        conversationAction.getAction(),
+                        conversationAction.getType(),
+                        conversationAction.getConfidenceScore());
+            }
+            if (notificationAction != null) {
+                actions.add(notificationAction);
+            }
+        }
+
+        // Start a new session for logging if necessary.
+        if (!TextUtils.isEmpty(resultId)
+                && !conversationActions.isEmpty()
+                && suggestionsMightBeUsedInNotification(
+                entry, !actions.isEmpty(), !replies.isEmpty())) {
+            mSessionCache.put(entry.getSbn().getKey(), new Session(resultId, repliesScore));
+        }
+
+        return new SmartSuggestions(replies, actions);
+    }
+
+    /**
+     * Creates notification action from ConversationAction that does not come up a RemoteAction.
+     * It could happen because we don't have common intents for some actions, like copying text.
+     */
+    @Nullable
+    private Notification.Action createNotificationActionWithoutRemoteAction(
+            ConversationAction conversationAction) {
+        if (ConversationAction.TYPE_COPY.equals(conversationAction.getType())) {
+            return createCopyCodeAction(conversationAction);
+        }
+        return null;
+    }
+
+    @Nullable
+    private Notification.Action createCopyCodeAction(ConversationAction conversationAction) {
+        Bundle extras = conversationAction.getExtras();
+        if (extras == null) {
+            return null;
+        }
+        Bundle entitiesExtas = extras.getParcelable(ENTITIES_EXTRAS);
+        if (entitiesExtas == null) {
+            return null;
+        }
+        String code = entitiesExtas.getString(KEY_TEXT);
+        if (TextUtils.isEmpty(code)) {
+            return null;
+        }
+        String contentDescription = mContext.getString(R.string.copy_code_desc, code);
+        Intent intent = new Intent(mContext, CopyCodeActivity.class);
+        intent.putExtra(Intent.EXTRA_TEXT, code);
+
+        RemoteAction remoteAction = new RemoteAction(Icon.createWithResource(
+                mContext.getResources(),
+                com.android.internal.R.drawable.ic_menu_copy_material),
+                code,
+                contentDescription,
+                PendingIntent.getActivity(
+                        mContext,
+                        code.hashCode(),
+                        intent,
+                        PendingIntent.FLAG_UPDATE_CURRENT
+                ));
+
+        return createNotificationActionFromRemoteAction(
+                remoteAction,
+                ConversationAction.TYPE_COPY,
+                conversationAction.getConfidenceScore());
+    }
+
+    /**
+     * Returns whether the suggestion might be used in the notifications in SysUI.
+     * <p>
+     * Currently, NAS has no idea if suggestions will actually be used in the notification, and thus
+     * this function tries to make a heuristic. This function tries to optimize the precision,
+     * that means when it is unsure, it will return false. The objective is to avoid false positive,
+     * which could pollute the log and CTR as we are logging click rate of suggestions that could
+     * be never visible to users. On the other hand, it is fine to have false negative because
+     * it would be just like sampling.
+     */
+    private boolean suggestionsMightBeUsedInNotification(
+            NotificationEntry notificationEntry, boolean hasSmartAction, boolean hasSmartReply) {
+        Notification notification = notificationEntry.getNotification();
+        boolean hasAppGeneratedContextualActions = !notification.getContextualActions().isEmpty();
+
+        Pair<RemoteInput, Notification.Action> freeformRemoteInputAndAction =
+                notification.findRemoteInputActionPair(/* requiresFreeform */ true);
+        boolean hasAppGeneratedReplies = false;
+        boolean allowGeneratedReplies = false;
+        if (freeformRemoteInputAndAction != null) {
+            RemoteInput freeformRemoteInput = freeformRemoteInputAndAction.first;
+            Notification.Action actionWithFreeformRemoteInput = freeformRemoteInputAndAction.second;
+            hasAppGeneratedReplies = !ArrayUtils.isEmpty(freeformRemoteInput.getChoices());
+            allowGeneratedReplies = actionWithFreeformRemoteInput.getAllowGeneratedReplies();
+        }
+
+        if (hasAppGeneratedReplies || hasAppGeneratedContextualActions) {
+            return false;
+        }
+        return hasSmartAction && notification.getAllowSystemGeneratedContextualActions()
+                || hasSmartReply && allowGeneratedReplies;
+    }
+
+    private void reportActionsGenerated(
+            String resultId, List<ConversationAction> conversationActions) {
+        if (TextUtils.isEmpty(resultId)) {
+            return;
+        }
+        TextClassifierEvent textClassifierEvent =
+                createTextClassifierEventBuilder(
+                        TextClassifierEvent.TYPE_ACTIONS_GENERATED, resultId)
+                        .setEntityTypes(conversationActions.stream()
+                                .map(ConversationAction::getType)
+                                .toArray(String[]::new))
+                        .build();
+        getTextClassifier().onTextClassifierEvent(textClassifierEvent);
+    }
+
+    /**
+     * Adds action adjustments based on the notification contents.
+     */
+    private ConversationActions suggestConversationActions(
+            NotificationEntry entry,
+            boolean includeReplies,
+            boolean includeActions) {
+        if (!includeReplies && !includeActions) {
+            return EMPTY_CONVERSATION_ACTIONS;
+        }
+        List<ConversationActions.Message> messages = extractMessages(entry.getNotification());
+        if (messages.isEmpty()) {
+            return EMPTY_CONVERSATION_ACTIONS;
+        }
+        // Do not generate smart actions if the last message is from the local user.
+        ConversationActions.Message lastMessage = messages.get(messages.size() - 1);
+        if (arePersonsEqual(
+                ConversationActions.Message.PERSON_USER_SELF, lastMessage.getAuthor())) {
+            return EMPTY_CONVERSATION_ACTIONS;
+        }
+
+        TextClassifier.EntityConfig.Builder typeConfigBuilder =
+                new TextClassifier.EntityConfig.Builder();
+        if (!includeReplies) {
+            typeConfigBuilder.setExcludedTypes(
+                    Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY));
+        } else if (!includeActions) {
+            typeConfigBuilder
+                    .setIncludedTypes(
+                            Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY))
+                    .includeTypesFromTextClassifier(false);
+        }
+        ConversationActions.Request request =
+                new ConversationActions.Request.Builder(messages)
+                        .setMaxSuggestions(mSettings.mMaxSuggestions)
+                        .setHints(HINTS)
+                        .setTypeConfig(typeConfigBuilder.build())
+                        .build();
+        ConversationActions conversationActions =
+                getTextClassifier().suggestConversationActions(request);
+        reportActionsGenerated(
+                conversationActions.getId(), conversationActions.getConversationActions());
+        return conversationActions;
+    }
+
+    void onNotificationExpansionChanged(NotificationEntry entry, boolean isExpanded) {
+        if (!isExpanded) {
+            return;
+        }
+        Session session = mSessionCache.get(entry.getSbn().getKey());
+        if (session == null) {
+            return;
+        }
+        // Only report if this is the first time the user sees these suggestions.
+        if (entry.isShowActionEventLogged()) {
+            return;
+        }
+        entry.setShowActionEventLogged();
+        TextClassifierEvent textClassifierEvent =
+                createTextClassifierEventBuilder(
+                        TextClassifierEvent.TYPE_ACTIONS_SHOWN, session.resultId)
+                        .build();
+        // TODO: If possible, report which replies / actions are actually seen by user.
+        getTextClassifier().onTextClassifierEvent(textClassifierEvent);
+    }
+
+    void onNotificationDirectReplied(String key) {
+        Session session = mSessionCache.get(key);
+        if (session == null) {
+            return;
+        }
+        TextClassifierEvent textClassifierEvent =
+                createTextClassifierEventBuilder(
+                        TextClassifierEvent.TYPE_MANUAL_REPLY, session.resultId)
+                        .build();
+        getTextClassifier().onTextClassifierEvent(textClassifierEvent);
+    }
+
+    void onSuggestedReplySent(String key, CharSequence reply,
+            @NotificationAssistantService.Source int source) {
+        if (source != NotificationAssistantService.SOURCE_FROM_ASSISTANT) {
+            return;
+        }
+        Session session = mSessionCache.get(key);
+        if (session == null) {
+            return;
+        }
+        TextClassifierEvent textClassifierEvent =
+                createTextClassifierEventBuilder(
+                        TextClassifierEvent.TYPE_SMART_ACTION, session.resultId)
+                        .setEntityTypes(ConversationAction.TYPE_TEXT_REPLY)
+                        .setScores(session.repliesScores.getOrDefault(reply, 0f))
+                        .build();
+        getTextClassifier().onTextClassifierEvent(textClassifierEvent);
+    }
+
+    void onActionClicked(String key, Notification.Action action,
+            @NotificationAssistantService.Source int source) {
+        if (source != NotificationAssistantService.SOURCE_FROM_ASSISTANT) {
+            return;
+        }
+        Session session = mSessionCache.get(key);
+        if (session == null) {
+            return;
+        }
+        String actionType = action.getExtras().getString(KEY_ACTION_TYPE);
+        if (actionType == null) {
+            return;
+        }
+        TextClassifierEvent textClassifierEvent =
+                createTextClassifierEventBuilder(
+                        TextClassifierEvent.TYPE_SMART_ACTION, session.resultId)
+                        .setEntityTypes(actionType)
+                        .build();
+        getTextClassifier().onTextClassifierEvent(textClassifierEvent);
+    }
+
+    private Notification.Action createNotificationActionFromRemoteAction(
+            RemoteAction remoteAction, String actionType, float score) {
+        Icon icon = remoteAction.shouldShowIcon()
+                ? remoteAction.getIcon()
+                : Icon.createWithResource(mContext, com.android.internal.R.drawable.ic_action_open);
+        Bundle extras = new Bundle();
+        extras.putString(KEY_ACTION_TYPE, actionType);
+        extras.putFloat(KEY_ACTION_SCORE, score);
+        return new Notification.Action.Builder(
+                icon,
+                remoteAction.getTitle(),
+                remoteAction.getActionIntent())
+                .setContextual(true)
+                .addExtras(extras)
+                .build();
+    }
+
+    private TextClassifierEvent.ConversationActionsEvent.Builder createTextClassifierEventBuilder(
+            int eventType, String resultId) {
+        return new TextClassifierEvent.ConversationActionsEvent.Builder(eventType)
+                .setEventContext(
+                        new TextClassificationContext.Builder(
+                                mContext.getPackageName(), TextClassifier.WIDGET_TYPE_NOTIFICATION)
+                        .build())
+                .setResultId(resultId);
+    }
+
+    /**
+     * Returns whether a notification is eligible for action adjustments.
+     *
+     * <p>We exclude system notifications, those that get refreshed frequently, or ones that relate
+     * to fundamental phone functionality where any error would result in a very negative user
+     * experience.
+     */
+    private boolean isEligibleForActionAdjustment(NotificationEntry entry) {
+        Notification notification = entry.getNotification();
+        String pkg = entry.getSbn().getPackageName();
+        if (!Process.myUserHandle().equals(entry.getSbn().getUser())) {
+            return false;
+        }
+        if ((notification.flags & FLAG_MASK_INELGIBILE_FOR_ACTIONS) != 0) {
+            return false;
+        }
+        if (TextUtils.isEmpty(pkg) || pkg.equals("android")) {
+            return false;
+        }
+        // For now, we are only interested in messages.
+        return entry.isMessaging();
+    }
+
+    private boolean isEligibleForReplyAdjustment(NotificationEntry entry) {
+        if (!Process.myUserHandle().equals(entry.getSbn().getUser())) {
+            return false;
+        }
+        String pkg = entry.getSbn().getPackageName();
+        if (TextUtils.isEmpty(pkg) || pkg.equals("android")) {
+            return false;
+        }
+        // For now, we are only interested in messages.
+        if (!entry.isMessaging()) {
+            return false;
+        }
+        // Does not make sense to provide suggested replies if it is not something that can be
+        // replied.
+        if (!entry.hasInlineReply()) {
+            return false;
+        }
+        return true;
+    }
+
+    /** Returns the text most salient for action extraction in a notification. */
+    private List<ConversationActions.Message> extractMessages(Notification notification) {
+        Parcelable[] messages = notification.extras.getParcelableArray(Notification.EXTRA_MESSAGES);
+        if (messages == null || messages.length == 0) {
+            return Collections.singletonList(new ConversationActions.Message.Builder(
+                    ConversationActions.Message.PERSON_USER_OTHERS)
+                    .setText(notification.extras.getCharSequence(Notification.EXTRA_TEXT))
+                    .build());
+        }
+        Person localUser = notification.extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON);
+        Deque<ConversationActions.Message> extractMessages = new ArrayDeque<>();
+        for (int i = messages.length - 1; i >= 0; i--) {
+            Notification.MessagingStyle.Message message =
+                    Notification.MessagingStyle.Message.getMessageFromBundle((Bundle) messages[i]);
+            if (message == null) {
+                continue;
+            }
+            // As per the javadoc of Notification.addMessage, null means local user.
+            Person senderPerson = message.getSenderPerson();
+            if (senderPerson == null) {
+                senderPerson = localUser;
+            }
+            Person author = localUser != null && arePersonsEqual(localUser, senderPerson)
+                    ? ConversationActions.Message.PERSON_USER_SELF : senderPerson;
+            extractMessages.push(new ConversationActions.Message.Builder(author)
+                    .setText(message.getText())
+                    .setReferenceTime(
+                            ZonedDateTime.ofInstant(Instant.ofEpochMilli(message.getTimestamp()),
+                                    ZoneOffset.systemDefault()))
+                    .build());
+            if (extractMessages.size() >= mSettings.mMaxMessagesToExtract) {
+                break;
+            }
+        }
+        return new ArrayList<>(extractMessages);
+    }
+
+    private TextClassifier getTextClassifier() {
+        return mTextClassificationManager.getTextClassifier();
+    }
+
+    private static boolean arePersonsEqual(Person left, Person right) {
+        return Objects.equals(left.getKey(), right.getKey())
+                && Objects.equals(left.getName(), right.getName())
+                && Objects.equals(left.getUri(), right.getUri());
+    }
+
+    static class SmartSuggestions {
+        public final ArrayList<CharSequence> replies;
+        public final ArrayList<Notification.Action> actions;
+
+        SmartSuggestions(
+                ArrayList<CharSequence> replies, ArrayList<Notification.Action> actions) {
+            this.replies = replies;
+            this.actions = actions;
+        }
+    }
+
+    private static class Session {
+        public final String resultId;
+        public final Map<CharSequence, Float> repliesScores;
+
+        Session(String resultId, Map<CharSequence, Float> repliesScores) {
+            this.resultId = resultId;
+            this.repliesScores = repliesScores;
+        }
+    }
+}
diff --git a/src/android/ext/services/notification/SmsHelper.java b/src/android/ext/services/notification/SmsHelper.java
new file mode 100644
index 0000000..07be0b8
--- /dev/null
+++ b/src/android/ext/services/notification/SmsHelper.java
@@ -0,0 +1,75 @@
+/**
+ * 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 android.ext.services.notification;
+
+import static android.provider.Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL;
+
+import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.util.Log;
+
+import com.android.internal.telephony.SmsApplication;
+
+/**
+ * A helper class for storing and retrieving the default SMS application.
+ */
+public class SmsHelper {
+    private static final String TAG = "SmsHelper";
+
+    private final Context mContext;
+    private ComponentName mDefaultSmsApplication;
+    private BroadcastReceiver mBroadcastReceiver;
+
+    SmsHelper(Context context) {
+        mContext = context.getApplicationContext();
+    }
+
+    void initialize() {
+        if (mBroadcastReceiver == null) {
+            mDefaultSmsApplication = SmsApplication.getDefaultSmsApplication(mContext, false);
+            mBroadcastReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    if (ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL.equals(intent.getAction())) {
+                        mDefaultSmsApplication =
+                                SmsApplication.getDefaultSmsApplication(mContext, false);
+                    } else {
+                        Log.w(TAG, "Unknown broadcast received: " + intent.getAction());
+                    }
+                }
+            };
+            mContext.registerReceiver(
+                    mBroadcastReceiver,
+                    new IntentFilter(ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL));
+        }
+    }
+
+    void destroy() {
+        if (mBroadcastReceiver != null) {
+            mContext.unregisterReceiver(mBroadcastReceiver);
+            mBroadcastReceiver = null;
+        }
+    }
+
+    @Nullable
+    public ComponentName getDefaultSmsApplication() {
+        return mDefaultSmsApplication;
+    }
+}
diff --git a/src/android/ext/services/sms/FinancialSmsServiceImpl.java b/src/android/ext/services/sms/FinancialSmsServiceImpl.java
new file mode 100644
index 0000000..81a63dd
--- /dev/null
+++ b/src/android/ext/services/sms/FinancialSmsServiceImpl.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 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 android.ext.services.sms;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.database.CursorWindow;
+import android.os.Bundle;
+import android.service.sms.FinancialSmsService;
+
+/**
+ * Service to provide financial apps access to sms messages.
+ */
+public class FinancialSmsServiceImpl extends FinancialSmsService {
+
+    private static final String TAG = "FinancialSmsServiceImpl";
+    private static final String KEY_COLUMN_NAMES = "column_names";
+
+    @Nullable
+    @Override
+    public CursorWindow onGetSmsMessages(@NonNull Bundle params) {
+        return null;
+    }
+}
diff --git a/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java b/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java
new file mode 100644
index 0000000..670b419
--- /dev/null
+++ b/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java
@@ -0,0 +1,125 @@
+/*
+ * 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 android.ext.services.watchdog;
+
+import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.provider.DeviceConfig;
+import android.service.watchdog.ExplicitHealthCheckService;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Routes explicit health check requests to the appropriate {@link ExplicitHealthChecker}.
+ */
+public final class ExplicitHealthCheckServiceImpl extends ExplicitHealthCheckService {
+    private static final String TAG = "ExplicitHealthCheckServiceImpl";
+    // TODO: Add build dependency on NetworkStack stable AIDL so we can stop hard coding class name
+    private static final String NETWORK_STACK_CONNECTOR_CLASS =
+            "android.net.INetworkStackConnector";
+    public static final String PROPERTY_WATCHDOG_REQUEST_TIMEOUT_MILLIS =
+            "watchdog_request_timeout_millis";
+    public static final long DEFAULT_REQUEST_TIMEOUT_MILLIS =
+            TimeUnit.HOURS.toMillis(1);
+    // Modified only #onCreate, using concurrent collection to ensure thread visibility
+    private final Map<String, ExplicitHealthChecker> mSupportedCheckers = new ConcurrentHashMap<>();
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        initHealthCheckers();
+    }
+
+    @Override
+    public void onRequestHealthCheck(String packageName) {
+        ExplicitHealthChecker checker = mSupportedCheckers.get(packageName);
+        if (checker != null) {
+            checker.request();
+        } else {
+            Log.w(TAG, "Ignoring request for explicit health check for unsupported package "
+                    + packageName);
+        }
+    }
+
+    @Override
+    public void onCancelHealthCheck(String packageName) {
+        ExplicitHealthChecker checker = mSupportedCheckers.get(packageName);
+        if (checker != null) {
+            checker.cancel();
+        } else {
+            Log.w(TAG, "Ignoring request to cancel explicit health check for unsupported package "
+                    + packageName);
+        }
+    }
+
+    @Override
+    public List<PackageConfig> onGetSupportedPackages() {
+        List<PackageConfig> packages = new ArrayList<>();
+        long requestTimeoutMillis = DeviceConfig.getLong(
+                DeviceConfig.NAMESPACE_ROLLBACK,
+                PROPERTY_WATCHDOG_REQUEST_TIMEOUT_MILLIS,
+                DEFAULT_REQUEST_TIMEOUT_MILLIS);
+        if (requestTimeoutMillis <= 0) {
+            requestTimeoutMillis = DEFAULT_REQUEST_TIMEOUT_MILLIS;
+        }
+        for (ExplicitHealthChecker checker : mSupportedCheckers.values()) {
+            PackageConfig pkg = new PackageConfig(checker.getSupportedPackageName(),
+                    requestTimeoutMillis);
+            packages.add(pkg);
+        }
+        return packages;
+    }
+
+    @Override
+    public List<String> onGetRequestedPackages() {
+        List<String> packages = new ArrayList<>();
+        Iterator<ExplicitHealthChecker> it = mSupportedCheckers.values().iterator();
+        // Could potentially race, where we read a checker#isPending and it changes before we
+        // return list. However, if it races and it is in the list, the caller might call #cancel
+        // which would fail, but that is fine. If it races and it ends up *not* in the list, it was
+        // already cancelled, so there's no need for the caller to cancel it
+        while (it.hasNext()) {
+            ExplicitHealthChecker checker = it.next();
+            if (checker.isPending()) {
+                packages.add(checker.getSupportedPackageName());
+            }
+        }
+        return packages;
+    }
+
+    private void initHealthCheckers() {
+        Intent intent = new Intent(NETWORK_STACK_CONNECTOR_CLASS);
+        ComponentName comp = intent.resolveSystemService(getPackageManager(), 0);
+        if (comp != null) {
+            String networkStackPackageName = comp.getPackageName();
+            mSupportedCheckers.put(networkStackPackageName,
+                    new NetworkChecker(this, networkStackPackageName));
+        } else {
+            // On Go devices, or any device that does not ship the network stack module.
+            // The network stack will live in system_server process, so no need to monitor.
+            Log.i(TAG, "Network stack module not found");
+        }
+    }
+}
diff --git a/src/android/ext/services/watchdog/ExplicitHealthChecker.java b/src/android/ext/services/watchdog/ExplicitHealthChecker.java
new file mode 100644
index 0000000..a982d52
--- /dev/null
+++ b/src/android/ext/services/watchdog/ExplicitHealthChecker.java
@@ -0,0 +1,44 @@
+/*
+ * 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 android.ext.services.watchdog;
+
+/**
+ * A type of explicit health check that can be performed on a device, e.g network health check
+ */
+interface ExplicitHealthChecker {
+    /**
+     * Requests a checker to listen to explicit health checks for {@link #getPackageName}.
+     *  {@link #isPending} will now return {@code true}.
+     */
+    void request();
+
+    /**
+     * Cancels a pending explicit health check request for {@link #getPackageName}.
+     * {@link #isPending} will now return {@code false}.
+     */
+    void cancel();
+
+    /**
+     * Returns {@code true} if a request is pending, {@code false} otherwise.
+     */
+    boolean isPending();
+
+    /**
+     * Returns the name of the package this checker can make requests for.
+     */
+    String getSupportedPackageName();
+}
diff --git a/src/android/ext/services/watchdog/NetworkChecker.java b/src/android/ext/services/watchdog/NetworkChecker.java
new file mode 100644
index 0000000..5722e09
--- /dev/null
+++ b/src/android/ext/services/watchdog/NetworkChecker.java
@@ -0,0 +1,92 @@
+/*
+ * 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 android.ext.services.watchdog;
+
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.service.watchdog.ExplicitHealthCheckService;
+
+import com.android.internal.annotations.GuardedBy;
+
+/**
+ * Observes the network stack via the ConnectivityManager.
+ */
+final class NetworkChecker extends ConnectivityManager.NetworkCallback
+        implements ExplicitHealthChecker {
+    private static final String TAG = "NetworkChecker";
+
+    private final Object mLock = new Object();
+    private final ExplicitHealthCheckService mService;
+    private final String mPackageName;
+    @GuardedBy("mLock")
+    private boolean mIsPending;
+
+    NetworkChecker(ExplicitHealthCheckService service, String packageName) {
+        mService = service;
+        mPackageName = packageName;
+    }
+
+    @Override
+    public void request() {
+        synchronized (mLock) {
+            if (mIsPending) {
+                return;
+            }
+            mService.getSystemService(ConnectivityManager.class).registerNetworkCallback(
+                    new NetworkRequest.Builder().build(), this);
+            mIsPending = true;
+        }
+    }
+
+    @Override
+    public void cancel() {
+        synchronized (mLock) {
+            if (!mIsPending) {
+                return;
+            }
+            mService.getSystemService(ConnectivityManager.class).unregisterNetworkCallback(this);
+            mIsPending = false;
+        }
+    }
+
+    @Override
+    public boolean isPending() {
+        synchronized (mLock) {
+            return mIsPending;
+        }
+    }
+
+    @Override
+    public String getSupportedPackageName() {
+        return mPackageName;
+    }
+
+    // TODO(b/120598832): Also monitor NetworkCallback#onAvailable to see if we have any
+    // available networks that may be unusable. This could be additional signal to our heuristics
+    @Override
+    public void onCapabilitiesChanged(Network network, NetworkCapabilities capabilities) {
+        synchronized (mLock) {
+            if (mIsPending
+                    && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
+                mService.notifyHealthCheckPassed(mPackageName);
+                cancel();
+            }
+        }
+    }
+}
diff --git a/tests/Android.bp b/tests/Android.bp
index db16027..ae60d4e 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -1,19 +1,27 @@
 android_test {
     name: "ExtServicesUnitTests",
+
+    // Include all test java files.
+    srcs: ["src/**/*.java"],
+
+    // We only want this apk build for tests.
     certificate: "platform",
+
     libs: [
         "android.test.runner",
         "android.test.base",
     ],
+
     static_libs: [
+        "ExtServices-core",
         "androidx.test.rules",
+        "compatibility-device-util-axt",
         "mockito-target-minus-junit4",
         "androidx.test.espresso.core",
         "truth-prebuilt",
         "testables",
+        "testng",
     ],
-    // Include all test java files.
-    srcs: ["src/**/*.java"],
+
     platform_apis: true,
-    instrumentation_for: "ExtServices",
 }
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 42293b5..a08a10e 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -24,7 +24,7 @@
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.ext.services"
+                     android:targetPackage="android.ext.services.tests.unit"
                      android:label="ExtServices Test Cases">
     </instrumentation>
 
diff --git a/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java b/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java
index 48c076e..6fda4c7 100644
--- a/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java
+++ b/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java
@@ -16,14 +16,21 @@
 
 package android.ext.services.autofill;
 
+import static android.service.autofill.AutofillFieldClassificationService.REQUIRED_ALGORITHM_EXACT_MATCH;
+import static android.view.autofill.AutofillValue.forText;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.os.Bundle;
+import android.view.autofill.AutofillValue;
+
 import org.junit.Test;
 
 import java.util.Arrays;
 import java.util.Collections;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.view.autofill.AutofillValue;
+import java.util.HashMap;
+import java.util.List;
 
 /**
  * Contains the base tests that does not rely on the specific algorithm implementation.
@@ -34,26 +41,78 @@
             new AutofillFieldClassificationServiceImpl();
 
     @Test
-    public void testOnGetScores_nullActualValues() {
-        assertThat(mService.onGetScores(null, null, null, Arrays.asList("whatever"))).isNull();
+    public void testOnCalculateScores_nullActualValues() {
+        assertThat(mService.onCalculateScores(null, null, null, null, null, null, null)).isNull();
     }
 
     @Test
-    public void testOnGetScores_emptyActualValues() {
-        assertThat(mService.onGetScores(null, null, Collections.emptyList(),
-                Arrays.asList("whatever"))).isNull();
+    public void testOnCalculateScores_emptyActualValues() {
+        assertThat(mService.onCalculateScores(Collections.emptyList(), Arrays.asList("whatever"),
+                null, null, null, null, null)).isNull();
     }
 
     @Test
-    public void testOnGetScores_nullUserDataValues() {
-        assertThat(mService.onGetScores(null, null,
-                Arrays.asList(AutofillValue.forText("whatever")), null)).isNull();
+    public void testOnCalculateScores_nullUserDataValues() {
+        assertThat(mService.onCalculateScores(Arrays.asList(AutofillValue.forText("whatever")),
+                null, null, null, null, null, null)).isNull();
     }
 
     @Test
-    public void testOnGetScores_emptyUserDataValues() {
-        assertThat(mService.onGetScores(null, null,
-                Arrays.asList(AutofillValue.forText("whatever")), Collections.emptyList()))
-                        .isNull();
+    public void testOnCalculateScores_emptyUserDataValues() {
+        assertThat(mService.onCalculateScores(Arrays.asList(AutofillValue.forText("whatever")),
+                Collections.emptyList(), null, null, null, null, null))
+                .isNull();
+    }
+
+    @Test
+    public void testCalculateScores() {
+        final List<AutofillValue> actualValues = Arrays.asList(forText("A"), forText("b"),
+                forText("dude"));
+        final List<String> userDataValues = Arrays.asList("a", "b", "B", "ab", "c", "dude",
+                "sweet_dude", "dude_sweet");
+        final List<String> categoryIds = Arrays.asList("cat", "cat", "cat", "cat", "cat", "last4",
+                "last4", "last4");
+        final HashMap<String, String> algorithms = new HashMap<>(1);
+        algorithms.put("last4", REQUIRED_ALGORITHM_EXACT_MATCH);
+
+        final Bundle last4Bundle = new Bundle();
+        last4Bundle.putInt("suffix", 4);
+
+        final HashMap<String, Bundle> args = new HashMap<>(1);
+        args.put("last4", last4Bundle);
+
+        final float[][] expectedScores = new float[][] {
+                new float[] { 1F, 0F, 0F, 0.5F, 0F, 0F, 0F, 0F },
+                new float[] { 0F, 1F, 1F, 0.5F, 0F, 0F, 0F, 0F },
+                new float[] { 0F, 0F, 0F, 0F  , 0F, 1F, 1F, 0F }
+        };
+        final float[][] actualScores = mService.onCalculateScores(actualValues, userDataValues,
+                categoryIds, null, null, algorithms, args);
+
+        // Unfortunately, Truth does not have an easy way to compare float matrices and show useful
+        // messages in case of error, so we need to check.
+        assertWithMessage("actual=%s, expected=%s", toString(actualScores),
+                toString(expectedScores)).that(actualScores.length).isEqualTo(3);
+        for (int i = 0; i < 3; i++) {
+            assertWithMessage("actual=%s, expected=%s", toString(actualScores),
+                    toString(expectedScores)).that(actualScores[i].length).isEqualTo(8);
+        }
+
+        for (int i = 0; i < actualScores.length; i++) {
+            final float[] line = actualScores[i];
+            for (int j = 0; j < line.length; j++) {
+                float cell = line[j];
+                assertWithMessage("wrong score at [%s, %s]", i, j).that(cell).isWithin(0.01F)
+                        .of(expectedScores[i][j]);
+            }
+        }
+    }
+
+    public static String toString(float[][] matrix) {
+        final StringBuilder string = new StringBuilder("[ ");
+        for (int i = 0; i < matrix.length; i++) {
+            string.append(Arrays.toString(matrix[i])).append(" ");
+        }
+        return string.append(" ]").toString();
     }
 }
diff --git a/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java b/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java
index afe2236..3d754f7 100644
--- a/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java
+++ b/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java
@@ -15,107 +15,71 @@
  */
 package android.ext.services.autofill;
 
-import static android.ext.services.autofill.EditDistanceScorer.getScore;
-import static android.ext.services.autofill.EditDistanceScorer.getScores;
-import static android.view.autofill.AutofillValue.forText;
+import static android.ext.services.autofill.EditDistanceScorer.calculateScore;
+import static android.ext.services.autofill.EditDistanceScorer.editDistance;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
 
 import android.view.autofill.AutofillValue;
 
 import org.junit.Test;
 
-import java.util.Arrays;
-import java.util.List;
-
 public class EditDistanceScorerTest {
 
     @Test
-    public void testGetScore_nullValue() {
-        assertFloat(getScore(null, "D'OH!"), 0);
+    public void testCalculateScore_nullValue() {
+        assertFloat(calculateScore(null, "D'OH!"), 0);
     }
 
     @Test
-    public void testGetScore_nonTextValue() {
-        assertFloat(getScore(AutofillValue.forToggle(true), "D'OH!"), 0);
+    public void testCalculateScore_nonTextValue() {
+        assertFloat(calculateScore(AutofillValue.forToggle(true), "D'OH!"), 0);
     }
 
     @Test
-    public void testGetScore_nullUserData() {
-        assertFloat(getScore(AutofillValue.forText("D'OH!"), null), 0);
+    public void testCalculateScore_nullUserData() {
+        assertFloat(calculateScore(AutofillValue.forText("D'OH!"), null), 0);
     }
 
     @Test
-    public void testGetScore_fullMatch() {
-        assertFloat(getScore(AutofillValue.forText("D'OH!"), "D'OH!"), 1);
-        assertFloat(getScore(AutofillValue.forText(""), ""), 1);
+    public void testCalculateScore_fullMatch() {
+        assertFloat(calculateScore(AutofillValue.forText("D'OH!"), "D'OH!"), 1);
+        assertFloat(calculateScore(AutofillValue.forText(""), ""), 1);
     }
 
     @Test
-    public void testGetScore_fullMatchMixedCase() {
-        assertFloat(getScore(AutofillValue.forText("D'OH!"), "D'oH!"), 1);
+    public void testCalculateScore_fullMatchMixedCase() {
+        assertFloat(calculateScore(AutofillValue.forText("D'OH!"), "D'oH!"), 1);
     }
 
     @Test
-    public void testGetScore_mismatchDifferentSizes() {
-        assertFloat(getScore(AutofillValue.forText("X"), "Xy"), 0.50F);
-        assertFloat(getScore(AutofillValue.forText("Xy"), "X"), 0.50F);
-        assertFloat(getScore(AutofillValue.forText("One"), "MoreThanOne"), 0.27F);
-        assertFloat(getScore(AutofillValue.forText("MoreThanOne"), "One"), 0.27F);
-        assertFloat(getScore(AutofillValue.forText("1600 Amphitheatre Parkway"),
+    public void testCalculateScore_mismatchDifferentSizes() {
+        assertFloat(calculateScore(AutofillValue.forText("X"), "Xy"), 0.50F);
+        assertFloat(calculateScore(AutofillValue.forText("Xy"), "X"), 0.50F);
+        assertFloat(calculateScore(AutofillValue.forText("One"), "MoreThanOne"), 0.27F);
+        assertFloat(calculateScore(AutofillValue.forText("MoreThanOne"), "One"), 0.27F);
+        assertFloat(calculateScore(AutofillValue.forText("1600 Amphitheatre Parkway"),
                 "1600 Amphitheatre Pkwy"), 0.88F);
-        assertFloat(getScore(AutofillValue.forText("1600 Amphitheatre Pkwy"),
+        assertFloat(calculateScore(AutofillValue.forText("1600 Amphitheatre Pkwy"),
                 "1600 Amphitheatre Parkway"), 0.88F);
     }
 
     @Test
-    public void testGetScore_partialMatch() {
-        assertFloat(getScore(AutofillValue.forText("Dude"), "Dxxx"), 0.25F);
-        assertFloat(getScore(AutofillValue.forText("Dude"), "DUxx"), 0.50F);
-        assertFloat(getScore(AutofillValue.forText("Dude"), "DUDx"), 0.75F);
-        assertFloat(getScore(AutofillValue.forText("Dxxx"), "Dude"), 0.25F);
-        assertFloat(getScore(AutofillValue.forText("DUxx"), "Dude"), 0.50F);
-        assertFloat(getScore(AutofillValue.forText("DUDx"), "Dude"), 0.75F);
+    public void testCalculateScore_partialMatch() {
+        assertFloat(calculateScore(AutofillValue.forText("Dude"), "Dxxx"), 0.25F);
+        assertFloat(calculateScore(AutofillValue.forText("Dude"), "DUxx"), 0.50F);
+        assertFloat(calculateScore(AutofillValue.forText("Dude"), "DUDx"), 0.75F);
+        assertFloat(calculateScore(AutofillValue.forText("Dxxx"), "Dude"), 0.25F);
+        assertFloat(calculateScore(AutofillValue.forText("DUxx"), "Dude"), 0.50F);
+        assertFloat(calculateScore(AutofillValue.forText("DUDx"), "Dude"), 0.75F);
     }
 
     @Test
-    public void testGetScores() {
-        final List<AutofillValue> actualValues = Arrays.asList(forText("A"), forText("b"));
-        final List<String> userDataValues = Arrays.asList("a", "B", "ab", "c");
-        final float[][] expectedScores = new float[][] {
-            new float[] { 1F, 0F, 0.5F, 0F },
-            new float[] { 0F, 1F, 0.5F, 0F }
-        };
-        final float[][] actualScores = getScores(actualValues, userDataValues);
-
-        // Unfortunately, Truth does not have an easy way to compare float matrices and show useful
-        // messages in case of error, so we need to check.
-        assertWithMessage("actual=%s, expected=%s", toString(actualScores),
-                toString(expectedScores)).that(actualScores.length).isEqualTo(2);
-        assertWithMessage("actual=%s, expected=%s", toString(actualScores),
-                toString(expectedScores)).that(actualScores[0].length).isEqualTo(4);
-        assertWithMessage("actual=%s, expected=%s", toString(actualScores),
-                toString(expectedScores)).that(actualScores[1].length).isEqualTo(4);
-        for (int i = 0; i < actualScores.length; i++) {
-            final float[] line = actualScores[i];
-            for (int j = 0; j < line.length; j++) {
-                float cell = line[j];
-                assertWithMessage("wrong score at [%s, %s]", i, j).that(cell).isWithin(0.01F)
-                        .of(expectedScores[i][j]);
-            }
-        }
+    public void testEditDistance_maxDistance() {
+        assertFloat(editDistance("testing", "b", 4), Integer.MAX_VALUE);
     }
 
     public static void assertFloat(float actualValue, float expectedValue) {
         assertThat(actualValue).isWithin(0.01F).of(expectedValue);
     }
-
-    public static String toString(float[][] matrix) {
-        final StringBuilder string = new StringBuilder("[ ");
-        for (int i = 0; i < matrix.length; i++) {
-            string.append(Arrays.toString(matrix[i])).append(" ");
-        }
-        return string.append(" ]").toString();
-    }
 }
diff --git a/tests/src/android/ext/services/autofill/ExactMatchTest.java b/tests/src/android/ext/services/autofill/ExactMatchTest.java
new file mode 100644
index 0000000..bf5e160
--- /dev/null
+++ b/tests/src/android/ext/services/autofill/ExactMatchTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2018 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 android.ext.services.autofill;
+
+import static android.ext.services.autofill.ExactMatch.calculateScore;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.os.Bundle;
+import android.view.autofill.AutofillValue;
+
+import org.junit.Test;
+
+public class ExactMatchTest {
+
+    private Bundle last4Bundle() {
+        final Bundle bundle = new Bundle();
+        bundle.putInt("suffix", 4);
+        return bundle;
+    }
+
+    @Test
+    public void testCalculateScore_nullValue() {
+        assertFloat(calculateScore(null, "TEST", null), 0);
+    }
+
+    @Test
+    public void testCalculateScore_nonTextValue() {
+        assertFloat(calculateScore(AutofillValue.forToggle(true), "TEST", null), 0);
+    }
+
+    @Test
+    public void testCalculateScore_nullUserData() {
+        assertFloat(calculateScore(AutofillValue.forText("TEST"), null, null), 0);
+    }
+
+    @Test
+    public void testCalculateScore_succeedMatchMixedCases_last4() {
+        final Bundle last4 = last4Bundle();
+        assertFloat(calculateScore(AutofillValue.forText("TEST"), "1234 test", last4), 1);
+        assertFloat(calculateScore(AutofillValue.forText("test"), "1234 TEST", last4), 1);
+    }
+
+    @Test
+    public void testCalculateScore_mismatchDifferentSizes_last4() {
+        final Bundle last4 = last4Bundle();
+        assertFloat(calculateScore(AutofillValue.forText("TEST"), "TEST1", last4), 0);
+        assertFloat(calculateScore(AutofillValue.forText(""), "TEST", last4), 0);
+        assertFloat(calculateScore(AutofillValue.forText("TEST"), "", last4), 0);
+    }
+
+    @Test
+    public void testCalculateScore_match() {
+        final Bundle last4 = last4Bundle();
+        assertFloat(calculateScore(AutofillValue.forText("1234 1234 1234 1234"),
+                "xxxx xxxx xxxx 1234", last4), 1);
+        assertFloat(calculateScore(AutofillValue.forText("TEST"), "TEST", null), 1);
+        assertFloat(calculateScore(AutofillValue.forText("TEST 1234"), "1234", last4), 1);
+        assertFloat(calculateScore(AutofillValue.forText("TEST"), "test", null), 1);
+    }
+
+    @Test
+    public void testCalculateScore_badBundle() {
+        final Bundle bundle = new Bundle();
+        bundle.putInt("suffix", -2);
+        assertThrows(IllegalArgumentException.class, () -> calculateScore(
+                AutofillValue.forText("TEST"), "TEST", bundle));
+
+        final Bundle largeBundle = new Bundle();
+        largeBundle.putInt("suffix", 10);
+        assertFloat(calculateScore(AutofillValue.forText("TEST"), "TEST", largeBundle), 1);
+
+        final Bundle stringBundle = new Bundle();
+        stringBundle.putString("suffix", "value");
+        assertThrows(IllegalArgumentException.class, () -> calculateScore(
+                AutofillValue.forText("TEST"), "TEST", stringBundle));
+
+    }
+
+    public static void assertFloat(float actualValue, float expectedValue) {
+        assertThat(actualValue).isWithin(0.01F).of(expectedValue);
+    }
+}
diff --git a/tests/src/android/ext/services/notification/AgingHelperTest.java b/tests/src/android/ext/services/notification/AgingHelperTest.java
new file mode 100644
index 0000000..a87d57c
--- /dev/null
+++ b/tests/src/android/ext/services/notification/AgingHelperTest.java
@@ -0,0 +1,160 @@
+/**
+ * Copyright (C) 2018 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 android.ext.services.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.AlarmManager;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.PendingIntent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.os.Build;
+import android.os.Process;
+import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
+import android.testing.TestableContext;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class AgingHelperTest {
+    private String mPkg = "pkg";
+    private int mUid = 2018;
+
+    @Rule
+    public final TestableContext mContext =
+            new TestableContext(InstrumentationRegistry.getTargetContext(), null);
+
+    @Mock
+    private NotificationCategorizer mCategorizer;
+    @Mock
+    private AlarmManager mAlarmManager;
+    @Mock
+    private IPackageManager mPackageManager;
+    @Mock
+    private AgingHelper.Callback mCallback;
+    @Mock
+    private SmsHelper mSmsHelper;
+
+    private AgingHelper mAgingHelper;
+
+    private StatusBarNotification generateSbn(String channelId) {
+        Notification n = new Notification.Builder(mContext, channelId)
+                .setContentTitle("foo")
+                .build();
+
+        return new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, mUid, n,
+                UserHandle.SYSTEM, null, 0);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mPkg = mContext.getPackageName();
+        mUid = Process.myUid();
+
+        ApplicationInfo info = mock(ApplicationInfo.class);
+        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
+                .thenReturn(info);
+        info.targetSdkVersion = Build.VERSION_CODES.P;
+
+        mContext.addMockSystemService(AlarmManager.class, mAlarmManager);
+
+        mAgingHelper = new AgingHelper(mContext, mCategorizer, mCallback);
+    }
+
+    @Test
+    public void testNoSnoozingOnPost() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+        StatusBarNotification sbn = generateSbn(channel.getId());
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, sbn, channel, mSmsHelper);
+
+
+        mAgingHelper.onNotificationPosted(entry);
+        verify(mAlarmManager, never()).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
+    }
+
+    @Test
+    public void testPostResetsSnooze() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+        StatusBarNotification sbn = generateSbn(channel.getId());
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, sbn, channel, mSmsHelper);
+
+
+        mAgingHelper.onNotificationPosted(entry);
+        verify(mAlarmManager, times(1)).cancel(any(PendingIntent.class));
+    }
+
+    @Test
+    public void testSnoozingOnSeen() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+        StatusBarNotification sbn = generateSbn(channel.getId());
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, sbn, channel, mSmsHelper);
+        entry.setSeen();
+        when(mCategorizer.getCategory(entry)).thenReturn(NotificationCategorizer.CATEGORY_PEOPLE);
+
+        mAgingHelper.onNotificationSeen(entry);
+        verify(mAlarmManager, times(1)).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
+    }
+
+    @Test
+    public void testNoSnoozingOnSeenUserLocked() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+        channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+        StatusBarNotification sbn = generateSbn(channel.getId());
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, sbn, channel, mSmsHelper);
+        when(mCategorizer.getCategory(entry)).thenReturn(NotificationCategorizer.CATEGORY_PEOPLE);
+
+        mAgingHelper.onNotificationSeen(entry);
+        verify(mAlarmManager, never()).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
+    }
+
+    @Test
+    public void testNoSnoozingOnSeenAlreadyLow() {
+        NotificationEntry entry = mock(NotificationEntry.class);
+        when(entry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_HIGH));
+        when(entry.getImportance()).thenReturn(IMPORTANCE_MIN);
+
+        mAgingHelper.onNotificationSeen(entry);
+        verify(mAlarmManager, never()).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
+    }
+}
diff --git a/tests/src/android/ext/services/notification/AssistantSettingsTest.java b/tests/src/android/ext/services/notification/AssistantSettingsTest.java
new file mode 100644
index 0000000..5c877de
--- /dev/null
+++ b/tests/src/android/ext/services/notification/AssistantSettingsTest.java
@@ -0,0 +1,263 @@
+/**
+ * Copyright (C) 2018 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 android.ext.services.notification;
+
+import static android.ext.services.notification.AssistantSettings.DEFAULT_MAX_SUGGESTIONS;
+import static android.provider.DeviceConfig.setProperty;
+
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.content.ContentResolver;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.DeviceConfig;
+import android.provider.Settings;
+import android.support.test.uiautomator.UiDevice;
+import android.testing.TestableContext;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.IOException;
+
+@RunWith(AndroidJUnit4.class)
+public class AssistantSettingsTest {
+    private static final String CLEAR_DEVICE_CONFIG_KEY_CMD =
+            "device_config delete " + DeviceConfig.NAMESPACE_SYSTEMUI;
+
+    private static final int USER_ID = 5;
+
+    @Rule
+    public final TestableContext mContext =
+            new TestableContext(InstrumentationRegistry.getContext(), null);
+
+    @Mock Runnable mOnUpdateRunnable;
+
+    private ContentResolver mResolver;
+    private AssistantSettings mAssistantSettings;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mResolver = mContext.getContentResolver();
+        Handler handler = new Handler(Looper.getMainLooper());
+
+        // To bypass real calls to global settings values, set the Settings values here.
+        Settings.Global.putFloat(mResolver,
+                Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT, 0.8f);
+        Settings.Global.putInt(mResolver, Settings.Global.BLOCKING_HELPER_STREAK_LIMIT, 2);
+        Settings.Secure.putInt(mResolver, Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL, 1);
+
+        mAssistantSettings = AssistantSettings.createForTesting(
+                handler, mResolver, USER_ID, mOnUpdateRunnable);
+    }
+
+    @After
+    public void tearDown() throws IOException {
+        clearDeviceConfig();
+    }
+
+    @Test
+    public void testGenerateRepliesDisabled() {
+        runWithShellPermissionIdentity(() -> setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
+                "false",
+                false /* makeDefault */));
+        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
+
+        assertFalse(mAssistantSettings.mGenerateReplies);
+    }
+
+    @Test
+    public void testGenerateRepliesEnabled() {
+        runWithShellPermissionIdentity(() -> setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
+                "true",
+                false /* makeDefault */));
+        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
+
+        assertTrue(mAssistantSettings.mGenerateReplies);
+    }
+
+    @Test
+    public void testGenerateRepliesNullFlag() {
+        runWithShellPermissionIdentity(() -> setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
+                "false",
+                false /* makeDefault */));
+        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
+
+        assertFalse(mAssistantSettings.mGenerateReplies);
+
+        runWithShellPermissionIdentity(() -> setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
+                null,
+                false /* makeDefault */));
+        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
+
+        // Go back to the default value.
+        assertTrue(mAssistantSettings.mGenerateReplies);
+    }
+
+    @Test
+    public void testGenerateActionsDisabled() {
+        runWithShellPermissionIdentity(() -> setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
+                "false",
+                false /* makeDefault */));
+        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
+
+        assertFalse(mAssistantSettings.mGenerateActions);
+    }
+
+    @Test
+    public void testGenerateActionsEnabled() {
+        runWithShellPermissionIdentity(() -> setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
+                "true",
+                false /* makeDefault */));
+        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
+
+        assertTrue(mAssistantSettings.mGenerateActions);
+    }
+
+    @Test
+    public void testGenerateActionsNullFlag() {
+        runWithShellPermissionIdentity(() -> setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
+                "false",
+                false /* makeDefault */));
+        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
+
+        assertFalse(mAssistantSettings.mGenerateActions);
+
+        runWithShellPermissionIdentity(() -> setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
+                null,
+                false /* makeDefault */));
+        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
+
+        // Go back to the default value.
+        assertTrue(mAssistantSettings.mGenerateActions);
+    }
+
+    @Test
+    public void testMaxMessagesToExtract() {
+        runWithShellPermissionIdentity(() -> setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_MAX_MESSAGES_TO_EXTRACT,
+                "10",
+                false /* makeDefault */));
+        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
+
+        assertEquals(10, mAssistantSettings.mMaxMessagesToExtract);
+    }
+
+    @Test
+    public void testMaxSuggestions() {
+        runWithShellPermissionIdentity(() -> setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_MAX_SUGGESTIONS,
+                "5",
+                false /* makeDefault */));
+        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
+
+        assertEquals(5, mAssistantSettings.mMaxSuggestions);
+    }
+
+    @Test
+    public void testMaxSuggestionsEmpty() {
+        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
+
+        assertEquals(DEFAULT_MAX_SUGGESTIONS, mAssistantSettings.mMaxSuggestions);
+    }
+
+    @Test
+    public void testStreakLimit() {
+        verify(mOnUpdateRunnable, never()).run();
+
+        // Update settings value.
+        int newStreakLimit = 4;
+        Settings.Global.putInt(mResolver,
+                Settings.Global.BLOCKING_HELPER_STREAK_LIMIT, newStreakLimit);
+
+        // Notify for the settings value we updated.
+        mAssistantSettings.onChange(false, Settings.Global.getUriFor(
+                Settings.Global.BLOCKING_HELPER_STREAK_LIMIT));
+
+        assertEquals(newStreakLimit, mAssistantSettings.mStreakLimit);
+        verify(mOnUpdateRunnable).run();
+    }
+
+    @Test
+    public void testDismissToViewRatioLimit() {
+        verify(mOnUpdateRunnable, never()).run();
+
+        // Update settings value.
+        float newDismissToViewRatioLimit = 3f;
+        Settings.Global.putFloat(mResolver,
+                Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT,
+                newDismissToViewRatioLimit);
+
+        // Notify for the settings value we updated.
+        mAssistantSettings.onChange(false, Settings.Global.getUriFor(
+                Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT));
+
+        assertEquals(newDismissToViewRatioLimit, mAssistantSettings.mDismissToViewRatioLimit, 1e-6);
+        verify(mOnUpdateRunnable).run();
+    }
+
+    private static void clearDeviceConfig() throws IOException {
+        UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        uiDevice.executeShellCommand(
+                CLEAR_DEVICE_CONFIG_KEY_CMD + " " + SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS);
+        uiDevice.executeShellCommand(
+                CLEAR_DEVICE_CONFIG_KEY_CMD + " " + SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES);
+        uiDevice.executeShellCommand(
+                CLEAR_DEVICE_CONFIG_KEY_CMD + " "
+                + SystemUiDeviceConfigFlags.NAS_MAX_MESSAGES_TO_EXTRACT);
+        uiDevice.executeShellCommand(
+                CLEAR_DEVICE_CONFIG_KEY_CMD + " " + SystemUiDeviceConfigFlags.NAS_MAX_SUGGESTIONS);
+    }
+
+}
diff --git a/tests/src/android/ext/services/notification/AssistantTest.java b/tests/src/android/ext/services/notification/AssistantTest.java
index 6ef25e5..012dcc0 100644
--- a/tests/src/android/ext/services/notification/AssistantTest.java
+++ b/tests/src/android/ext/services/notification/AssistantTest.java
@@ -20,9 +20,9 @@
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_MIN;
 
-import static junit.framework.Assert.assertEquals;
-
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
@@ -33,10 +33,11 @@
 import android.app.INotificationManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
-import android.content.ContentResolver;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.os.Build;
 import android.os.UserHandle;
-import android.provider.Settings;
 import android.service.notification.Adjustment;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationListenerService.Ranking;
@@ -64,6 +65,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.FileOutputStream;
+import java.util.ArrayList;
 
 public class AssistantTest extends ServiceTestCase<Assistant> {
 
@@ -83,6 +85,8 @@
 
     @Mock INotificationManager mNoMan;
     @Mock AtomicFile mFile;
+    @Mock IPackageManager mPackageManager;
+    @Mock SmsHelper mSmsHelper;
 
     Assistant mAssistant;
     Application mApplication;
@@ -103,19 +107,30 @@
                 new Intent("android.service.notification.NotificationAssistantService");
         startIntent.setPackage("android.ext.services");
 
-        // To bypass real calls to global settings values, set the Settings values here.
-        Settings.Global.putFloat(mContext.getContentResolver(),
-                Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT, 0.8f);
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.BLOCKING_HELPER_STREAK_LIMIT, 2);
         mApplication = (Application) InstrumentationRegistry.getInstrumentation().
                 getTargetContext().getApplicationContext();
         // Force the test to use the correct application instead of trying to use a mock application
         setApplication(mApplication);
-        bindService(startIntent);
+
+        setupService();
         mAssistant = getService();
+
+        // Override the AssistantSettings factory.
+        mAssistant.mSettingsFactory = AssistantSettings::createForTesting;
+
+        bindService(startIntent);
+
+        mAssistant.mSettings.mDismissToViewRatioLimit = 0.8f;
+        mAssistant.mSettings.mStreakLimit = 2;
+        mAssistant.mSettings.mNewInterruptionModel = true;
         mAssistant.setNoMan(mNoMan);
         mAssistant.setFile(mFile);
+        mAssistant.setPackageManager(mPackageManager);
+
+        ApplicationInfo info = mock(ApplicationInfo.class);
+        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
+                .thenReturn(info);
+        info.targetSdkVersion = Build.VERSION_CODES.P;
         when(mFile.startWrite()).thenReturn(mock(FileOutputStream.class));
     }
 
@@ -167,7 +182,7 @@
         mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
@@ -180,7 +195,7 @@
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
         ArgumentCaptor<Adjustment> captor = ArgumentCaptor.forClass(Adjustment.class);
-        verify(mNoMan, times(1)).applyAdjustmentFromAssistant(any(), captor.capture());
+        verify(mNoMan, times(1)).applyEnqueuedAdjustmentFromAssistant(any(), captor.capture());
         assertEquals(sbn.getKey(), captor.getValue().getKey());
         assertEquals(Ranking.USER_SENTIMENT_NEGATIVE,
                 captor.getValue().getSignals().getInt(Adjustment.KEY_USER_SENTIMENT));
@@ -195,7 +210,7 @@
         mAssistant.setFakeRanking(generateRanking(sbn, P1C3));
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
@@ -215,7 +230,7 @@
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
         ArgumentCaptor<Adjustment> captor = ArgumentCaptor.forClass(Adjustment.class);
-        verify(mNoMan, times(1)).applyAdjustmentFromAssistant(any(), captor.capture());
+        verify(mNoMan, times(1)).applyEnqueuedAdjustmentFromAssistant(any(), captor.capture());
         assertEquals(sbn.getKey(), captor.getValue().getKey());
         assertEquals(Ranking.USER_SENTIMENT_NEGATIVE,
                 captor.getValue().getSignals().getInt(Adjustment.KEY_USER_SENTIMENT));
@@ -238,7 +253,7 @@
         sbn = generateSbn(PKG1, UID1, P1C1, "new one!", "group");
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
@@ -257,7 +272,7 @@
         sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
@@ -276,7 +291,7 @@
         sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
@@ -295,7 +310,7 @@
         sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
@@ -307,7 +322,7 @@
         mAssistant.setFakeRanking(generateRanking(sbn, P2C1));
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
@@ -319,7 +334,7 @@
         mAssistant.setFakeRanking(generateRanking(sbn, P1C2));
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
@@ -398,6 +413,8 @@
         mAssistant.writeXml(serializer);
 
         Assistant assistant = new Assistant();
+        // onCreate is not invoked, so settings won't be initialised, unless we do it here.
+        assistant.mSettings = mAssistant.mSettings;
         assistant.readXml(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())));
 
         assertEquals(ci1, assistant.getImpressions(key1));
@@ -407,8 +424,6 @@
 
     @Test
     public void testSettingsProviderUpdate() {
-        ContentResolver resolver = mApplication.getContentResolver();
-
         // Set up channels
         String key = mAssistant.getKey("pkg1", 1, "channel1");
         ChannelImpressions ci = new ChannelImpressions();
@@ -425,23 +440,38 @@
         assertEquals(false, ci.shouldTriggerBlock());
 
         // Update settings values.
-        float newDismissToViewRatioLimit = 0f;
-        int newStreakLimit = 0;
-        Settings.Global.putFloat(resolver,
-                Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT,
-                newDismissToViewRatioLimit);
-        Settings.Global.putInt(resolver,
-                Settings.Global.BLOCKING_HELPER_STREAK_LIMIT, newStreakLimit);
+        mAssistant.mSettings.mDismissToViewRatioLimit = 0f;
+        mAssistant.mSettings.mStreakLimit = 0;
 
         // Notify for the settings values we updated.
-        resolver.notifyChange(
-                Settings.Global.getUriFor(Settings.Global.BLOCKING_HELPER_STREAK_LIMIT), null);
-        resolver.notifyChange(
-                Settings.Global.getUriFor(
-                        Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT),
-                null);
+        mAssistant.mSettings.mOnUpdateRunnable.run();
 
         // With the new threshold, the blocking helper should be triggered.
         assertEquals(true, ci.shouldTriggerBlock());
     }
+
+    @Test
+    public void testTrimLiveNotifications() {
+        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", null);
+        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
+
+        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
+
+        assertTrue(mAssistant.mLiveNotifications.containsKey(sbn.getKey()));
+
+        mAssistant.onNotificationRemoved(
+                sbn, mock(RankingMap.class), new NotificationStats(), 0);
+
+        assertFalse(mAssistant.mLiveNotifications.containsKey(sbn.getKey()));
+    }
+
+    @Test
+    public void testAssistantNeverIncreasesImportanceWhenSuggestingSilent() throws Exception {
+        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C3, "min notif!", null);
+        Adjustment adjust = mAssistant.createEnqueuedNotificationAdjustment(
+                new NotificationEntry(mContext, mPackageManager, sbn, P1C3, mSmsHelper),
+                new ArrayList<>(),
+                new ArrayList<>());
+        assertEquals(IMPORTANCE_MIN, adjust.getSignals().getInt(Adjustment.KEY_IMPORTANCE));
+    }
 }
diff --git a/tests/src/android/ext/services/notification/EntityTypeCounterTest.java b/tests/src/android/ext/services/notification/EntityTypeCounterTest.java
new file mode 100644
index 0000000..ada61d0
--- /dev/null
+++ b/tests/src/android/ext/services/notification/EntityTypeCounterTest.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2018 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 android.ext.services.notification;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.view.textclassifier.TextClassifier;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class EntityTypeCounterTest {
+    private EntityTypeCounter mCounter;
+
+    @Before
+    public void setup() {
+        mCounter = new EntityTypeCounter();
+    }
+
+    @Test
+    public void testIncrementAndGetCount() {
+        mCounter.increment(TextClassifier.TYPE_URL);
+        mCounter.increment(TextClassifier.TYPE_URL);
+        mCounter.increment(TextClassifier.TYPE_URL);
+
+        mCounter.increment(TextClassifier.TYPE_PHONE);
+        mCounter.increment(TextClassifier.TYPE_PHONE);
+
+        assertThat(mCounter.getCount(TextClassifier.TYPE_URL)).isEqualTo(3);
+        assertThat(mCounter.getCount(TextClassifier.TYPE_PHONE)).isEqualTo(2);
+        assertThat(mCounter.getCount(TextClassifier.TYPE_DATE_TIME)).isEqualTo(0);
+    }
+
+    @Test
+    public void testIncrementAndGetCount_typeDateAndDateTime() {
+        mCounter.increment(TextClassifier.TYPE_DATE_TIME);
+        mCounter.increment(TextClassifier.TYPE_DATE);
+
+        assertThat(mCounter.getCount(TextClassifier.TYPE_DATE_TIME)).isEqualTo(2);
+        assertThat(mCounter.getCount(TextClassifier.TYPE_DATE)).isEqualTo(2);
+    }
+}
diff --git a/tests/src/android/ext/services/notification/NotificationCategorizerTest.java b/tests/src/android/ext/services/notification/NotificationCategorizerTest.java
new file mode 100644
index 0000000..ea77d31
--- /dev/null
+++ b/tests/src/android/ext/services/notification/NotificationCategorizerTest.java
@@ -0,0 +1,202 @@
+/**
+ * Copyright (C) 2018 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 android.ext.services.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static android.os.Process.FIRST_APPLICATION_UID;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.os.Process;
+import android.service.notification.StatusBarNotification;
+import android.testing.TestableContext;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class NotificationCategorizerTest {
+    @Mock
+    private NotificationEntry mEntry;
+    @Mock
+    private StatusBarNotification mSbn;
+
+    @Rule
+    public final TestableContext mContext =
+            new TestableContext(InstrumentationRegistry.getContext(), null);
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        when(mEntry.getSbn()).thenReturn(mSbn);
+        when(mSbn.getUid()).thenReturn(Process.myUid());
+        when(mSbn.getPackageName()).thenReturn(mContext.getPackageName());
+    }
+
+    @Test
+    public void testPeopleCategory() {
+        NotificationCategorizer nc = new NotificationCategorizer();
+
+        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
+        when(mEntry.involvesPeople()).thenReturn(true);
+
+        assertEquals(NotificationCategorizer.CATEGORY_PEOPLE, nc.getCategory(mEntry));
+        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_PEOPLE));
+    }
+
+    @Test
+    public void testMin() {
+        NotificationCategorizer nc = new NotificationCategorizer();
+
+        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_MIN));
+        when(mEntry.involvesPeople()).thenReturn(true);
+
+        assertEquals(NotificationCategorizer.CATEGORY_MIN, nc.getCategory(mEntry));
+        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_MIN));
+    }
+
+    @Test
+    public void testHigh() {
+        NotificationCategorizer nc = new NotificationCategorizer();
+
+        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_HIGH));
+
+        assertEquals(NotificationCategorizer.CATEGORY_HIGH, nc.getCategory(mEntry));
+        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_HIGH));
+    }
+
+    @Test
+    public void testOngoingCategory() {
+        NotificationCategorizer nc = new NotificationCategorizer();
+
+        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
+        when(mEntry.isOngoing()).thenReturn(true);
+
+        assertEquals(NotificationCategorizer.CATEGORY_ONGOING, nc.getCategory(mEntry));
+        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_ONGOING));
+
+        when(mEntry.isOngoing()).thenReturn(false);
+        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
+        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE));
+    }
+
+    @Test
+    public void testAlarmCategory() {
+        NotificationCategorizer nc = new NotificationCategorizer();
+
+        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
+        when(mEntry.isCategory(Notification.CATEGORY_ALARM)).thenReturn(true);
+
+        assertEquals(NotificationCategorizer.CATEGORY_ALARM, nc.getCategory(mEntry));
+        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_ALARM));
+
+        when(mEntry.isCategory(Notification.CATEGORY_ALARM)).thenReturn(false);
+        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
+        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE));
+    }
+
+    @Test
+    public void testCallCategory() {
+        NotificationCategorizer nc = new NotificationCategorizer();
+
+        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
+        when(mEntry.isCategory(Notification.CATEGORY_CALL)).thenReturn(true);
+
+        assertEquals(NotificationCategorizer.CATEGORY_CALL, nc.getCategory(mEntry));
+        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_CALL));
+
+        when(mEntry.isCategory(Notification.CATEGORY_CALL)).thenReturn(false);
+        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
+        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE));
+    }
+
+    @Test
+    public void testReminderCategory() {
+        NotificationCategorizer nc = new NotificationCategorizer();
+
+        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
+        when(mEntry.isCategory(Notification.CATEGORY_REMINDER)).thenReturn(true);
+
+        assertEquals(NotificationCategorizer.CATEGORY_REMINDER, nc.getCategory(mEntry));
+        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_REMINDER));
+
+        when(mEntry.isCategory(Notification.CATEGORY_REMINDER)).thenReturn(false);
+        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
+        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE));
+    }
+
+    @Test
+    public void testEventCategory() {
+        NotificationCategorizer nc = new NotificationCategorizer();
+
+        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
+        when(mEntry.isCategory(Notification.CATEGORY_EVENT)).thenReturn(true);
+
+        assertEquals(NotificationCategorizer.CATEGORY_EVENT, nc.getCategory(mEntry));
+        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_EVENT));
+
+        when(mEntry.isCategory(Notification.CATEGORY_EVENT)).thenReturn(false);
+        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
+    }
+
+    @Test
+    public void testSystemCategory() {
+        NotificationCategorizer nc = new NotificationCategorizer();
+
+        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
+        when(mEntry.getImportance()).thenReturn(IMPORTANCE_DEFAULT);
+        when(mSbn.getUid()).thenReturn(FIRST_APPLICATION_UID - 1);
+
+        assertEquals(NotificationCategorizer.CATEGORY_SYSTEM, nc.getCategory(mEntry));
+        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_SYSTEM));
+
+        when(mSbn.getUid()).thenReturn(FIRST_APPLICATION_UID);
+        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
+    }
+
+    @Test
+    public void testSystemLowCategory() {
+        NotificationCategorizer nc = new NotificationCategorizer();
+
+        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_LOW));
+        when(mEntry.getImportance()).thenReturn(IMPORTANCE_LOW);
+        when(mSbn.getUid()).thenReturn(FIRST_APPLICATION_UID - 1);
+
+        assertEquals(NotificationCategorizer.CATEGORY_SYSTEM_LOW, nc.getCategory(mEntry));
+        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_SYSTEM_LOW));
+
+        when(mSbn.getUid()).thenReturn(FIRST_APPLICATION_UID);
+        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
+    }
+}
diff --git a/tests/src/android/ext/services/notification/NotificationEntryTest.java b/tests/src/android/ext/services/notification/NotificationEntryTest.java
new file mode 100644
index 0000000..c026079
--- /dev/null
+++ b/tests/src/android/ext/services/notification/NotificationEntryTest.java
@@ -0,0 +1,266 @@
+/**
+ * Copyright (C) 2018 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 android.ext.services.notification;
+
+import static android.app.Notification.FLAG_CAN_COLORIZE;
+import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.media.AudioAttributes.USAGE_ALARM;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.Person;
+import android.content.ComponentName;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Icon;
+import android.media.AudioAttributes;
+import android.os.Build;
+import android.os.Process;
+import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
+import android.testing.TestableContext;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+@RunWith(AndroidJUnit4.class)
+public class NotificationEntryTest {
+    private String mPkg = "pkg";
+    private int mUid = 2018;
+    @Mock
+    private IPackageManager mPackageManager;
+    @Mock
+    private ApplicationInfo mAppInfo;
+    @Mock
+    private SmsHelper mSmsHelper;
+
+    private static final String DEFAULT_SMS_PACKAGE_NAME = "foo";
+
+    @Rule
+    public final TestableContext mContext =
+            new TestableContext(InstrumentationRegistry.getContext(), null);
+
+    private StatusBarNotification generateSbn(String channelId) {
+        Notification n = new Notification.Builder(mContext, channelId)
+                .setContentTitle("foo")
+                .build();
+
+        return new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, mUid, n,
+                UserHandle.SYSTEM, null, 0);
+    }
+
+    private StatusBarNotification generateSbn(String channelId, String packageName) {
+        Notification n = new Notification.Builder(mContext, channelId)
+                .setContentTitle("foo")
+                .build();
+
+        return new StatusBarNotification(packageName, packageName, 0, "tag", mUid, mUid, n,
+                UserHandle.SYSTEM, null, 0);
+    }
+
+    private StatusBarNotification generateSbn(Notification n) {
+        return new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, mUid, n,
+                UserHandle.SYSTEM, null, 0);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mPkg = mContext.getPackageName();
+        mUid = Process.myUid();
+        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
+                .thenReturn(mAppInfo);
+        mAppInfo.targetSdkVersion = Build.VERSION_CODES.P;
+        when(mSmsHelper.getDefaultSmsApplication())
+                .thenReturn(new ComponentName(DEFAULT_SMS_PACKAGE_NAME, "bar"));
+    }
+
+    @Test
+    public void testHasPerson() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+        StatusBarNotification sbn = generateSbn(channel.getId());
+        ArrayList<Person> people = new ArrayList<>();
+        people.add(new Person.Builder().setKey("mailto:testing@android.com").build());
+        sbn.getNotification().extras.putParcelableArrayList(Notification.EXTRA_PEOPLE_LIST, people);
+
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, sbn, channel, mSmsHelper);
+        assertTrue(entry.involvesPeople());
+    }
+
+    @Test
+    public void testNotPerson() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+        StatusBarNotification sbn = generateSbn(channel.getId());
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, sbn, channel, mSmsHelper);
+        assertFalse(entry.involvesPeople());
+    }
+
+    @Test
+    public void testHasPerson_matchesDefaultSmsApp() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+        StatusBarNotification sbn = generateSbn(channel.getId(), DEFAULT_SMS_PACKAGE_NAME);
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, sbn, channel, mSmsHelper);
+        assertTrue(entry.involvesPeople());
+    }
+
+    @Test
+    public void testHasPerson_doesntMatchDefaultSmsApp() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+        StatusBarNotification sbn = generateSbn(channel.getId(), "abc");
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, sbn, channel, mSmsHelper);
+        assertFalse(entry.involvesPeople());
+    }
+
+    @Test
+    public void testIsInboxStyle() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+
+        Notification n = new Notification.Builder(mContext, channel.getId())
+                .setStyle(new Notification.InboxStyle())
+                .build();
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
+        assertTrue(entry.hasStyle(Notification.InboxStyle.class));
+    }
+
+    @Test
+    public void testIsMessagingStyle() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+
+        Notification n = new Notification.Builder(mContext, channel.getId())
+                .setStyle(new Notification.MessagingStyle(""))
+                .build();
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
+        assertTrue(entry.hasStyle(Notification.MessagingStyle.class));
+    }
+
+    @Test
+    public void testIsNotPersonStyle() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+
+        Notification n = new Notification.Builder(mContext, channel.getId())
+                .setStyle(new Notification.BigPictureStyle())
+                .build();
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
+        assertFalse(entry.hasStyle(Notification.InboxStyle.class));
+        assertFalse(entry.hasStyle(Notification.MessagingStyle.class));
+    }
+
+    @Test
+    public void testIsAudioAttributes() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+        channel.setSound(null, new AudioAttributes.Builder().setUsage(USAGE_ALARM).build());
+
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, generateSbn(channel.getId()), channel, mSmsHelper);
+
+        assertTrue(entry.isAudioAttributesUsage(USAGE_ALARM));
+    }
+
+    @Test
+    public void testIsNotAudioAttributes() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, generateSbn(channel.getId()), channel, mSmsHelper);
+
+        assertFalse(entry.isAudioAttributesUsage(USAGE_ALARM));
+    }
+
+    @Test
+    public void testIsCategory() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+
+        Notification n = new Notification.Builder(mContext, channel.getId())
+                .setCategory(Notification.CATEGORY_EMAIL)
+                .build();
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
+
+        assertTrue(entry.isCategory(Notification.CATEGORY_EMAIL));
+        assertFalse(entry.isCategory(Notification.CATEGORY_MESSAGE));
+    }
+
+    @Test
+    public void testIsOngoing() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+
+        Notification n = new Notification.Builder(mContext, channel.getId())
+                .setFlag(FLAG_FOREGROUND_SERVICE, true)
+                .build();
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
+
+        assertTrue(entry.isOngoing());
+    }
+
+    @Test
+    public void testIsNotOngoing() {
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+
+        Notification n = new Notification.Builder(mContext, channel.getId())
+                .setFlag(FLAG_CAN_COLORIZE, true)
+                .build();
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
+
+        assertFalse(entry.isOngoing());
+    }
+
+    @Test
+    public void testShrinkNotification() {
+        Notification n = new Notification.Builder(mContext, "")
+                .setLargeIcon(Icon.createWithResource(
+                        mContext, android.R.drawable.alert_dark_frame))
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .build();
+        n.largeIcon = Bitmap.createBitmap(100, 200, Bitmap.Config.RGB_565);
+        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+
+        NotificationEntry entry = new NotificationEntry(
+                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
+
+        assertNull(entry.getNotification().getSmallIcon());
+        assertNull(entry.getNotification().getLargeIcon());
+        assertNull(entry.getNotification().largeIcon);
+        assertNull(entry.getNotification().extras.getParcelable(Notification.EXTRA_LARGE_ICON));
+    }
+}
diff --git a/tests/src/android/ext/services/notification/SmartActionsHelperTest.java b/tests/src/android/ext/services/notification/SmartActionsHelperTest.java
new file mode 100644
index 0000000..52b7225
--- /dev/null
+++ b/tests/src/android/ext/services/notification/SmartActionsHelperTest.java
@@ -0,0 +1,566 @@
+/**
+ * Copyright (C) 2018 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 android.ext.services.notification;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.annotation.NonNull;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Person;
+import android.app.RemoteInput;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.IPackageManager;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+import android.os.Process;
+import android.service.notification.NotificationAssistantService;
+import android.service.notification.StatusBarNotification;
+import android.view.textclassifier.ConversationAction;
+import android.view.textclassifier.ConversationActions;
+import android.view.textclassifier.TextClassificationManager;
+import android.view.textclassifier.TextClassifier;
+import android.view.textclassifier.TextClassifierEvent;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.google.common.truth.FailureMetadata;
+import com.google.common.truth.Subject;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+import javax.annotation.Nullable;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+@RunWith(AndroidJUnit4.class)
+public class SmartActionsHelperTest {
+    private static final String RESULT_ID = "id";
+    private static final float SCORE = 0.7f;
+    private static final CharSequence SMART_REPLY = "Home";
+    private static final ConversationAction REPLY_ACTION =
+            new ConversationAction.Builder(ConversationAction.TYPE_TEXT_REPLY)
+                    .setTextReply(SMART_REPLY)
+                    .setConfidenceScore(SCORE)
+                    .build();
+    private static final String MESSAGE = "Where are you?";
+
+    @Mock
+    IPackageManager mIPackageManager;
+    @Mock
+    private TextClassifier mTextClassifier;
+    private StatusBarNotification mStatusBarNotification;
+    @Mock
+    private SmsHelper mSmsHelper;
+
+    private SmartActionsHelper mSmartActionsHelper;
+    private Context mContext;
+    private Notification.Builder mNotificationBuilder;
+    private AssistantSettings mSettings;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mContext = InstrumentationRegistry.getTargetContext();
+
+        mContext.getSystemService(TextClassificationManager.class)
+                .setTextClassifier(mTextClassifier);
+        when(mTextClassifier.suggestConversationActions(any(ConversationActions.Request.class)))
+                .thenReturn(new ConversationActions(Arrays.asList(REPLY_ACTION), RESULT_ID));
+
+        mNotificationBuilder = new Notification.Builder(mContext, "channel");
+        mSettings = AssistantSettings.createForTesting(
+                null, null, Process.myUserHandle().getIdentifier(), null);
+        mSettings.mGenerateActions = true;
+        mSettings.mGenerateReplies = true;
+        mSmartActionsHelper = new SmartActionsHelper(mContext, mSettings);
+    }
+
+    private void setStatusBarNotification(Notification n) {
+        mStatusBarNotification = new StatusBarNotification("random.app", "random.app", 0,
+        "tag", Process.myUid(), Process.myPid(), n, Process.myUserHandle(), null, 0);
+    }
+
+    @Test
+    public void testSuggest_notMessageNotification() {
+        Notification notification = mNotificationBuilder.setContentText(MESSAGE).build();
+        setStatusBarNotification(notification);
+
+        mSmartActionsHelper.suggest(createNotificationEntry());
+
+        verify(mTextClassifier, never())
+                .suggestConversationActions(any(ConversationActions.Request.class));
+    }
+
+    @Test
+    public void testSuggest_noInlineReply() {
+        Notification notification =
+                mNotificationBuilder
+                        .setContentText(MESSAGE)
+                        .setCategory(Notification.CATEGORY_MESSAGE)
+                        .build();
+        setStatusBarNotification(notification);
+
+        ConversationActions.Request request = runSuggestAndCaptureRequest();
+
+        // actions are enabled, but replies are not.
+        assertThat(
+                request.getTypeConfig().resolveEntityListModifications(
+                        Arrays.asList(ConversationAction.TYPE_TEXT_REPLY,
+                                ConversationAction.TYPE_OPEN_URL)))
+                .containsExactly(ConversationAction.TYPE_OPEN_URL);
+    }
+
+    @Test
+    public void testSuggest_settingsOff() {
+        mSettings.mGenerateActions = false;
+        mSettings.mGenerateReplies = false;
+        Notification notification = createMessageNotification();
+        setStatusBarNotification(notification);
+
+        mSmartActionsHelper.suggest(createNotificationEntry());
+
+        verify(mTextClassifier, never())
+                .suggestConversationActions(any(ConversationActions.Request.class));
+    }
+
+    @Test
+    public void testSuggest_settings_repliesOnActionsOff() {
+        mSettings.mGenerateReplies = true;
+        mSettings.mGenerateActions = false;
+        Notification notification = createMessageNotification();
+        setStatusBarNotification(notification);
+
+        ConversationActions.Request request = runSuggestAndCaptureRequest();
+
+        // replies are enabled, but actions are not.
+        assertThat(
+                request.getTypeConfig().resolveEntityListModifications(
+                        Arrays.asList(ConversationAction.TYPE_TEXT_REPLY,
+                                ConversationAction.TYPE_OPEN_URL)))
+                .containsExactly(ConversationAction.TYPE_TEXT_REPLY);
+    }
+
+    @Test
+    public void testSuggest_settings_repliesOffActionsOn() {
+        mSettings.mGenerateReplies = false;
+        mSettings.mGenerateActions = true;
+        Notification notification = createMessageNotification();
+        setStatusBarNotification(notification);
+
+        ConversationActions.Request request = runSuggestAndCaptureRequest();
+
+        // actions are enabled, but replies are not.
+        assertThat(
+                request.getTypeConfig().resolveEntityListModifications(
+                        Arrays.asList(ConversationAction.TYPE_TEXT_REPLY,
+                                ConversationAction.TYPE_OPEN_URL)))
+                .containsExactly(ConversationAction.TYPE_OPEN_URL);
+    }
+
+
+    @Test
+    public void testSuggest_nonMessageStyleMessageNotification() {
+        Notification notification = createMessageNotification();
+        setStatusBarNotification(notification);
+
+        List<ConversationActions.Message> messages =
+                runSuggestAndCaptureRequest().getConversation();
+
+        assertThat(messages).hasSize(1);
+        MessageSubject.assertThat(messages.get(0)).hasText(MESSAGE);
+        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
+                ArgumentCaptor.forClass(TextClassifierEvent.class);
+        verify(mTextClassifier).onTextClassifierEvent(argumentCaptor.capture());
+        TextClassifierEvent textClassifierEvent = argumentCaptor.getValue();
+        assertTextClassifierEvent(textClassifierEvent, TextClassifierEvent.TYPE_ACTIONS_GENERATED);
+        assertThat(textClassifierEvent.getEntityTypes()).asList()
+                .containsExactly(ConversationAction.TYPE_TEXT_REPLY);
+    }
+
+    @Test
+    public void testSuggest_messageStyle() {
+        Person me = new Person.Builder().setName("Me").build();
+        Person userA = new Person.Builder().setName("A").build();
+        Person userB = new Person.Builder().setName("B").build();
+        Notification.MessagingStyle style =
+                new Notification.MessagingStyle(me)
+                        .addMessage("firstMessage", 1000, (Person) null)
+                        .addMessage("secondMessage", 2000, me)
+                        .addMessage("thirdMessage", 3000, userA)
+                        .addMessage("fourthMessage", 4000, userB);
+        Notification notification =
+                mNotificationBuilder
+                        .setContentText("You have three new messages")
+                        .setStyle(style)
+                        .setActions(createReplyAction())
+                        .build();
+        setStatusBarNotification(notification);
+
+        List<ConversationActions.Message> messages =
+                runSuggestAndCaptureRequest().getConversation();
+        assertThat(messages).hasSize(4);
+
+        ConversationActions.Message firstMessage = messages.get(0);
+        MessageSubject.assertThat(firstMessage).hasText("firstMessage");
+        MessageSubject.assertThat(firstMessage)
+                .hasPerson(ConversationActions.Message.PERSON_USER_SELF);
+        MessageSubject.assertThat(firstMessage)
+                .hasReferenceTime(createZonedDateTimeFromMsUtc(1000));
+
+        ConversationActions.Message secondMessage = messages.get(1);
+        MessageSubject.assertThat(secondMessage).hasText("secondMessage");
+        MessageSubject.assertThat(secondMessage)
+                .hasPerson(ConversationActions.Message.PERSON_USER_SELF);
+        MessageSubject.assertThat(secondMessage)
+                .hasReferenceTime(createZonedDateTimeFromMsUtc(2000));
+
+        ConversationActions.Message thirdMessage = messages.get(2);
+        MessageSubject.assertThat(thirdMessage).hasText("thirdMessage");
+        MessageSubject.assertThat(thirdMessage).hasPerson(userA);
+        MessageSubject.assertThat(thirdMessage)
+                .hasReferenceTime(createZonedDateTimeFromMsUtc(3000));
+
+        ConversationActions.Message fourthMessage = messages.get(3);
+        MessageSubject.assertThat(fourthMessage).hasText("fourthMessage");
+        MessageSubject.assertThat(fourthMessage).hasPerson(userB);
+        MessageSubject.assertThat(fourthMessage)
+                .hasReferenceTime(createZonedDateTimeFromMsUtc(4000));
+
+        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
+                ArgumentCaptor.forClass(TextClassifierEvent.class);
+        verify(mTextClassifier).onTextClassifierEvent(argumentCaptor.capture());
+        TextClassifierEvent textClassifierEvent = argumentCaptor.getValue();
+        assertTextClassifierEvent(textClassifierEvent, TextClassifierEvent.TYPE_ACTIONS_GENERATED);
+        assertThat(textClassifierEvent.getEntityTypes()).asList()
+                .containsExactly(ConversationAction.TYPE_TEXT_REPLY);
+    }
+
+    @Test
+    public void testSuggest_lastMessageLocalUser() {
+        Person me = new Person.Builder().setName("Me").build();
+        Person userA = new Person.Builder().setName("A").build();
+        Notification.MessagingStyle style =
+                new Notification.MessagingStyle(me)
+                        .addMessage("firstMessage", 1000, userA)
+                        .addMessage("secondMessage", 2000, me);
+        Notification notification =
+                mNotificationBuilder
+                        .setContentText("You have two new messages")
+                        .setStyle(style)
+                        .setActions(createReplyAction())
+                        .build();
+        setStatusBarNotification(notification);
+
+        mSmartActionsHelper.suggest(createNotificationEntry());
+
+        verify(mTextClassifier, never())
+                .suggestConversationActions(any(ConversationActions.Request.class));
+    }
+
+    @Test
+    public void testSuggest_messageStyle_noPerson() {
+        Person me = new Person.Builder().setName("Me").build();
+        Notification.MessagingStyle style =
+                new Notification.MessagingStyle(me).addMessage("message", 1000, (Person) null);
+        Notification notification =
+                mNotificationBuilder
+                        .setContentText("You have one new message")
+                        .setStyle(style)
+                        .setActions(createReplyAction())
+                        .build();
+        setStatusBarNotification(notification);
+
+        mSmartActionsHelper.suggest(createNotificationEntry());
+
+        verify(mTextClassifier, never())
+                .suggestConversationActions(any(ConversationActions.Request.class));
+    }
+
+    @Test
+    public void testOnSuggestedReplySent() {
+        Notification notification = createMessageNotification();
+        setStatusBarNotification(notification);
+
+        mSmartActionsHelper.suggest(createNotificationEntry());
+        mSmartActionsHelper.onSuggestedReplySent(mStatusBarNotification.getKey(), SMART_REPLY,
+                NotificationAssistantService.SOURCE_FROM_ASSISTANT);
+
+        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
+                ArgumentCaptor.forClass(TextClassifierEvent.class);
+        verify(mTextClassifier, times(2)).onTextClassifierEvent(argumentCaptor.capture());
+        List<TextClassifierEvent> events = argumentCaptor.getAllValues();
+        assertTextClassifierEvent(events.get(0), TextClassifierEvent.TYPE_ACTIONS_GENERATED);
+        assertTextClassifierEvent(events.get(1), TextClassifierEvent.TYPE_SMART_ACTION);
+        float[] scores = events.get(1).getScores();
+        assertThat(scores).hasLength(1);
+        assertThat(scores[0]).isEqualTo(SCORE);
+    }
+
+    @Test
+    public void testOnSuggestedReplySent_anotherNotification() {
+        Notification notification = createMessageNotification();
+        setStatusBarNotification(notification);
+
+        mSmartActionsHelper.suggest(createNotificationEntry());
+        mSmartActionsHelper.onSuggestedReplySent(
+                "something_else", MESSAGE, NotificationAssistantService.SOURCE_FROM_ASSISTANT);
+
+        verify(mTextClassifier, never()).onTextClassifierEvent(
+                argThat(new TextClassifierEventMatcher(TextClassifierEvent.TYPE_SMART_ACTION)));
+    }
+
+    @Test
+    public void testOnSuggestedReplySent_missingResultId() {
+        when(mTextClassifier.suggestConversationActions(any(ConversationActions.Request.class)))
+                .thenReturn(new ConversationActions(Collections.singletonList(REPLY_ACTION), null));
+        Notification notification = createMessageNotification();
+        setStatusBarNotification(notification);
+
+        mSmartActionsHelper.suggest(createNotificationEntry());
+        mSmartActionsHelper.onSuggestedReplySent(mStatusBarNotification.getKey(), SMART_REPLY,
+                NotificationAssistantService.SOURCE_FROM_ASSISTANT);
+
+        verify(mTextClassifier, never()).onTextClassifierEvent(any(TextClassifierEvent.class));
+    }
+
+    @Test
+    public void testOnNotificationDirectReply() {
+        Notification notification = createMessageNotification();
+        setStatusBarNotification(notification);
+
+        mSmartActionsHelper.suggest(createNotificationEntry());
+        mSmartActionsHelper.onNotificationDirectReplied(mStatusBarNotification.getKey());
+
+        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
+                ArgumentCaptor.forClass(TextClassifierEvent.class);
+        verify(mTextClassifier, times(2)).onTextClassifierEvent(argumentCaptor.capture());
+        List<TextClassifierEvent> events = argumentCaptor.getAllValues();
+        assertTextClassifierEvent(events.get(0), TextClassifierEvent.TYPE_ACTIONS_GENERATED);
+        assertTextClassifierEvent(events.get(1), TextClassifierEvent.TYPE_MANUAL_REPLY);
+    }
+
+    @Test
+    public void testOnNotificationExpansionChanged() {
+        Notification notification = createMessageNotification();
+        setStatusBarNotification(notification);
+
+        mSmartActionsHelper.suggest(createNotificationEntry());
+        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true);
+
+        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
+                ArgumentCaptor.forClass(TextClassifierEvent.class);
+        verify(mTextClassifier, times(2)).onTextClassifierEvent(argumentCaptor.capture());
+        List<TextClassifierEvent> events = argumentCaptor.getAllValues();
+        assertTextClassifierEvent(events.get(0), TextClassifierEvent.TYPE_ACTIONS_GENERATED);
+        assertTextClassifierEvent(events.get(1), TextClassifierEvent.TYPE_ACTIONS_SHOWN);
+    }
+
+    @Test
+    public void testOnNotificationsSeen_notExpanded() {
+        Notification notification = createMessageNotification();
+        setStatusBarNotification(notification);
+
+        mSmartActionsHelper.suggest(createNotificationEntry());
+        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), false);
+
+        verify(mTextClassifier, never()).onTextClassifierEvent(
+                argThat(new TextClassifierEventMatcher(TextClassifierEvent.TYPE_ACTIONS_SHOWN)));
+    }
+
+    @Test
+    public void testOnNotifications_expanded() {
+        Notification notification = createMessageNotification();
+        setStatusBarNotification(notification);
+
+        mSmartActionsHelper.suggest(createNotificationEntry());
+        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true);
+
+        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
+                ArgumentCaptor.forClass(TextClassifierEvent.class);
+        verify(mTextClassifier, times(2)).onTextClassifierEvent(argumentCaptor.capture());
+        List<TextClassifierEvent> events = argumentCaptor.getAllValues();
+        assertTextClassifierEvent(events.get(0), TextClassifierEvent.TYPE_ACTIONS_GENERATED);
+        assertTextClassifierEvent(events.get(1), TextClassifierEvent.TYPE_ACTIONS_SHOWN);
+    }
+
+    @Test
+    public void testCopyAction() {
+        Bundle extras = new Bundle();
+        Bundle entitiesExtras = new Bundle();
+        entitiesExtras.putString(SmartActionsHelper.KEY_TEXT, "12345");
+        extras.putParcelable(SmartActionsHelper.ENTITIES_EXTRAS, entitiesExtras);
+        ConversationAction conversationAction =
+                new ConversationAction.Builder(ConversationAction.TYPE_COPY)
+                        .setExtras(extras)
+                        .build();
+        when(mTextClassifier.suggestConversationActions(any(ConversationActions.Request.class)))
+                .thenReturn(
+                        new ConversationActions(
+                                Collections.singletonList(conversationAction), null));
+
+        Notification notification = createMessageNotification();
+        setStatusBarNotification(notification);
+        SmartActionsHelper.SmartSuggestions suggestions =
+                mSmartActionsHelper.suggest(createNotificationEntry());
+
+        assertThat(suggestions.actions).hasSize(1);
+        Notification.Action action = suggestions.actions.get(0);
+        assertThat(action.title).isEqualTo("12345");
+    }
+
+    private ZonedDateTime createZonedDateTimeFromMsUtc(long msUtc) {
+        return ZonedDateTime.ofInstant(Instant.ofEpochMilli(msUtc), ZoneOffset.systemDefault());
+    }
+
+    private ConversationActions.Request runSuggestAndCaptureRequest() {
+        mSmartActionsHelper.suggest(createNotificationEntry());
+
+        ArgumentCaptor<ConversationActions.Request> argumentCaptor =
+                ArgumentCaptor.forClass(ConversationActions.Request.class);
+        verify(mTextClassifier).suggestConversationActions(argumentCaptor.capture());
+        return argumentCaptor.getValue();
+    }
+
+    private Notification.Action createReplyAction() {
+        PendingIntent pendingIntent =
+                PendingIntent.getActivity(mContext, 0, new Intent(mContext, this.getClass()), 0);
+        RemoteInput remoteInput = new RemoteInput.Builder("result")
+                .setAllowFreeFormInput(true)
+                .build();
+        return new Notification.Action.Builder(
+                Icon.createWithResource(mContext.getResources(),
+                        android.R.drawable.stat_sys_warning),
+                "Reply", pendingIntent)
+                .addRemoteInput(remoteInput)
+                .build();
+    }
+
+    private NotificationEntry createNotificationEntry() {
+        NotificationChannel channel =
+                new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
+        return new NotificationEntry(
+                mContext, mIPackageManager, mStatusBarNotification, channel, mSmsHelper);
+    }
+
+    private Notification createMessageNotification() {
+        return mNotificationBuilder
+                .setContentText(MESSAGE)
+                .setCategory(Notification.CATEGORY_MESSAGE)
+                .setActions(createReplyAction())
+                .build();
+    }
+
+    private void assertTextClassifierEvent(
+            TextClassifierEvent textClassifierEvent, int expectedEventType) {
+        assertThat(textClassifierEvent.getEventCategory())
+                .isEqualTo(TextClassifierEvent.CATEGORY_CONVERSATION_ACTIONS);
+        assertThat(textClassifierEvent.getEventContext().getPackageName())
+                .isEqualTo(InstrumentationRegistry.getTargetContext().getPackageName());
+        assertThat(textClassifierEvent.getEventContext().getWidgetType())
+                .isEqualTo(TextClassifier.WIDGET_TYPE_NOTIFICATION);
+        assertThat(textClassifierEvent.getEventType()).isEqualTo(expectedEventType);
+    }
+
+    private static final class MessageSubject
+            extends Subject<MessageSubject, ConversationActions.Message> {
+
+        private static final Subject.Factory<MessageSubject, ConversationActions.Message> FACTORY =
+                new Subject.Factory<MessageSubject, ConversationActions.Message>() {
+                    @Override
+                    public MessageSubject createSubject(
+                            @NonNull FailureMetadata failureMetadata,
+                            @NonNull ConversationActions.Message subject) {
+                        return new MessageSubject(failureMetadata, subject);
+                    }
+                };
+
+        private MessageSubject(
+                FailureMetadata failureMetadata, @Nullable ConversationActions.Message subject) {
+            super(failureMetadata, subject);
+        }
+
+        private void hasText(String text) {
+            if (!Objects.equals(text, getSubject().getText().toString())) {
+                failWithBadResults("has text", text, "has", getSubject().getText());
+            }
+        }
+
+        private void hasPerson(Person person) {
+            if (!Objects.equals(person, getSubject().getAuthor())) {
+                failWithBadResults("has author", person, "has", getSubject().getAuthor());
+            }
+        }
+
+        private void hasReferenceTime(ZonedDateTime referenceTime) {
+            if (!Objects.equals(referenceTime, getSubject().getReferenceTime())) {
+                failWithBadResults(
+                        "has reference time",
+                        referenceTime,
+                        "has",
+                        getSubject().getReferenceTime());
+            }
+        }
+
+        private static MessageSubject assertThat(ConversationActions.Message message) {
+            return assertAbout(FACTORY).that(message);
+        }
+    }
+
+    private final class TextClassifierEventMatcher implements ArgumentMatcher<TextClassifierEvent> {
+
+        private int mType;
+
+        private TextClassifierEventMatcher(int type) {
+            mType = type;
+        }
+
+        @Override
+        public boolean matches(TextClassifierEvent textClassifierEvent) {
+            if (textClassifierEvent == null) {
+                return false;
+            }
+            return mType == textClassifierEvent.getEventType();
+        }
+    }
+}
diff --git a/tests/src/android/ext/services/sms/FinancialSmsServiceImplTest.java b/tests/src/android/ext/services/sms/FinancialSmsServiceImplTest.java
new file mode 100644
index 0000000..12575a6
--- /dev/null
+++ b/tests/src/android/ext/services/sms/FinancialSmsServiceImplTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 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 android.ext.services.sms;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Bundle;
+
+import org.junit.Test;
+
+/**
+ * Contains the base tests for FinancialSmsServiceImpl.
+ */
+public class FinancialSmsServiceImplTest {
+
+    private final FinancialSmsServiceImpl mService = new FinancialSmsServiceImpl();
+
+    @Test
+    public void testOnGetSmsMessages_nullWithNoParamData() {
+        assertThat(mService.onGetSmsMessages(new Bundle())).isNull();
+    }
+}
diff --git a/tests/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImplTest.java b/tests/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImplTest.java
new file mode 100644
index 0000000..a9cb63e
--- /dev/null
+++ b/tests/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImplTest.java
@@ -0,0 +1,201 @@
+/*
+ * 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 android.ext.services.watchdog;
+
+import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_REQUESTED_PACKAGES;
+import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_SUPPORTED_PACKAGES;
+import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
+
+import android.Manifest;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.RemoteCallback;
+import android.service.watchdog.ExplicitHealthCheckService;
+import android.service.watchdog.IExplicitHealthCheckService;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.rule.ServiceTestRule;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Contains the base tests that does not rely on the specific algorithm implementation.
+ */
+public class ExplicitHealthCheckServiceImplTest {
+    private static final String NETWORK_STACK_CONNECTOR_CLASS =
+            "android.net.INetworkStackConnector";
+
+    private final Context mContext = InstrumentationRegistry.getContext();
+    private IExplicitHealthCheckService mService;
+    private String mNetworkStackPackageName;
+
+    @Rule
+    public ServiceTestRule mServiceTestRule;
+
+    @Before
+    public void setUp() throws Exception {
+        InstrumentationRegistry
+                .getInstrumentation()
+                .getUiAutomation()
+                .adoptShellPermissionIdentity(
+                        Manifest.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE);
+
+        mServiceTestRule = new ServiceTestRule();
+        mService = IExplicitHealthCheckService.Stub.asInterface(
+                mServiceTestRule.bindService(getExtServiceIntent()));
+        mNetworkStackPackageName = getNetworkStackPackage();
+        assumeFalse(mNetworkStackPackageName == null);
+    }
+
+    @After
+    public void tearDown() {
+        InstrumentationRegistry
+                .getInstrumentation()
+                .getUiAutomation()
+                .dropShellPermissionIdentity();
+    }
+
+    @Test
+    public void testHealthCheckSupportedPackage() throws Exception {
+        List<PackageConfig> supportedPackages = new ArrayList<>();
+        CountDownLatch latch = new CountDownLatch(1);
+
+        mService.getSupportedPackages(new RemoteCallback(result -> {
+            supportedPackages.addAll(result.getParcelableArrayList(EXTRA_SUPPORTED_PACKAGES));
+            latch.countDown();
+        }));
+        latch.await();
+
+        // TODO: Support DeviceConfig changes for the health check timeout
+        assertThat(supportedPackages).hasSize(1);
+        assertThat(supportedPackages.get(0).getPackageName())
+                .isEqualTo(mNetworkStackPackageName);
+        assertThat(supportedPackages.get(0).getHealthCheckTimeoutMillis())
+                .isEqualTo(ExplicitHealthCheckServiceImpl.DEFAULT_REQUEST_TIMEOUT_MILLIS);
+    }
+
+    @Test
+    public void testHealthCheckRequests() throws Exception {
+        List<String> requestedPackages = new ArrayList<>();
+        CountDownLatch latch1 = new CountDownLatch(1);
+        CountDownLatch latch2 = new CountDownLatch(1);
+        CountDownLatch latch3 = new CountDownLatch(1);
+
+        // Initially, no health checks requested
+        mService.getRequestedPackages(new RemoteCallback(result -> {
+            requestedPackages.addAll(result.getParcelableArrayList(EXTRA_REQUESTED_PACKAGES));
+            latch1.countDown();
+        }));
+
+        // Verify that no health checks requested
+        latch1.await();
+        assertThat(requestedPackages).isEmpty();
+
+        // Then request health check
+        mService.request(mNetworkStackPackageName);
+
+        // Verify that health check is requested for network stack
+        mService.getRequestedPackages(new RemoteCallback(result -> {
+            requestedPackages.addAll(result.getParcelableArrayList(EXTRA_REQUESTED_PACKAGES));
+            latch2.countDown();
+        }));
+        latch2.await();
+        assertThat(requestedPackages).hasSize(1);
+        assertThat(requestedPackages.get(0)).isEqualTo(mNetworkStackPackageName);
+
+        // Then cancel health check
+        requestedPackages.clear();
+        mService.cancel(mNetworkStackPackageName);
+
+        // Verify that health check is cancelled for network stack
+        mService.getRequestedPackages(new RemoteCallback(result -> {
+            requestedPackages.addAll(result.getParcelableArrayList(EXTRA_REQUESTED_PACKAGES));
+            latch3.countDown();
+        }));
+        latch3.await();
+        assertThat(requestedPackages).isEmpty();
+    }
+
+    private String getNetworkStackPackage() {
+        Intent intent = new Intent(NETWORK_STACK_CONNECTOR_CLASS);
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        if (comp != null) {
+            return comp.getPackageName();
+        } else {
+            // On Go devices, or any device that does not ship the network stack module.
+            // The network stack will live in system_server process, so no need to monitor.
+            return null;
+        }
+    }
+
+    private Intent getExtServiceIntent() {
+        ComponentName component = getExtServiceComponentNameLocked();
+        if (component == null) {
+            fail("Health check service not found");
+        }
+        Intent intent = new Intent();
+        intent.setComponent(component);
+        return intent;
+    }
+
+    private ComponentName getExtServiceComponentNameLocked() {
+        ServiceInfo serviceInfo = getExtServiceInfoLocked();
+        if (serviceInfo == null) {
+            return null;
+        }
+
+        final ComponentName name = new ComponentName(serviceInfo.packageName, serviceInfo.name);
+        if (!Manifest.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE
+                .equals(serviceInfo.permission)) {
+            return null;
+        }
+        return name;
+    }
+
+    private ServiceInfo getExtServiceInfoLocked() {
+        final String packageName =
+                mContext.getPackageManager().getServicesSystemSharedLibraryPackageName();
+        if (packageName == null) {
+            return null;
+        }
+
+        final Intent intent = new Intent(ExplicitHealthCheckService.SERVICE_INTERFACE);
+        intent.setPackage(packageName);
+        final ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent,
+                PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
+        if (resolveInfo == null || resolveInfo.serviceInfo == null) {
+            return null;
+        }
+        return resolveInfo.serviceInfo;
+    }
+}
