Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f09e5e1c authored by Sarah Chin's avatar Sarah Chin
Browse files

Slice purchase app get URL from intent

Get the purchase URL from the intent sent by SlicePurchaseController
instead of querying CarrierConfigManager directly.

Test: manual
Test: SlicePurchaseBroadcastReceiverTest, SlicePurchaseActivityTest
Bug: 259498920
Change-Id: I163ecb44026486798e4d26dec23f2aa4aa6fbd56
parent f8fb10ff
Loading
Loading
Loading
Loading
+21 −39
Original line number Diff line number Diff line
@@ -22,17 +22,14 @@ import android.app.Activity;
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.URLUtil;
import android.webkit.WebView;

import com.android.phone.slice.SlicePurchaseController;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;

@@ -61,37 +58,29 @@ public class SlicePurchaseActivity extends Activity {
    @NonNull private WebView mWebView;
    @NonNull private Context mApplicationContext;
    @NonNull private Intent mIntent;
    @Nullable private URL mUrl;
    private int mSubId;
    @NonNull private URL mUrl;
    @TelephonyManager.PremiumCapability protected int mCapability;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mIntent = getIntent();
        mSubId = mIntent.getIntExtra(SlicePurchaseController.EXTRA_SUB_ID,
        int subId = mIntent.getIntExtra(SlicePurchaseController.EXTRA_SUB_ID,
                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
        mCapability = mIntent.getIntExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
                SlicePurchaseController.PREMIUM_CAPABILITY_INVALID);
        String url = mIntent.getStringExtra(SlicePurchaseController.EXTRA_PURCHASE_URL);
        mApplicationContext = getApplicationContext();
        mUrl = getUrl();
        logd("onCreate: subId=" + mSubId + ", capability="
                + TelephonyManager.convertPremiumCapabilityToString(mCapability)
                + ", url=" + mUrl);
        logd("onCreate: subId=" + subId + ", capability="
                + TelephonyManager.convertPremiumCapabilityToString(mCapability) + ", url=" + url);

        // Cancel network boost notification
        SlicePurchaseBroadcastReceiver.cancelNotification(mApplicationContext, mCapability);

        // Verify intent and values are valid
        if (!SlicePurchaseBroadcastReceiver.isIntentValid(mIntent)) {
            loge("Not starting SlicePurchaseActivity with an invalid Intent: " + mIntent);
            SlicePurchaseBroadcastReceiver.sendSlicePurchaseAppResponse(
                    mIntent, SlicePurchaseController.EXTRA_INTENT_REQUEST_FAILED);
            finishAndRemoveTask();
            return;
        }
        // Verify purchase URL is valid
        mUrl = SlicePurchaseBroadcastReceiver.getPurchaseUrl(url);
        if (mUrl == null) {
            String error = "Unable to create a URL from carrier configs.";
            String error = "Unable to create a purchase URL.";
            loge(error);
            Intent data = new Intent();
            data.putExtra(SlicePurchaseController.EXTRA_FAILURE_CODE,
@@ -102,9 +91,20 @@ public class SlicePurchaseActivity extends Activity {
            finishAndRemoveTask();
            return;
        }
        if (mSubId != SubscriptionManager.getDefaultSubscriptionId()) {

        // Verify intent is valid
        if (!SlicePurchaseBroadcastReceiver.isIntentValid(mIntent)) {
            loge("Not starting SlicePurchaseActivity with an invalid Intent: " + mIntent);
            SlicePurchaseBroadcastReceiver.sendSlicePurchaseAppResponse(
                    mIntent, SlicePurchaseController.EXTRA_INTENT_REQUEST_FAILED);
            finishAndRemoveTask();
            return;
        }

        // Verify sub ID is valid
        if (subId != SubscriptionManager.getDefaultSubscriptionId()) {
            loge("Unable to start the slice purchase application on the non-default data "
                    + "subscription: " + mSubId);
                    + "subscription: " + subId);
            SlicePurchaseBroadcastReceiver.sendSlicePurchaseAppResponse(
                    mIntent, SlicePurchaseController.EXTRA_INTENT_NOT_DEFAULT_DATA_SUBSCRIPTION);
            finishAndRemoveTask();
@@ -159,24 +159,6 @@ public class SlicePurchaseActivity extends Activity {
        super.onDestroy();
    }

    @Nullable private URL getUrl() {
        String url = mApplicationContext.getSystemService(CarrierConfigManager.class)
                .getConfigForSubId(mSubId).getString(
                        CarrierConfigManager.KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING);
        boolean isUrlValid = URLUtil.isValidUrl(url);
        if (URLUtil.isAssetUrl(url)) {
            isUrlValid = url.equals(SlicePurchaseController.SLICE_PURCHASE_TEST_FILE);
        }
        if (isUrlValid) {
            try {
                return new URL(url);
            } catch (MalformedURLException ignored) {
            }
        }
        loge("Invalid URL: " + url);
        return null;
    }

    private void setupWebView() {
        // Create WebView
        mWebView = new WebView(this);
+36 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.carrierdefaultapp;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
@@ -35,11 +36,15 @@ import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.URLUtil;
import android.webkit.WebView;

import com.android.internal.annotations.VisibleForTesting;
import com.android.phone.slice.SlicePurchaseController;

import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@@ -140,7 +145,7 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{
     * 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
     * @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) {
@@ -165,6 +170,12 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{
            return false;
        }

        String purchaseUrl = intent.getStringExtra(SlicePurchaseController.EXTRA_PURCHASE_URL);
        if (getPurchaseUrl(purchaseUrl) == null) {
            loge("isIntentValid: invalid purchase URL: " + purchaseUrl);
            return false;
        }

        String appName = intent.getStringExtra(SlicePurchaseController.EXTRA_REQUESTING_APP_NAME);
        if (TextUtils.isEmpty(appName)) {
            loge("isIntentValid: empty requesting application name: " + appName);
@@ -181,6 +192,30 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{
                        SlicePurchaseController.EXTRA_INTENT_NOTIFICATION_SHOWN);
    }

    /**
     * Get the {@link URL} from the given purchase URL String, if it is valid.
     *
     * @param purchaseUrl The purchase URL String to use to create the URL.
     * @return The purchase URL from the given String or {@code null} if it is invalid.
     */
    @Nullable public static URL getPurchaseUrl(@Nullable String purchaseUrl) {
        if (!URLUtil.isValidUrl(purchaseUrl)) {
            return null;
        }
        if (URLUtil.isAssetUrl(purchaseUrl)
                && !purchaseUrl.equals(SlicePurchaseController.SLICE_PURCHASE_TEST_FILE)) {
            return null;
        }
        URL url = null;
        try {
            url = new URL(purchaseUrl);
            url.toURI();
        } catch (MalformedURLException | URISyntaxException e) {
            loge("Invalid purchase URL: " + purchaseUrl + ", " + e);
        }
        return url;
    }

    private static boolean isPendingIntentValid(@NonNull Intent intent, @NonNull String extra) {
        String intentType = getPendingIntentType(extra);
        PendingIntent pendingIntent = intent.getParcelableExtra(extra, PendingIntent.class);
+2 −7
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ import androidx.test.runner.AndroidJUnit4;

import com.android.phone.slice.SlicePurchaseController;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -94,6 +93,8 @@ public class SlicePurchaseActivityTest extends ActivityUnitTestCase<SlicePurchas
                SubscriptionManager.getDefaultDataSubscriptionId());
        intent.putExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
                TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY);
        intent.putExtra(SlicePurchaseController.EXTRA_PURCHASE_URL,
                SlicePurchaseController.SLICE_PURCHASE_TEST_FILE);
        intent.putExtra(SlicePurchaseController.EXTRA_REQUESTING_APP_NAME, TAG);
        Intent spiedIntent = spy(intent);

@@ -110,12 +111,6 @@ public class SlicePurchaseActivityTest extends ActivityUnitTestCase<SlicePurchas
        mSlicePurchaseActivity = startActivity(spiedIntent, null, null);
    }

    @After
    public void tearDown() throws Exception {
        mSlicePurchaseActivity.onDestroy();
        super.tearDown();
    }

    @Test
    public void testOnPurchaseSuccessful() throws Exception {
        int duration = 5 * 60 * 1000; // 5 minutes
+29 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.carrierdefaultapp;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.any;
@@ -55,6 +56,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.net.URL;
import java.util.Locale;

@RunWith(AndroidJUnit4.class)
@@ -132,6 +134,8 @@ public class SlicePurchaseBroadcastReceiverTest {
                eq(SlicePurchaseController.EXTRA_SUB_ID), anyInt());
        doReturn(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY).when(mIntent).getIntExtra(
                eq(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY), anyInt());
        doReturn(SlicePurchaseController.SLICE_PURCHASE_TEST_FILE).when(mIntent).getStringExtra(
                eq(SlicePurchaseController.EXTRA_PURCHASE_URL));
        doReturn(TAG).when(mIntent).getStringExtra(
                eq(SlicePurchaseController.EXTRA_REQUESTING_APP_NAME));
        assertFalse(SlicePurchaseBroadcastReceiver.isIntentValid(mIntent));
@@ -144,6 +148,29 @@ public class SlicePurchaseBroadcastReceiverTest {
        assertTrue(SlicePurchaseBroadcastReceiver.isIntentValid(mIntent));
    }

    @Test
    public void testGetPurchaseUrl() {
        String[] invalidUrls = new String[] {
                null,
                "",
                "www.google.com",
                "htt://www.google.com",
                "http//www.google.com",
                "http:/www.google.com",
                "file:///android_asset/",
                "file:///android_asset/slice_store_test.html"
        };

        for (String url : invalidUrls) {
            URL purchaseUrl = SlicePurchaseBroadcastReceiver.getPurchaseUrl(url);
            assertNull(purchaseUrl);
        }

        assertEquals(SlicePurchaseController.SLICE_PURCHASE_TEST_FILE,
                SlicePurchaseBroadcastReceiver.getPurchaseUrl(
                        SlicePurchaseController.SLICE_PURCHASE_TEST_FILE).toString());
    }

    @Test
    public void testDisplayNetworkBoostNotification() throws Exception {
        displayNetworkBoostNotification();
@@ -200,6 +227,8 @@ public class SlicePurchaseBroadcastReceiverTest {
                eq(SlicePurchaseController.EXTRA_SUB_ID), anyInt());
        doReturn(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY).when(mIntent).getIntExtra(
                eq(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY), anyInt());
        doReturn(SlicePurchaseController.SLICE_PURCHASE_TEST_FILE).when(mIntent).getStringExtra(
                eq(SlicePurchaseController.EXTRA_PURCHASE_URL));
        doReturn(TAG).when(mIntent).getStringExtra(
                eq(SlicePurchaseController.EXTRA_REQUESTING_APP_NAME));
        mSlicePurchaseBroadcastReceiver.onReceive(mContext, mIntent);