Resolve API feedback and remove references to SliceStore

Rename PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_DEFAULT_DATA to
PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_DEFAULT_DATA_SUB

Split KEY_PREMIUM_CAPABILITY_MAXIMUM_NOTIFICATION_COUNT_INT_ARRAY
into KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT
and KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT

Rename SliceStore to SlicePurchaseController. Remove all references to
SliceStore.

Test: atest TelephonyManagerReadNonDangerousPermissionTest
Test: manually verify premium capability purchase behavior
Bug: 255552152
Change-Id: I653db7566c91942faadcec24fb7bb340236ebdc0
diff --git a/core/api/current.txt b/core/api/current.txt
index 3174c28..98d87de 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -41783,7 +41783,8 @@
     field public static final String KEY_OPPORTUNISTIC_NETWORK_PING_PONG_TIME_LONG = "opportunistic_network_ping_pong_time_long";
     field public static final String KEY_PING_TEST_BEFORE_DATA_SWITCH_BOOL = "ping_test_before_data_switch_bool";
     field public static final String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
-    field public static final String KEY_PREMIUM_CAPABILITY_MAXIMUM_NOTIFICATION_COUNT_INT_ARRAY = "premium_capability_maximum_notification_count_int_array";
+    field public static final String KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT = "premium_capability_maximum_daily_notification_count_int";
+    field public static final String KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT = "premium_capability_maximum_monthly_notification_count_int";
     field public static final String KEY_PREMIUM_CAPABILITY_NETWORK_SETUP_TIME_MILLIS_LONG = "premium_capability_network_setup_time_millis_long";
     field public static final String KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG = "premium_capability_notification_backoff_hysteresis_time_millis_long";
     field public static final String KEY_PREMIUM_CAPABILITY_NOTIFICATION_DISPLAY_TIMEOUT_MILLIS_LONG = "premium_capability_notification_display_timeout_millis_long";
@@ -44090,7 +44091,7 @@
     field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_FEATURE_NOT_SUPPORTED = 10; // 0xa
     field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_CONGESTED = 13; // 0xd
     field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_NOT_AVAILABLE = 12; // 0xc
-    field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_DEFAULT_DATA = 14; // 0xe
+    field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_DEFAULT_DATA_SUB = 14; // 0xe
     field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_OVERRIDDEN = 5; // 0x5
     field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_PENDING_NETWORK_SETUP = 15; // 0xf
     field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_REQUEST_FAILED = 11; // 0xb
