Fix DND crash from SpringboardActivity

Special case Uris need to explicitly add their intents.
This unfortunately duplicates a list of special-cased Slices,
but I have attached a bug with a plan to address this duplicity in Q.

Change-Id: I346915c32543713d33716422018d7c950cce323d
Fixes: 80065409
Test: atest SliceDeepLinkSpringBoardTest
diff --git a/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java b/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
index da759a3..a8bb1ca 100644
--- a/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
+++ b/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
@@ -100,6 +100,17 @@
                 .build();
     }
 
+    public static Intent getIntent(Context context) {
+        final String screenTitle = context.getText(R.string.bluetooth_settings_title).toString();
+        final Uri contentUri = new Uri.Builder().appendPath(
+                SettingsSlicesContract.KEY_BLUETOOTH).build();
+        return DatabaseIndexingUtils.buildSearchResultPageIntent(context,
+                BluetoothDashboardFragment.class.getName(), null /* key */, screenTitle,
+                MetricsProto.MetricsEvent.SETTINGS_CONNECTED_DEVICE_CATEGORY)
+                .setClassName(context.getPackageName(), SubSettings.class.getName())
+                .setData(contentUri);
+    }
+
     /**
      * Update the current Bluetooth status to the boolean value keyed by
      * {@link android.app.slice.Slice#EXTRA_TOGGLE_STATE} on {@param intent}.
@@ -122,15 +133,7 @@
     }
 
     private static PendingIntent getPrimaryAction(Context context) {
-        final String screenTitle = context.getText(R.string.bluetooth_settings_title).toString();
-        final Uri contentUri = new Uri.Builder().appendPath(
-                SettingsSlicesContract.KEY_BLUETOOTH).build();
-        final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
-                BluetoothDashboardFragment.class.getName(), null /* key */, screenTitle,
-                MetricsProto.MetricsEvent.SETTINGS_CONNECTED_DEVICE_CATEGORY)
-                .setClassName(context.getPackageName(), SubSettings.class.getName())
-                .setData(contentUri);
-
+        final Intent intent = getIntent(context);
         return PendingIntent.getActivity(context, 0 /* requestCode */,
                 intent, 0 /* flags */);
     }
diff --git a/src/com/android/settings/location/LocationSliceBuilder.java b/src/com/android/settings/location/LocationSliceBuilder.java
index e69ccfb..4cf861f 100644
--- a/src/com/android/settings/location/LocationSliceBuilder.java
+++ b/src/com/android/settings/location/LocationSliceBuilder.java
@@ -79,15 +79,18 @@
                 .build();
     }
 
-    private static PendingIntent getPrimaryAction(Context context) {
+    public static Intent getIntent(Context context) {
         final String screenTitle = context.getText(R.string.location_settings_title).toString();
         final Uri contentUri = new Uri.Builder().appendPath(KEY_LOCATION).build();
-        final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
+        return DatabaseIndexingUtils.buildSearchResultPageIntent(context,
                 LocationSettings.class.getName(), KEY_LOCATION, screenTitle,
                 MetricsEvent.LOCATION)
                 .setClassName(context.getPackageName(), SubSettings.class.getName())
                 .setData(contentUri);
+    }
 
+    private static PendingIntent getPrimaryAction(Context context) {
+        final Intent intent = getIntent(context);
         return PendingIntent.getActivity(context, 0 /* requestCode */,
                 intent, 0 /* flags */);
     }
diff --git a/src/com/android/settings/notification/ZenModeSliceBuilder.java b/src/com/android/settings/notification/ZenModeSliceBuilder.java
index aedd0b3..16591ce 100644
--- a/src/com/android/settings/notification/ZenModeSliceBuilder.java
+++ b/src/com/android/settings/notification/ZenModeSliceBuilder.java
@@ -123,6 +123,16 @@
         // handle it.
     }
 
+    public static Intent getIntent(Context context) {
+        final Uri contentUri = new Uri.Builder().appendPath(ZEN_MODE_KEY).build();
+        final String screenTitle = context.getText(R.string.zen_mode_settings_title).toString();
+        return DatabaseIndexingUtils.buildSearchResultPageIntent(context,
+                ZenModeSettings.class.getName(), ZEN_MODE_KEY, screenTitle,
+                MetricsEvent.NOTIFICATION_ZEN_MODE)
+                .setClassName(context.getPackageName(), SubSettings.class.getName())
+                .setData(contentUri);
+    }
+
     private static boolean isZenModeEnabled(Context context) {
         final NotificationManager manager = context.getSystemService(NotificationManager.class);
         final int zenMode = manager.getZenMode();
@@ -139,16 +149,8 @@
     }
 
     private static PendingIntent getPrimaryAction(Context context) {
-        final String screenTitle = context.getText(R.string.zen_mode_settings_title).toString();
-        final Uri contentUri = new Uri.Builder().appendPath(ZEN_MODE_KEY).build();
-        final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
-                ZenModeSettings.class.getName(), ZEN_MODE_KEY, screenTitle,
-                MetricsEvent.NOTIFICATION_ZEN_MODE)
-                .setClassName(context.getPackageName(), SubSettings.class.getName())
-                .setData(contentUri);
-
-        return PendingIntent.getActivity(context, 0 /* requestCode */,
-                intent, 0 /* flags */);
+        final Intent intent = getIntent(context);
+        return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */);
     }
 
     private static PendingIntent getBroadcastIntent(Context context) {
diff --git a/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java b/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java
index 7f1a0f3..4f8ed96 100644
--- a/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java
+++ b/src/com/android/settings/slices/SliceDeepLinkSpringBoard.java
@@ -18,8 +18,16 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
+import android.provider.Settings;
 import android.util.Log;
 
+import com.android.settings.bluetooth.BluetoothSliceBuilder;
+import com.android.settings.location.LocationSliceBuilder;
+import com.android.settings.notification.ZenModeSliceBuilder;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.wifi.WifiSliceBuilder;
+import com.android.settings.wifi.calling.WifiCallingSliceHelper;
+
 import java.net.URISyntaxException;
 
 public class SliceDeepLinkSpringBoard extends Activity {
@@ -44,11 +52,26 @@
             if (ACTION_VIEW_SLICE.equals(intent.getAction())) {
                 // This shouldn't matter since the slice is shown instead of the device
                 // index caring about the launch uri.
-                Uri slice = Uri.parse(intent.getStringExtra(EXTRA_SLICE));
-                SlicesDatabaseAccessor slicesDatabaseAccessor = new SlicesDatabaseAccessor(this);
-                // Sadly have to block here because we don't know where to go.
-                final SliceData sliceData = slicesDatabaseAccessor.getSliceDataFromUri(slice);
-                Intent launchIntent = SliceBuilderUtils.getContentIntent(this, sliceData);
+                final Uri slice = Uri.parse(intent.getStringExtra(EXTRA_SLICE));
+                final Intent launchIntent;
+
+                // TODO (b/80263568) Avoid duplicating this list of Slice Uris.
+                if (WifiSliceBuilder.WIFI_URI.equals(slice)) {
+                    launchIntent = WifiSliceBuilder.getIntent(this /* context */);
+                } else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(slice)) {
+                    launchIntent = ZenModeSliceBuilder.getIntent(this /* context */);
+                } else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(slice)) {
+                    launchIntent = BluetoothSliceBuilder.getIntent(this /* context */);
+                } else if (LocationSliceBuilder.LOCATION_URI.equals(slice)) {
+                    launchIntent = LocationSliceBuilder.getIntent(this /* context */);
+                } else {
+                    final SlicesDatabaseAccessor slicesDatabaseAccessor =
+                            new SlicesDatabaseAccessor(this /* context */);
+                    // Sadly have to block here because we don't know where to go.
+                    final SliceData sliceData = slicesDatabaseAccessor.getSliceDataFromUri(slice);
+                    launchIntent = SliceBuilderUtils.getContentIntent(this, sliceData);
+                }
+
                 startActivity(launchIntent);
             } else {
                 startActivity(intent);
@@ -57,6 +80,10 @@
         } catch (URISyntaxException e) {
             Log.e(TAG, "Error decoding uri", e);
             finish();
+        } catch (IllegalStateException e) {
+            Log.w(TAG, "Couldn't launch Slice intent", e);
+            startActivity(new Intent(Settings.ACTION_SETTINGS));
+            finish();
         }
     }
 
diff --git a/src/com/android/settings/wifi/WifiSliceBuilder.java b/src/com/android/settings/wifi/WifiSliceBuilder.java
index 7df7f19..21a9455 100644
--- a/src/com/android/settings/wifi/WifiSliceBuilder.java
+++ b/src/com/android/settings/wifi/WifiSliceBuilder.java
@@ -121,6 +121,18 @@
         // handle it.
     }
 
+    public static Intent getIntent(Context context) {
+        final String screenTitle = context.getText(R.string.wifi_settings).toString();
+        final Uri contentUri = new Uri.Builder().appendPath(KEY_WIFI).build();
+        final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
+                WifiSettings.class.getName(), KEY_WIFI, screenTitle,
+                MetricsEvent.DIALOG_WIFI_AP_EDIT)
+                .setClassName(context.getPackageName(), SubSettings.class.getName())
+                .setData(contentUri);
+
+        return intent;
+    }
+
     private static boolean isWifiEnabled(Context context) {
         final WifiManager wifiManager = context.getSystemService(WifiManager.class);
 
@@ -159,14 +171,7 @@
     }
 
     private static PendingIntent getPrimaryAction(Context context) {
-        final String screenTitle = context.getText(R.string.wifi_settings).toString();
-        final Uri contentUri = new Uri.Builder().appendPath(KEY_WIFI).build();
-        final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
-                WifiSettings.class.getName(), KEY_WIFI, screenTitle,
-                MetricsEvent.DIALOG_WIFI_AP_EDIT);
-        intent.setClassName(context.getPackageName(), SubSettings.class.getName());
-        intent.setData(contentUri);
-
+        final Intent intent = getIntent(context);
         return PendingIntent.getActivity(context, 0 /* requestCode */,
                 intent, 0 /* flags */);
     }
diff --git a/tests/unit/src/com/android/settings/slices/SliceDeepLinkSpringBoardTest.java b/tests/unit/src/com/android/settings/slices/SliceDeepLinkSpringBoardTest.java
index e7c5d6e..91057b8 100644
--- a/tests/unit/src/com/android/settings/slices/SliceDeepLinkSpringBoardTest.java
+++ b/tests/unit/src/com/android/settings/slices/SliceDeepLinkSpringBoardTest.java
@@ -21,14 +21,22 @@
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
+import android.platform.test.annotations.Presubmit;
 import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 
+import com.android.settings.bluetooth.BluetoothSliceBuilder;
+import com.android.settings.location.LocationSliceBuilder;
+import com.android.settings.notification.ZenModeSliceBuilder;
+import com.android.settings.wifi.WifiSliceBuilder;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
+@MediumTest
 public class SliceDeepLinkSpringBoardTest {
     private Context mContext;
 
@@ -38,18 +46,57 @@
     }
 
     @Test
-    public void launcheDeepLinkIntent_shouldNotCrash() {
-        final Uri springBoardIntentUri = createDeepLink(
-                new Intent(SliceDeepLinkSpringBoard.ACTION_VIEW_SLICE)
-                        .setPackage(mContext.getPackageName())
-                        .putExtra(SliceDeepLinkSpringBoard.EXTRA_SLICE,
-                                "content://com.android.settings.slices/action/test_slice")
-                        .toUri(Intent.URI_ANDROID_APP_SCHEME));
-
-        final Intent deepLinkIntent = new Intent(Intent.ACTION_VIEW)
-                .setData(springBoardIntentUri)
-                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+    @Presubmit
+    public void launchesDeepLinkIntent_shouldNotCrash() {
+        final Intent deepLinkIntent = getSpringboardIntent(
+                "content://com.android.settings.slices/action/test_slice");
 
         mContext.startActivity(deepLinkIntent);
     }
+
+    @Test
+    @Presubmit
+    public void launchesDeepLinkIntent_wifiSlice_shouldNotCrash() {
+        final Intent deepLinkIntent = getSpringboardIntent(WifiSliceBuilder.WIFI_URI.toString());
+
+        mContext.startActivity(deepLinkIntent);
+    }
+
+    @Test
+    @Presubmit
+    public void launchesDeepLinkIntent_bluetoothSlice_shouldNotCrash() {
+        final Intent deepLinkIntent = getSpringboardIntent(
+                BluetoothSliceBuilder.BLUETOOTH_URI.toString());
+
+        mContext.startActivity(deepLinkIntent);
+    }
+
+    @Test
+    @Presubmit
+    public void launchesDeepLinkIntent_dndSlice_shouldNotCrash() {
+        final Intent deepLinkIntent = getSpringboardIntent(
+                ZenModeSliceBuilder.ZEN_MODE_URI.toString());
+
+        mContext.startActivity(deepLinkIntent);
+    }
+
+    @Test
+    @Presubmit
+    public void launchesDeepLinkIntent_locationSlice_shouldNotCrash() {
+        final Intent deepLinkIntent = getSpringboardIntent(
+                LocationSliceBuilder.LOCATION_URI.toString());
+
+        mContext.startActivity(deepLinkIntent);
+    }
+
+    private Intent getSpringboardIntent(String uriString) {
+        final Uri uri = createDeepLink(new Intent(SliceDeepLinkSpringBoard.ACTION_VIEW_SLICE)
+                .setPackage(mContext.getPackageName())
+                .putExtra(SliceDeepLinkSpringBoard.EXTRA_SLICE, uriString)
+                .toUri(Intent.URI_ANDROID_APP_SCHEME));
+
+        return new Intent(Intent.ACTION_VIEW)
+                .setData(uri)
+                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+    }
 }