diff --git a/packages/CarrierDefaultApp/Android.bp b/packages/CarrierDefaultApp/Android.bp
index 62ffe38..a216381 100644
--- a/packages/CarrierDefaultApp/Android.bp
+++ b/packages/CarrierDefaultApp/Android.bp
@@ -10,7 +10,7 @@
 android_app {
     name: "CarrierDefaultApp",
     srcs: ["src/**/*.java"],
-    libs: ["SliceStore"],
+    libs: ["SlicePurchaseController"],
     platform_apis: true,
     certificate: "platform",
     optimize: {
diff --git a/packages/CarrierDefaultApp/AndroidManifest.xml b/packages/CarrierDefaultApp/AndroidManifest.xml
index a5b104b..4c22ee6 100644
--- a/packages/CarrierDefaultApp/AndroidManifest.xml
+++ b/packages/CarrierDefaultApp/AndroidManifest.xml
@@ -73,16 +73,16 @@
             </intent-filter>
         </activity-alias>
 
-        <receiver android:name="com.android.carrierdefaultapp.SliceStoreBroadcastReceiver"
+        <receiver android:name="com.android.carrierdefaultapp.SlicePurchaseBroadcastReceiver"
                   android:exported="true">
             <intent-filter>
-                <action android:name="com.android.phone.slicestore.action.START_SLICE_STORE" />
-                <action android:name="com.android.phone.slicestore.action.SLICE_STORE_RESPONSE_TIMEOUT" />
-                <action android:name="com.android.phone.slicestore.action.NOTIFICATION_CANCELED" />
+                <action android:name="com.android.phone.slice.action.START_SLICE_PURCHASE_APP" />
+                <action android:name="com.android.phone.slice.action.SLICE_PURCHASE_APP_RESPONSE_TIMEOUT" />
+                <action android:name="com.android.phone.slice.action.NOTIFICATION_CANCELED" />
             </intent-filter>
         </receiver>
-        <activity android:name="com.android.carrierdefaultapp.SliceStoreActivity"
-                  android:label="@string/slice_store_label"
+        <activity android:name="com.android.carrierdefaultapp.SlicePurchaseActivity"
+                  android:label="@string/slice_purchase_app_label"
                   android:exported="true"
                   android:configChanges="keyboardHidden|orientation|screenSize">
             <intent-filter>
diff --git a/packages/CarrierDefaultApp/assets/slice_store_test.html b/packages/CarrierDefaultApp/assets/slice_purchase_test.html
similarity index 86%
rename from packages/CarrierDefaultApp/assets/slice_store_test.html
rename to packages/CarrierDefaultApp/assets/slice_purchase_test.html
index 7ddbd2d..67d2184 100644
--- a/packages/CarrierDefaultApp/assets/slice_store_test.html
+++ b/packages/CarrierDefaultApp/assets/slice_purchase_test.html
@@ -20,7 +20,8 @@
     <meta charset="UTF-8">
     <meta name="description" content="
     This is a HTML page that calls and verifies responses from the @JavascriptInterface functions of
-    SliceStoreWebInterface. Test SliceStore APIs using ADB shell commands and the APIs below:
+    SlicePurchaseWebInterface. Test slice purchase application behavior using ADB shell commands and
+    the APIs below:
 
     FROM TERMINAL:
     Allow device to override carrier configs:
@@ -29,7 +30,7 @@
     $ adb shell cmd phone cc set-value -p supported_premium_capabilities_int_array 34
     Set the carrier purchase URL to this test HTML file:
     $ adb shell cmd phone cc set-value -p premium_capability_purchase_url_string \
-      file:///android_asset/slice_store_test.html
+      file:///android_asset/slice_purchase_test.html
     OPTIONAL: Allow premium capability purchase on LTE:
     $ adb shell cmd phone cc set-value -p premium_capability_supported_on_lte_bool true
     OPTIONAL: Override ServiceState to fake a NR SA connection:
@@ -43,7 +44,7 @@
             this.getMainExecutor(), request::offer);
 
     When the test application starts, this HTML will be loaded into the WebView along with the
-    associated JavaScript functions in file:///android_asset/slice_store_test.js.
+    associated JavaScript functions in file:///android_asset/slice_purchase_test.js.
     Click on the buttons in the HTML to call the corresponding @JavascriptInterface APIs.
 
     RESET DEVICE STATE:
@@ -52,11 +53,11 @@
     Clear ServiceState override that was set:
     $ adb shell am broadcast -a com.android.internal.telephony.TestServiceState --es action reset
     ">
-    <title>Test SliceStoreActivity</title>
-    <script type="text/javascript" src="slice_store_test.js"></script>
+    <title>Test SlicePurchaseActivity</title>
+    <script type="text/javascript" src="slice_purchase_test.js"></script>
 </head>
 <body>
-    <h1>Test SliceStoreActivity</h1>
+    <h1>Test SlicePurchaseActivity</h1>
     <h2>Get requested premium capability</h2>
     <button type="button" onclick="testGetRequestedCapability()">
         Get requested premium capability
@@ -70,7 +71,7 @@
     <p id="purchase_successful"></p>
 
     <h2>Notify purchase failed</h2>
-    <button type="button" onclick="testNotifyPurchaseFailed()">
+    <button type="button" onclick="testNotifyPurchaseFailed(2, 'FAILURE_CODE_SERVER_UNREACHABLE')">
         Notify purchase failed
     </button>
     <p id="purchase_failed"></p>
diff --git a/packages/CarrierDefaultApp/assets/slice_store_test.js b/packages/CarrierDefaultApp/assets/slice_purchase_test.js
similarity index 76%
rename from packages/CarrierDefaultApp/assets/slice_store_test.js
rename to packages/CarrierDefaultApp/assets/slice_purchase_test.js
index f12a6da..02c4fea 100644
--- a/packages/CarrierDefaultApp/assets/slice_store_test.js
+++ b/packages/CarrierDefaultApp/assets/slice_purchase_test.js
@@ -15,19 +15,19 @@
  */
 
 function testGetRequestedCapability() {
-    let capability = SliceStoreWebInterface.getRequestedCapability();
+    let capability = SlicePurchaseWebInterface.getRequestedCapability();
     document.getElementById("requested_capability").innerHTML =
             "Premium capability requested: " + capability;
 }
 
 function testNotifyPurchaseSuccessful(duration_ms_long = 0) {
-    SliceStoreWebInterface.notifyPurchaseSuccessful(duration);
+    SlicePurchaseWebInterface.notifyPurchaseSuccessful(duration_ms_long);
     document.getElementById("purchase_successful").innerHTML =
-            "Notified purchase success for duration: " + duration;
+            "Notified purchase success for duration: " + duration_ms_long;
 }
 
-function testNotifyPurchaseFailed() {
-    SliceStoreWebInterface.notifyPurchaseFailed();
+function testNotifyPurchaseFailed(failure_code = 0, failure_reason = "unknown") {
+    SlicePurchaseWebInterface.notifyPurchaseFailed(failure_code, failure_reason);
     document.getElementById("purchase_failed").innerHTML =
             "Notified purchase failed.";
 }
diff --git a/packages/CarrierDefaultApp/res/values/strings.xml b/packages/CarrierDefaultApp/res/values/strings.xml
index ce88a40..8a19709 100644
--- a/packages/CarrierDefaultApp/res/values/strings.xml
+++ b/packages/CarrierDefaultApp/res/values/strings.xml
@@ -25,6 +25,6 @@
     <!-- Notification button text to manage the network boost notification. -->
     <string name="network_boost_notification_button_manage">Manage</string>
 
-    <!-- Label to display when the slice store opens. -->
-    <string name="slice_store_label">Purchase a network boost.</string>
+    <!-- Label to display when the slice purchase application opens. -->
+    <string name="slice_purchase_app_label">Purchase a network boost.</string>
 </resources>
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java
new file mode 100644
index 0000000..e67ea7e
--- /dev/null
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2022 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 com.android.carrierdefaultapp;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.webkit.WebView;
+
+import com.android.phone.slice.SlicePurchaseController;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Activity that launches when the user clicks on the network boost notification.
+ * This will open a {@link WebView} for the carrier website to allow the user to complete the
+ * premium capability purchase.
+ * The carrier website can get the requested premium capability using the JavaScript interface
+ * method {@code SlicePurchaseWebInterface.getRequestedCapability()}.
+ * If the purchase is successful, the carrier website shall notify the slice purchase application
+ * using the JavaScript interface method
+ * {@code SlicePurchaseWebInterface.notifyPurchaseSuccessful(duration)}, where {@code duration} is
+ * the optional duration of the network boost.
+ * If the purchase was not successful, the carrier website shall notify the slice purchase
+ * application using the JavaScript interface method
+ * {@code SlicePurchaseWebInterface.notifyPurchaseFailed(code, reason)}, where {@code code} is the
+ * {@link SlicePurchaseController.FailureCode} indicating the reason for failure and {@code reason}
+ * is the human-readable reason for failure if the failure code is
+ * {@link SlicePurchaseController#FAILURE_CODE_UNKNOWN}.
+ * If either of these notification methods are not called, the purchase cannot be completed
+ * successfully and the purchase request will eventually time out.
+ */
+public class SlicePurchaseActivity extends Activity {
+    private static final String TAG = "SlicePurchaseActivity";
+
+    private @NonNull WebView mWebView;
+    private @NonNull Context mApplicationContext;
+    private int mSubId;
+    @TelephonyManager.PremiumCapability protected int mCapability;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent intent = getIntent();
+        mSubId = intent.getIntExtra(SlicePurchaseController.EXTRA_SUB_ID,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        mCapability = intent.getIntExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
+                SlicePurchaseController.PREMIUM_CAPABILITY_INVALID);
+        mApplicationContext = getApplicationContext();
+        URL url = getUrl();
+        logd("onCreate: subId=" + mSubId + ", capability="
+                + TelephonyManager.convertPremiumCapabilityToString(mCapability)
+                + ", url=" + url);
+
+        // Cancel network boost notification
+        mApplicationContext.getSystemService(NotificationManager.class)
+                .cancel(SlicePurchaseBroadcastReceiver.NETWORK_BOOST_NOTIFICATION_TAG, mCapability);
+
+        // Verify intent and values are valid
+        if (!SlicePurchaseBroadcastReceiver.isIntentValid(intent)) {
+            loge("Not starting SlicePurchaseActivity with an invalid Intent: " + intent);
+            SlicePurchaseBroadcastReceiver.sendSlicePurchaseAppResponse(
+                    intent, SlicePurchaseController.EXTRA_INTENT_REQUEST_FAILED);
+            finishAndRemoveTask();
+            return;
+        }
+        if (url == null) {
+            String error = "Unable to create a URL from carrier configs.";
+            loge(error);
+            Intent data = new Intent();
+            data.putExtra(SlicePurchaseController.EXTRA_FAILURE_CODE,
+                    SlicePurchaseController.FAILURE_CODE_CARRIER_URL_UNAVAILABLE);
+            data.putExtra(SlicePurchaseController.EXTRA_FAILURE_REASON, error);
+            SlicePurchaseBroadcastReceiver.sendSlicePurchaseAppResponseWithData(mApplicationContext,
+                    getIntent(), SlicePurchaseController.EXTRA_INTENT_CARRIER_ERROR, data);
+            finishAndRemoveTask();
+            return;
+        }
+        if (mSubId != SubscriptionManager.getDefaultSubscriptionId()) {
+            loge("Unable to start the slice purchase application on the non-default data "
+                    + "subscription: " + mSubId);
+            SlicePurchaseBroadcastReceiver.sendSlicePurchaseAppResponse(
+                    intent, SlicePurchaseController.EXTRA_INTENT_NOT_DEFAULT_DATA_SUB);
+            finishAndRemoveTask();
+            return;
+        }
+
+        // Create a reference to this activity in SlicePurchaseBroadcastReceiver
+        SlicePurchaseBroadcastReceiver.updateSlicePurchaseActivity(mCapability, this);
+
+        // Create and configure WebView
+        mWebView = new WebView(this);
+        // Enable JavaScript for the carrier purchase website to send results back to
+        //  the slice purchase application.
+        mWebView.getSettings().setJavaScriptEnabled(true);
+        mWebView.addJavascriptInterface(
+                new SlicePurchaseWebInterface(this), "SlicePurchaseWebInterface");
+
+        // Display WebView
+        setContentView(mWebView);
+        mWebView.loadUrl(url.toString());
+    }
+
+    protected void onPurchaseSuccessful(long duration) {
+        logd("onPurchaseSuccessful: Carrier website indicated successfully purchased premium "
+                + "capability " + TelephonyManager.convertPremiumCapabilityToString(mCapability)
+                + (duration > 0 ? " for " + TimeUnit.MILLISECONDS.toMinutes(duration) + " minutes."
+                : "."));
+        Intent intent = new Intent();
+        intent.putExtra(SlicePurchaseController.EXTRA_PURCHASE_DURATION, duration);
+        SlicePurchaseBroadcastReceiver.sendSlicePurchaseAppResponseWithData(mApplicationContext,
+                getIntent(), SlicePurchaseController.EXTRA_INTENT_SUCCESS, intent);
+        finishAndRemoveTask();
+    }
+
+    protected void onPurchaseFailed(@SlicePurchaseController.FailureCode int failureCode,
+            @Nullable String failureReason) {
+        logd("onPurchaseFailed: Carrier website indicated purchase failed for premium capability "
+                + TelephonyManager.convertPremiumCapabilityToString(mCapability) + " with code: "
+                + failureCode + " and reason: " + failureReason);
+        Intent data = new Intent();
+        data.putExtra(SlicePurchaseController.EXTRA_FAILURE_CODE, failureCode);
+        data.putExtra(SlicePurchaseController.EXTRA_FAILURE_REASON, failureReason);
+        SlicePurchaseBroadcastReceiver.sendSlicePurchaseAppResponseWithData(mApplicationContext,
+                getIntent(), SlicePurchaseController.EXTRA_INTENT_CARRIER_ERROR, data);
+        finishAndRemoveTask();
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
+        // Pressing back in the WebView will go to the previous page instead of closing
+        //  the slice purchase application.
+        if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
+            mWebView.goBack();
+            return true;
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    protected void onDestroy() {
+        logd("onDestroy: User canceled the purchase by closing the application.");
+        SlicePurchaseBroadcastReceiver.sendSlicePurchaseAppResponse(
+                getIntent(), SlicePurchaseController.EXTRA_INTENT_CANCELED);
+        SlicePurchaseBroadcastReceiver.removeSlicePurchaseActivity(mCapability);
+        super.onDestroy();
+    }
+
+    @Nullable private URL getUrl() {
+        String url = mApplicationContext.getSystemService(CarrierConfigManager.class)
+                .getConfigForSubId(mSubId).getString(
+                        CarrierConfigManager.KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING);
+        try {
+            return new URL(url);
+        } catch (MalformedURLException e) {
+            loge("Invalid URL: " + url);
+        }
+        return null;
+    }
+
+    private static void logd(@NonNull String s) {
+        Log.d(TAG, s);
+    }
+
+    private static void loge(@NonNull String s) {
+        Log.e(TAG, s);
+    }
+}
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SliceStoreBroadcastReceiver.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiver.java
similarity index 68%
rename from packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SliceStoreBroadcastReceiver.java
rename to packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiver.java
index 7867ef1..5761b3c 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SliceStoreBroadcastReceiver.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiver.java
@@ -33,7 +33,7 @@
 import android.util.Log;
 import android.webkit.WebView;
 
-import com.android.phone.slicestore.SliceStore;
+import com.android.phone.slice.SlicePurchaseController;
 
 import java.lang.ref.WeakReference;
 import java.util.HashMap;
@@ -41,13 +41,14 @@
 import java.util.UUID;
 
 /**
- * The SliceStoreBroadcastReceiver listens for {@link SliceStore#ACTION_START_SLICE_STORE} from the
- * SliceStore in the phone process to start the SliceStore application. It displays the network
- * boost notification to the user and will start the {@link SliceStoreActivity} to display the
+ * The SlicePurchaseBroadcastReceiver listens for
+ * {@link SlicePurchaseController#ACTION_START_SLICE_PURCHASE_APP} from the SlicePurchaseController
+ * in the phone process to start the slice purchase application. It displays the network boost
+ * notification to the user and will start the {@link SlicePurchaseActivity} to display the
  * {@link WebView} to purchase network boosts from the user's carrier.
  */
-public class SliceStoreBroadcastReceiver extends BroadcastReceiver{
-    private static final String TAG = "SliceStoreBroadcastReceiver";
+public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{
+    private static final String TAG = "SlicePurchaseBroadcastReceiver";
 
     /**
      * UUID to report an anomaly when receiving a PendingIntent from an application or process
@@ -55,48 +56,49 @@
      */
     private static final String UUID_BAD_PENDING_INTENT = "c360246e-95dc-4abf-9dc1-929a76cd7e53";
 
-    /** Weak references to {@link SliceStoreActivity} for each capability, if it exists. */
-    private static final Map<Integer, WeakReference<SliceStoreActivity>> sSliceStoreActivities =
-            new HashMap<>();
+    /** Weak references to {@link SlicePurchaseActivity} for each capability, if it exists. */
+    private static final Map<Integer, WeakReference<SlicePurchaseActivity>>
+            sSlicePurchaseActivities = new HashMap<>();
 
     /** Channel ID for the network boost notification. */
     private static final String NETWORK_BOOST_NOTIFICATION_CHANNEL_ID = "network_boost";
     /** Tag for the network boost notification. */
-    public static final String NETWORK_BOOST_NOTIFICATION_TAG = "SliceStore.Notification";
+    public static final String NETWORK_BOOST_NOTIFICATION_TAG = "SlicePurchaseApp.Notification";
     /** Action for when the user clicks the "Not now" button on the network boost notification. */
     private static final String ACTION_NOTIFICATION_CANCELED =
-            "com.android.phone.slicestore.action.NOTIFICATION_CANCELED";
+            "com.android.phone.slice.action.NOTIFICATION_CANCELED";
 
     /**
-     * Create a weak reference to {@link SliceStoreActivity}. The reference will be removed when
-     * {@link SliceStoreActivity#onDestroy()} is called.
+     * Create a weak reference to {@link SlicePurchaseActivity}. The reference will be removed when
+     * {@link SlicePurchaseActivity#onDestroy()} is called.
      *
      * @param capability The premium capability requested.
-     * @param sliceStoreActivity The instance of SliceStoreActivity.
+     * @param slicePurchaseActivity The instance of SlicePurchaseActivity.
      */
-    public static void updateSliceStoreActivity(@TelephonyManager.PremiumCapability int capability,
-            @NonNull SliceStoreActivity sliceStoreActivity) {
-        sSliceStoreActivities.put(capability, new WeakReference<>(sliceStoreActivity));
+    public static void updateSlicePurchaseActivity(
+            @TelephonyManager.PremiumCapability int capability,
+            @NonNull SlicePurchaseActivity slicePurchaseActivity) {
+        sSlicePurchaseActivities.put(capability, new WeakReference<>(slicePurchaseActivity));
     }
 
     /**
-     * Remove the weak reference to {@link SliceStoreActivity} when
-     * {@link SliceStoreActivity#onDestroy()} is called.
+     * Remove the weak reference to {@link SlicePurchaseActivity} when
+     * {@link SlicePurchaseActivity#onDestroy()} is called.
      *
      * @param capability The premium capability requested.
      */
-    public static void removeSliceStoreActivity(
+    public static void removeSlicePurchaseActivity(
             @TelephonyManager.PremiumCapability int capability) {
-        sSliceStoreActivities.remove(capability);
+        sSlicePurchaseActivities.remove(capability);
     }
 
     /**
-     * Send the PendingIntent containing the corresponding SliceStore response.
+     * Send the PendingIntent containing the corresponding slice purchase application response.
      *
      * @param intent The Intent containing the PendingIntent extra.
      * @param extra The extra to get the PendingIntent to send.
      */
-    public static void sendSliceStoreResponse(@NonNull Intent intent, @NonNull String extra) {
+    public static void sendSlicePurchaseAppResponse(@NonNull Intent intent, @NonNull String extra) {
         PendingIntent pendingIntent = intent.getParcelableExtra(extra, PendingIntent.class);
         if (pendingIntent == null) {
             loge("PendingIntent does not exist for extra: " + extra);
@@ -110,14 +112,15 @@
     }
 
     /**
-     * Send the PendingIntent containing the corresponding SliceStore response with additional data.
+     * Send the PendingIntent containing the corresponding slice purchase application response
+     * with additional data.
      *
      * @param context The Context to use to send the PendingIntent.
      * @param intent The Intent containing the PendingIntent extra.
      * @param extra The extra to get the PendingIntent to send.
      * @param data The Intent containing additional data to send with the PendingIntent.
      */
-    public static void sendSliceStoreResponseWithData(@NonNull Context context,
+    public static void sendSlicePurchaseAppResponseWithData(@NonNull Context context,
             @NonNull Intent intent, @NonNull String extra, @NonNull Intent data) {
         PendingIntent pendingIntent = intent.getParcelableExtra(extra, PendingIntent.class);
         if (pendingIntent == null) {
@@ -132,45 +135,46 @@
     }
 
     /**
-     * Check whether the Intent is valid and can be used to complete purchases in the SliceStore.
-     * This checks that all necessary extras exist and that the values are valid.
+     * Check whether the Intent is valid and can be used to complete purchases in the slice purchase
+     * application. This checks that all necessary extras exist and that the values are valid.
      *
      * @param intent The intent to check
      * @return {@code true} if the intent is valid and {@code false} otherwise.
      */
     public static boolean isIntentValid(@NonNull Intent intent) {
-        int phoneId = intent.getIntExtra(SliceStore.EXTRA_PHONE_ID,
+        int phoneId = intent.getIntExtra(SlicePurchaseController.EXTRA_PHONE_ID,
                 SubscriptionManager.INVALID_PHONE_INDEX);
         if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
             loge("isIntentValid: invalid phone index: " + phoneId);
             return false;
         }
 
-        int subId = intent.getIntExtra(SliceStore.EXTRA_SUB_ID,
+        int subId = intent.getIntExtra(SlicePurchaseController.EXTRA_SUB_ID,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
             loge("isIntentValid: invalid subscription ID: " + subId);
             return false;
         }
 
-        int capability = intent.getIntExtra(SliceStore.EXTRA_PREMIUM_CAPABILITY,
-                SliceStore.PREMIUM_CAPABILITY_INVALID);
-        if (capability == SliceStore.PREMIUM_CAPABILITY_INVALID) {
+        int capability = intent.getIntExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
+                SlicePurchaseController.PREMIUM_CAPABILITY_INVALID);
+        if (capability == SlicePurchaseController.PREMIUM_CAPABILITY_INVALID) {
             loge("isIntentValid: invalid premium capability: " + capability);
             return false;
         }
 
-        String appName = intent.getStringExtra(SliceStore.EXTRA_REQUESTING_APP_NAME);
+        String appName = intent.getStringExtra(SlicePurchaseController.EXTRA_REQUESTING_APP_NAME);
         if (TextUtils.isEmpty(appName)) {
             loge("isIntentValid: empty requesting application name: " + appName);
             return false;
         }
 
-        return isPendingIntentValid(intent, SliceStore.EXTRA_INTENT_CANCELED)
-                && isPendingIntentValid(intent, SliceStore.EXTRA_INTENT_CARRIER_ERROR)
-                && isPendingIntentValid(intent, SliceStore.EXTRA_INTENT_REQUEST_FAILED)
-                && isPendingIntentValid(intent, SliceStore.EXTRA_INTENT_NOT_DEFAULT_DATA)
-                && isPendingIntentValid(intent, SliceStore.EXTRA_INTENT_SUCCESS);
+        return isPendingIntentValid(intent, SlicePurchaseController.EXTRA_INTENT_CANCELED)
+                && isPendingIntentValid(intent, SlicePurchaseController.EXTRA_INTENT_CARRIER_ERROR)
+                && isPendingIntentValid(intent, SlicePurchaseController.EXTRA_INTENT_REQUEST_FAILED)
+                && isPendingIntentValid(intent,
+                        SlicePurchaseController.EXTRA_INTENT_NOT_DEFAULT_DATA_SUB)
+                && isPendingIntentValid(intent, SlicePurchaseController.EXTRA_INTENT_SUCCESS);
     }
 
     private static boolean isPendingIntentValid(@NonNull Intent intent, @NonNull String extra) {
@@ -197,11 +201,12 @@
 
     @NonNull private static String getPendingIntentType(@NonNull String extra) {
         switch (extra) {
-            case SliceStore.EXTRA_INTENT_CANCELED: return "canceled";
-            case SliceStore.EXTRA_INTENT_CARRIER_ERROR: return "carrier error";
-            case SliceStore.EXTRA_INTENT_REQUEST_FAILED: return "request failed";
-            case SliceStore.EXTRA_INTENT_NOT_DEFAULT_DATA: return "not default data";
-            case SliceStore.EXTRA_INTENT_SUCCESS: return "success";
+            case SlicePurchaseController.EXTRA_INTENT_CANCELED: return "canceled";
+            case SlicePurchaseController.EXTRA_INTENT_CARRIER_ERROR: return "carrier error";
+            case SlicePurchaseController.EXTRA_INTENT_REQUEST_FAILED: return "request failed";
+            case SlicePurchaseController.EXTRA_INTENT_NOT_DEFAULT_DATA_SUB:
+                return "not default data sub";
+            case SlicePurchaseController.EXTRA_INTENT_SUCCESS: return "success";
             default: {
                 loge("Unknown pending intent extra: " + extra);
                 return "unknown(" + extra + ")";
@@ -213,10 +218,10 @@
     public void onReceive(@NonNull Context context, @NonNull Intent intent) {
         logd("onReceive intent: " + intent.getAction());
         switch (intent.getAction()) {
-            case SliceStore.ACTION_START_SLICE_STORE:
+            case SlicePurchaseController.ACTION_START_SLICE_PURCHASE_APP:
                 onDisplayBoosterNotification(context, intent);
                 break;
-            case SliceStore.ACTION_SLICE_STORE_RESPONSE_TIMEOUT:
+            case SlicePurchaseController.ACTION_SLICE_PURCHASE_APP_RESPONSE_TIMEOUT:
                 onTimeout(context, intent);
                 break;
             case ACTION_NOTIFICATION_CANCELED:
@@ -229,7 +234,8 @@
 
     private void onDisplayBoosterNotification(@NonNull Context context, @NonNull Intent intent) {
         if (!isIntentValid(intent)) {
-            sendSliceStoreResponse(intent, SliceStore.EXTRA_INTENT_REQUEST_FAILED);
+            sendSlicePurchaseAppResponse(intent,
+                    SlicePurchaseController.EXTRA_INTENT_REQUEST_FAILED);
             return;
         }
 
@@ -243,13 +249,14 @@
                 new Notification.Builder(context, NETWORK_BOOST_NOTIFICATION_CHANNEL_ID)
                         .setContentTitle(String.format(context.getResources().getString(
                                 R.string.network_boost_notification_title),
-                                intent.getStringExtra(SliceStore.EXTRA_REQUESTING_APP_NAME)))
+                                intent.getStringExtra(
+                                        SlicePurchaseController.EXTRA_REQUESTING_APP_NAME)))
                         .setContentText(context.getResources().getString(
                                 R.string.network_boost_notification_detail))
                         .setSmallIcon(R.drawable.ic_network_boost)
                         .setContentIntent(createContentIntent(context, intent, 1))
                         .setDeleteIntent(intent.getParcelableExtra(
-                                SliceStore.EXTRA_INTENT_CANCELED, PendingIntent.class))
+                                SlicePurchaseController.EXTRA_INTENT_CANCELED, PendingIntent.class))
                         // Add an action for the "Not now" button, which has the same behavior as
                         // the user canceling or closing the notification.
                         .addAction(new Notification.Action.Builder(
@@ -266,8 +273,8 @@
                                 createContentIntent(context, intent, 2)).build())
                         .build();
 
-        int capability = intent.getIntExtra(SliceStore.EXTRA_PREMIUM_CAPABILITY,
-                SliceStore.PREMIUM_CAPABILITY_INVALID);
+        int capability = intent.getIntExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
+                SlicePurchaseController.PREMIUM_CAPABILITY_INVALID);
         logd("Display the booster notification for capability "
                 + TelephonyManager.convertPremiumCapabilityToString(capability));
         context.getSystemService(NotificationManager.class).notifyAsUser(
@@ -276,19 +283,19 @@
 
     /**
      * Create the intent for when the user clicks on the "Manage" button on the network boost
-     * notification or the notification itself. This will open {@link SliceStoreActivity}.
+     * notification or the notification itself. This will open {@link SlicePurchaseActivity}.
      *
      * @param context The Context to create the intent for.
-     * @param intent The source Intent used to launch the SliceStore application.
+     * @param intent The source Intent used to launch the slice purchase application.
      * @param requestCode The request code for the PendingIntent.
      *
-     * @return The intent to start {@link SliceStoreActivity}.
+     * @return The intent to start {@link SlicePurchaseActivity}.
      */
     @NonNull private PendingIntent createContentIntent(@NonNull Context context,
             @NonNull Intent intent, int requestCode) {
-        Intent i = new Intent(context, SliceStoreActivity.class);
+        Intent i = new Intent(context, SlicePurchaseActivity.class);
         i.setComponent(ComponentName.unflattenFromString(
-                "com.android.carrierdefaultapp/.SliceStoreActivity"));
+                "com.android.carrierdefaultapp/.SlicePurchaseActivity"));
         i.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
                 | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
         i.putExtras(intent);
@@ -303,7 +310,7 @@
      * as if the user had canceled or removed the notification.
      *
      * @param context The Context to create the intent for.
-     * @param intent The source Intent used to launch the SliceStore application.
+     * @param intent The source Intent used to launch the slice purchase application.
      *
      * @return The canceled intent.
      */
@@ -311,37 +318,37 @@
             @NonNull Intent intent) {
         Intent i = new Intent(ACTION_NOTIFICATION_CANCELED);
         i.setComponent(ComponentName.unflattenFromString(
-                "com.android.carrierdefaultapp/.SliceStoreBroadcastReceiver"));
+                "com.android.carrierdefaultapp/.SlicePurchaseBroadcastReceiver"));
         i.putExtras(intent);
         return PendingIntent.getBroadcast(context, 0, i,
                 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_MUTABLE);
     }
 
     private void onTimeout(@NonNull Context context, @NonNull Intent intent) {
-        int capability = intent.getIntExtra(SliceStore.EXTRA_PREMIUM_CAPABILITY,
-                SliceStore.PREMIUM_CAPABILITY_INVALID);
+        int capability = intent.getIntExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
+                SlicePurchaseController.PREMIUM_CAPABILITY_INVALID);
         logd("Purchase capability " + TelephonyManager.convertPremiumCapabilityToString(capability)
                 + " timed out.");
-        if (sSliceStoreActivities.get(capability) == null) {
+        if (sSlicePurchaseActivities.get(capability) == null) {
             // Notification is still active
             logd("Closing booster notification since the user did not respond in time.");
             context.getSystemService(NotificationManager.class).cancelAsUser(
                     NETWORK_BOOST_NOTIFICATION_TAG, capability, UserHandle.ALL);
         } else {
-            // Notification was dismissed but SliceStoreActivity is still active
-            logd("Closing SliceStore WebView since the user did not complete the purchase "
-                    + "in time.");
-            sSliceStoreActivities.get(capability).get().finishAndRemoveTask();
+            // Notification was dismissed but SlicePurchaseActivity is still active
+            logd("Closing slice purchase application WebView since the user did not complete the "
+                    + "purchase in time.");
+            sSlicePurchaseActivities.get(capability).get().finishAndRemoveTask();
         }
     }
 
     private void onUserCanceled(@NonNull Context context, @NonNull Intent intent) {
-        int capability = intent.getIntExtra(SliceStore.EXTRA_PREMIUM_CAPABILITY,
-                SliceStore.PREMIUM_CAPABILITY_INVALID);
+        int capability = intent.getIntExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
+                SlicePurchaseController.PREMIUM_CAPABILITY_INVALID);
         logd("onUserCanceled: " + TelephonyManager.convertPremiumCapabilityToString(capability));
         context.getSystemService(NotificationManager.class)
                 .cancelAsUser(NETWORK_BOOST_NOTIFICATION_TAG, capability, UserHandle.ALL);
-        sendSliceStoreResponse(intent, SliceStore.EXTRA_INTENT_CANCELED);
+        sendSlicePurchaseAppResponse(intent, SlicePurchaseController.EXTRA_INTENT_CANCELED);
     }
 
     private static void logd(String s) {
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SliceStoreWebInterface.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseWebInterface.java
similarity index 67%
rename from packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SliceStoreWebInterface.java
rename to packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseWebInterface.java
index ab5d080..8547898 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SliceStoreWebInterface.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseWebInterface.java
@@ -21,18 +21,19 @@
 import android.telephony.TelephonyManager;
 import android.webkit.JavascriptInterface;
 
-import com.android.phone.slicestore.SliceStore;
+import com.android.phone.slice.SlicePurchaseController;
 
 /**
- * SliceStore web interface class allowing carrier websites to send responses back to SliceStore
- * using JavaScript.
+ * Slice purchase web interface class allowing carrier websites to send responses back to the
+ * slice purchase application using JavaScript.
  */
-public class SliceStoreWebInterface {
-    @NonNull SliceStoreActivity mActivity;
+public class SlicePurchaseWebInterface {
+    @NonNull SlicePurchaseActivity mActivity;
 
-    public SliceStoreWebInterface(@NonNull SliceStoreActivity activity) {
+    public SlicePurchaseWebInterface(@NonNull SlicePurchaseActivity activity) {
         mActivity = activity;
     }
+
     /**
      * Interface method allowing the carrier website to get the premium capability
      * that was requested to purchase.
@@ -40,7 +41,7 @@
      * This can be called using the JavaScript below:
      * <script type="text/javascript">
      *     function getRequestedCapability(duration) {
-     *         SliceStoreWebInterface.getRequestedCapability();
+     *         SlicePurchaseWebInterface.getRequestedCapability();
      *     }
      * </script>
      */
@@ -50,13 +51,14 @@
     }
 
     /**
-     * Interface method allowing the carrier website to notify the SliceStore of a successful
-     * premium capability purchase and the duration for which the premium capability is purchased.
+     * Interface method allowing the carrier website to notify the slice purchase application of
+     * a successful premium capability purchase and the duration for which the premium capability is
+     * purchased.
      *
      * This can be called using the JavaScript below:
      * <script type="text/javascript">
      *     function notifyPurchaseSuccessful(duration_ms_long = 0) {
-     *         SliceStoreWebInterface.notifyPurchaseSuccessful(duration_ms_long);
+     *         SlicePurchaseWebInterface.notifyPurchaseSuccessful(duration_ms_long);
      *     }
      * </script>
      *
@@ -68,22 +70,23 @@
     }
 
     /**
-     * Interface method allowing the carrier website to notify the SliceStore of a failed
-     * premium capability purchase.
+     * Interface method allowing the carrier website to notify the slice purchase application of
+     * a failed premium capability purchase.
      *
      * This can be called using the JavaScript below:
      * <script type="text/javascript">
-     *     function notifyPurchaseFailed() {
-     *         SliceStoreWebInterface.notifyPurchaseFailed();
+     *     function notifyPurchaseFailed(failure_code = 0, failure_reason = "unknown") {
+     *         SlicePurchaseWebInterface.notifyPurchaseFailed();
      *     }
      * </script>
      *
      * @param failureCode The failure code.
-     * @param failureReason If the failure code is {@link SliceStore#FAILURE_CODE_UNKNOWN},
+     * @param failureReason If the failure code is
+     *                      {@link SlicePurchaseController#FAILURE_CODE_UNKNOWN},
      *                      the human-readable reason for failure.
      */
     @JavascriptInterface
-    public void notifyPurchaseFailed(@SliceStore.FailureCode int failureCode,
+    public void notifyPurchaseFailed(@SlicePurchaseController.FailureCode int failureCode,
             @Nullable String failureReason) {
         mActivity.onPurchaseFailed(failureCode, failureReason);
     }
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SliceStoreActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SliceStoreActivity.java
deleted file mode 100644
index 348e389..0000000
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SliceStoreActivity.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2022 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 com.android.carrierdefaultapp;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Activity;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.webkit.WebView;
-
-import com.android.phone.slicestore.SliceStore;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Activity that launches when the user clicks on the network boost notification.
- * This will open a {@link WebView} for the carrier website to allow the user to complete the
- * premium capability purchase.
- * The carrier website can get the requested premium capability using the JavaScript interface
- * method {@code SliceStoreWebInterface.getRequestedCapability()}.
- * If the purchase is successful, the carrier website shall notify SliceStore using the JavaScript
- * interface method {@code SliceStoreWebInterface.notifyPurchaseSuccessful(duration)}, where
- * {@code duration} is the duration of the network boost.
- * If the purchase was not successful, the carrier website shall notify SliceStore using the
- * JavaScript interface method {@code SliceStoreWebInterface.notifyPurchaseFailed()}.
- * If either of these notification methods are not called, the purchase cannot be completed
- * successfully and the purchase request will eventually time out.
- */
-public class SliceStoreActivity extends Activity {
-    private static final String TAG = "SliceStoreActivity";
-
-    private @NonNull WebView mWebView;
-    private @NonNull Context mApplicationContext;
-    private int mSubId;
-    @TelephonyManager.PremiumCapability protected int mCapability;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        Intent intent = getIntent();
-        mSubId = intent.getIntExtra(SliceStore.EXTRA_SUB_ID,
-                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        mCapability = intent.getIntExtra(SliceStore.EXTRA_PREMIUM_CAPABILITY,
-                SliceStore.PREMIUM_CAPABILITY_INVALID);
-        mApplicationContext = getApplicationContext();
-        URL url = getUrl();
-        logd("onCreate: subId=" + mSubId + ", capability="
-                + TelephonyManager.convertPremiumCapabilityToString(mCapability)
-                + ", url=" + url);
-
-        // Cancel network boost notification
-        mApplicationContext.getSystemService(NotificationManager.class)
-                .cancel(SliceStoreBroadcastReceiver.NETWORK_BOOST_NOTIFICATION_TAG, mCapability);
-
-        // Verify intent and values are valid
-        if (!SliceStoreBroadcastReceiver.isIntentValid(intent)) {
-            loge("Not starting SliceStoreActivity with an invalid Intent: " + intent);
-            SliceStoreBroadcastReceiver.sendSliceStoreResponse(
-                    intent, SliceStore.EXTRA_INTENT_REQUEST_FAILED);
-            finishAndRemoveTask();
-            return;
-        }
-        if (url == null) {
-            String error = "Unable to create a URL from carrier configs.";
-            loge(error);
-            Intent data = new Intent();
-            data.putExtra(SliceStore.EXTRA_FAILURE_CODE,
-                    SliceStore.FAILURE_CODE_CARRIER_URL_UNAVAILABLE);
-            data.putExtra(SliceStore.EXTRA_FAILURE_REASON, error);
-            SliceStoreBroadcastReceiver.sendSliceStoreResponseWithData(
-                    mApplicationContext, getIntent(), SliceStore.EXTRA_INTENT_CARRIER_ERROR, data);
-            finishAndRemoveTask();
-            return;
-        }
-        if (mSubId != SubscriptionManager.getDefaultSubscriptionId()) {
-            loge("Unable to start SliceStore on the non-default data subscription: " + mSubId);
-            SliceStoreBroadcastReceiver.sendSliceStoreResponse(
-                    intent, SliceStore.EXTRA_INTENT_NOT_DEFAULT_DATA);
-            finishAndRemoveTask();
-            return;
-        }
-
-        // Create a reference to this activity in SliceStoreBroadcastReceiver
-        SliceStoreBroadcastReceiver.updateSliceStoreActivity(mCapability, this);
-
-        // Create and configure WebView
-        mWebView = new WebView(this);
-        // Enable JavaScript for the carrier purchase website to send results back to SliceStore
-        mWebView.getSettings().setJavaScriptEnabled(true);
-        mWebView.addJavascriptInterface(new SliceStoreWebInterface(this), "SliceStoreWebInterface");
-
-        // Display WebView
-        setContentView(mWebView);
-        mWebView.loadUrl(url.toString());
-    }
-
-    protected void onPurchaseSuccessful(long duration) {
-        logd("onPurchaseSuccessful: Carrier website indicated successfully purchased premium "
-                + "capability " + TelephonyManager.convertPremiumCapabilityToString(mCapability)
-                + " for " + TimeUnit.MILLISECONDS.toMinutes(duration) + " minutes.");
-        Intent intent = new Intent();
-        intent.putExtra(SliceStore.EXTRA_PURCHASE_DURATION, duration);
-        SliceStoreBroadcastReceiver.sendSliceStoreResponseWithData(
-                mApplicationContext, getIntent(), SliceStore.EXTRA_INTENT_SUCCESS, intent);
-        finishAndRemoveTask();
-    }
-
-    protected void onPurchaseFailed(@SliceStore.FailureCode int failureCode,
-            @Nullable String failureReason) {
-        logd("onPurchaseFailed: Carrier website indicated purchase failed for premium capability "
-                + TelephonyManager.convertPremiumCapabilityToString(mCapability) + " with code: "
-                + SliceStore.convertFailureCodeToString(failureCode) + " and reason: "
-                + failureReason);
-        Intent data = new Intent();
-        data.putExtra(SliceStore.EXTRA_FAILURE_CODE, failureCode);
-        data.putExtra(SliceStore.EXTRA_FAILURE_REASON, failureReason);
-        SliceStoreBroadcastReceiver.sendSliceStoreResponseWithData(
-                mApplicationContext, getIntent(), SliceStore.EXTRA_INTENT_CARRIER_ERROR, data);
-        finishAndRemoveTask();
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
-        // Pressing back in the WebView will go to the previous page instead of closing SliceStore.
-        if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
-            mWebView.goBack();
-            return true;
-        }
-        return super.onKeyDown(keyCode, event);
-    }
-
-    @Override
-    protected void onDestroy() {
-        logd("onDestroy: User canceled the purchase by closing the application.");
-        SliceStoreBroadcastReceiver.sendSliceStoreResponse(
-                getIntent(), SliceStore.EXTRA_INTENT_CANCELED);
-        SliceStoreBroadcastReceiver.removeSliceStoreActivity(mCapability);
-        super.onDestroy();
-    }
-
-    @Nullable private URL getUrl() {
-        String url = mApplicationContext.getSystemService(CarrierConfigManager.class)
-                .getConfigForSubId(mSubId).getString(
-                        CarrierConfigManager.KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING);
-        try {
-            return new URL(url);
-        } catch (MalformedURLException e) {
-            loge("Invalid URL: " + url);
-        }
-        return null;
-    }
-
-    private static void logd(@NonNull String s) {
-        Log.d(TAG, s);
-    }
-
-    private static void loge(@NonNull String s) {
-        Log.e(TAG, s);
-    }
-}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 7be40b8..453c656 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -8732,7 +8732,8 @@
      * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)}
      * returns a failure due to user action or timeout.
      * The maximum number of network boost notifications to show the user are defined in
-     * {@link #KEY_PREMIUM_CAPABILITY_MAXIMUM_NOTIFICATION_COUNT_INT_ARRAY}.
+     * {@link #KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT} and
+     * {@link #KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT}.
      *
      * The default value is 30 minutes.
      *
@@ -8744,20 +8745,32 @@
             "premium_capability_notification_backoff_hysteresis_time_millis_long";
 
     /**
-     * The maximum number of times that we display the notification for a network boost via premium
-     * capabilities when {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)}
+     * The maximum number of times in a day that we display the notification for a network boost
+     * via premium capabilities when
+     * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)}
      * returns a failure due to user action or timeout.
      *
-     * An int array with 2 values: {max_notifications_per_day, max_notifications_per_month}.
-     *
-     * The default value is {2, 10}, meaning we display a maximum of 2 network boost notifications
-     * per day and 10 notifications per month.
+     * The default value is 2 times.
      *
      * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED
      * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT
      */
-    public static final String KEY_PREMIUM_CAPABILITY_MAXIMUM_NOTIFICATION_COUNT_INT_ARRAY =
-            "premium_capability_maximum_notification_count_int_array";
+    public static final String KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT =
+            "premium_capability_maximum_daily_notification_count_int";
+
+    /**
+     * The maximum number of times in a month that we display the notification for a network boost
+     * via premium capabilities when
+     * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)}
+     * returns a failure due to user action or timeout.
+     *
+     * The default value is 10 times.
+     *
+     * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED
+     * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT
+     */
+    public static final String KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT =
+            "premium_capability_maximum_monthly_notification_count_int";
 
     /**
      * The amount of time in milliseconds that the purchase request should be throttled when
@@ -8781,7 +8794,7 @@
      * During the setup time, calls to
      * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)} will return
      * {@link TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_PENDING_NETWORK_SETUP}.
-     * If the network fails set up a slicing configuration for the premium capability within the
+     * If the network fails to set up a slicing configuration for the premium capability within the
      * setup time, subsequent purchase requests will be allowed to go through again.
      *
      * The default value is 5 minutes.
@@ -8808,7 +8821,7 @@
      * when connected to {@link TelephonyManager#NETWORK_TYPE_LTE} to purchase and use
      * premium capabilities.
      * If this is {@code false}, applications can only purchase and use premium capabilities when
-     * conencted to {@link TelephonyManager#NETWORK_TYPE_NR}.
+     * connected to {@link TelephonyManager#NETWORK_TYPE_NR}.
      *
      * This is {@code false} by default.
      */
@@ -9507,8 +9520,8 @@
                 TimeUnit.MINUTES.toMillis(30));
         sDefaults.putLong(KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG,
                 TimeUnit.MINUTES.toMillis(30));
-        sDefaults.putIntArray(KEY_PREMIUM_CAPABILITY_MAXIMUM_NOTIFICATION_COUNT_INT_ARRAY,
-                new int[] {2, 10});
+        sDefaults.putInt(KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT, 2);
+        sDefaults.putInt(KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT, 10);
         sDefaults.putLong(
                 KEY_PREMIUM_CAPABILITY_PURCHASE_CONDITION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG,
                 TimeUnit.MINUTES.toMillis(30));
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 35b2055..051fb74 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -17226,12 +17226,13 @@
      * #KEY_PREMIUM_CAPABILITY_PURCHASE_CONDITION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG}.
      * If displaying the network boost notification is throttled, it will be for the amount of time
      * specified by {@link CarrierConfigManager
-     * #KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_INT_ARRAY}.
+     * #KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG}.
      * If a foreground application requests premium capabilities, the network boost notification
      * will be displayed to the user regardless of the throttled status.
      * We will show the network boost notification to the user up to the daily and monthly maximum
-     * number of times specified by {@link CarrierConfigManager
-     * #KEY_PREMIUM_CAPABILITY_MAXIMUM_NOTIFICATION_COUNT_INT_ARRAY}.
+     * number of times specified by
+     * {@link CarrierConfigManager#KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT} and
+     * {@link CarrierConfigManager#KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT}.
      * Subsequent attempts will return the same error until the request is no longer throttled
      * or throttling conditions change.
      */
@@ -17333,7 +17334,7 @@
      * Subsequent attempts will return the same error until the request is made on the default
      * data subscription.
      */
-    public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_DEFAULT_DATA = 14;
+    public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_DEFAULT_DATA_SUB = 14;
 
     /**
      * Purchase premium capability was successful and is waiting for the network to setup the
@@ -17341,7 +17342,7 @@
      * {@link CarrierConfigManager#KEY_PREMIUM_CAPABILITY_NETWORK_SETUP_TIME_MILLIS_LONG},
      * subsequent requests will return {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED}
      * until the purchase expires. If the setup is not complete within the time specified above,
-     * applications can reques the premium capability again.
+     * applications can request the premium capability again.
      */
     public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_PENDING_NETWORK_SETUP = 15;
 
@@ -17363,7 +17364,7 @@
             PURCHASE_PREMIUM_CAPABILITY_RESULT_FEATURE_NOT_SUPPORTED,
             PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_NOT_AVAILABLE,
             PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_CONGESTED,
-            PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_DEFAULT_DATA,
+            PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_DEFAULT_DATA_SUB,
             PURCHASE_PREMIUM_CAPABILITY_RESULT_PENDING_NETWORK_SETUP})
     public @interface PurchasePremiumCapabilityResult {}
 
@@ -17403,8 +17404,8 @@
                 return "NETWORK_NOT_AVAILABLE";
             case PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_CONGESTED:
                 return "NETWORK_CONGESTED";
-            case PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_DEFAULT_DATA:
-                return "NOT_DEFAULT_DATA";
+            case PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_DEFAULT_DATA_SUB:
+                return "NOT_DEFAULT_DATA_SUB";
             case PURCHASE_PREMIUM_CAPABILITY_RESULT_PENDING_NETWORK_SETUP:
                 return "PENDING_NETWORK_SETUP";
             default: