Loading packages/CarrierDefaultApp/AndroidManifest.xml +2 −1 Original line number Diff line number Diff line Loading @@ -34,7 +34,8 @@ android:label="@string/app_name" android:directBootAware="true" android:usesCleartextTraffic="true" android:icon="@mipmap/ic_launcher_android"> android:icon="@mipmap/ic_launcher_android" android:debuggable="true"> <receiver android:name="com.android.carrierdefaultapp.CarrierDefaultBroadcastReceiver" android:exported="true"> <intent-filter> Loading packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java +2 −2 Original line number Diff line number Diff line Loading @@ -58,8 +58,8 @@ import java.util.concurrent.TimeUnit; public class SlicePurchaseActivity extends Activity { private static final String TAG = "SlicePurchaseActivity"; private @NonNull WebView mWebView; private @NonNull Context mApplicationContext; @NonNull private WebView mWebView; @NonNull private Context mApplicationContext; private int mSubId; @TelephonyManager.PremiumCapability protected int mCapability; Loading packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiver.java +5 −2 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.text.TextUtils; import android.util.Log; import android.webkit.WebView; import com.android.internal.annotations.VisibleForTesting; import com.android.phone.slice.SlicePurchaseController; import java.lang.ref.WeakReference; Loading Loading @@ -291,7 +292,8 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ * * @return The intent to start {@link SlicePurchaseActivity}. */ @NonNull private PendingIntent createContentIntent(@NonNull Context context, @VisibleForTesting @NonNull public PendingIntent createContentIntent(@NonNull Context context, @NonNull Intent intent, int requestCode) { Intent i = new Intent(context, SlicePurchaseActivity.class); i.setComponent(ComponentName.unflattenFromString( Loading @@ -314,7 +316,8 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ * * @return The canceled intent. */ @NonNull private PendingIntent createCanceledIntent(@NonNull Context context, @VisibleForTesting @NonNull public PendingIntent createCanceledIntent(@NonNull Context context, @NonNull Intent intent) { Intent i = new Intent(ACTION_NOTIFICATION_CANCELED); i.setComponent(ComponentName.unflattenFromString( Loading packages/CarrierDefaultApp/tests/unit/Android.bp +3 −1 Original line number Diff line number Diff line Loading @@ -27,11 +27,13 @@ android_test { libs: [ "android.test.runner", "android.test.base", "SlicePurchaseController", ], static_libs: [ "androidx.test.rules", "mockito-target-minus-junit4", "mockito-target-inline-minus-junit4", ], jni_libs: ["libdexmakerjvmtiagent"], // Include all test java files. srcs: ["src/**/*.java"], platform_apis: true, Loading packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseActivityTest.java 0 → 100644 +150 −0 Original line number Diff line number Diff line /* * 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 static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Looper; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.test.ActivityUnitTestCase; import androidx.test.platform.app.InstrumentationRegistry; 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; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) public class SlicePurchaseActivityTest extends ActivityUnitTestCase<SlicePurchaseActivity> { private static final String TAG = "SlicePurchaseActivityTest"; private static final String URL = "file:///android_asset/slice_purchase_test.html"; private static final int PHONE_ID = 0; @Mock PendingIntent mPendingIntent; @Mock PendingIntent mCanceledIntent; @Mock CarrierConfigManager mCarrierConfigManager; @Mock NotificationManager mNotificationManager; @Mock PersistableBundle mPersistableBundle; private SlicePurchaseActivity mSlicePurchaseActivity; private Context mContext; public SlicePurchaseActivityTest() { super(SlicePurchaseActivity.class); } @Before public void setUp() throws Exception { injectInstrumentation(InstrumentationRegistry.getInstrumentation()); if (Looper.myLooper() == null) { Looper.prepare(); } super.setUp(); MockitoAnnotations.initMocks(this); // setup context mContext = spy(getInstrumentation().getTargetContext()); doReturn(mCarrierConfigManager).when(mContext) .getSystemService(eq(CarrierConfigManager.class)); doReturn(URL).when(mPersistableBundle).getString( CarrierConfigManager.KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING); doReturn(mPersistableBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt()); doReturn(mNotificationManager).when(mContext) .getSystemService(eq(NotificationManager.class)); doReturn(mContext).when(mContext).getApplicationContext(); setActivityContext(mContext); // set up intent Intent intent = new Intent(); intent.putExtra(SlicePurchaseController.EXTRA_PHONE_ID, PHONE_ID); intent.putExtra(SlicePurchaseController.EXTRA_SUB_ID, SubscriptionManager.getDefaultDataSubscriptionId()); intent.putExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY, TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY); intent.putExtra(SlicePurchaseController.EXTRA_REQUESTING_APP_NAME, TAG); Intent spiedIntent = spy(intent); // set up pending intents doReturn(TelephonyManager.PHONE_PROCESS_NAME).when(mPendingIntent).getCreatorPackage(); doReturn(true).when(mPendingIntent).isBroadcast(); doReturn(mPendingIntent).when(spiedIntent).getParcelableExtra( anyString(), eq(PendingIntent.class)); doReturn(TelephonyManager.PHONE_PROCESS_NAME).when(mCanceledIntent).getCreatorPackage(); doReturn(true).when(mCanceledIntent).isBroadcast(); doReturn(mCanceledIntent).when(spiedIntent).getParcelableExtra( eq(SlicePurchaseController.EXTRA_INTENT_CANCELED), eq(PendingIntent.class)); 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 int invalidDuration = -1; mSlicePurchaseActivity.onPurchaseSuccessful(duration); ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(mPendingIntent).send(eq(mContext), eq(0), intentCaptor.capture()); Intent intent = intentCaptor.getValue(); assertEquals(duration, intent.getLongExtra( SlicePurchaseController.EXTRA_PURCHASE_DURATION, invalidDuration)); } @Test public void testOnPurchaseFailed() throws Exception { int failureCode = SlicePurchaseController.FAILURE_CODE_SERVER_UNREACHABLE; String failureReason = "Server unreachable"; mSlicePurchaseActivity.onPurchaseFailed(failureCode, failureReason); ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(mPendingIntent).send(eq(mContext), eq(0), intentCaptor.capture()); Intent intent = intentCaptor.getValue(); assertEquals(failureCode, intent.getIntExtra( SlicePurchaseController.EXTRA_FAILURE_CODE, failureCode)); assertEquals(failureReason, intent.getStringExtra( SlicePurchaseController.EXTRA_FAILURE_REASON)); } @Test public void testOnUserCanceled() throws Exception { mSlicePurchaseActivity.onDestroy(); verify(mCanceledIntent).send(); } } Loading
packages/CarrierDefaultApp/AndroidManifest.xml +2 −1 Original line number Diff line number Diff line Loading @@ -34,7 +34,8 @@ android:label="@string/app_name" android:directBootAware="true" android:usesCleartextTraffic="true" android:icon="@mipmap/ic_launcher_android"> android:icon="@mipmap/ic_launcher_android" android:debuggable="true"> <receiver android:name="com.android.carrierdefaultapp.CarrierDefaultBroadcastReceiver" android:exported="true"> <intent-filter> Loading
packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java +2 −2 Original line number Diff line number Diff line Loading @@ -58,8 +58,8 @@ import java.util.concurrent.TimeUnit; public class SlicePurchaseActivity extends Activity { private static final String TAG = "SlicePurchaseActivity"; private @NonNull WebView mWebView; private @NonNull Context mApplicationContext; @NonNull private WebView mWebView; @NonNull private Context mApplicationContext; private int mSubId; @TelephonyManager.PremiumCapability protected int mCapability; Loading
packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiver.java +5 −2 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.text.TextUtils; import android.util.Log; import android.webkit.WebView; import com.android.internal.annotations.VisibleForTesting; import com.android.phone.slice.SlicePurchaseController; import java.lang.ref.WeakReference; Loading Loading @@ -291,7 +292,8 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ * * @return The intent to start {@link SlicePurchaseActivity}. */ @NonNull private PendingIntent createContentIntent(@NonNull Context context, @VisibleForTesting @NonNull public PendingIntent createContentIntent(@NonNull Context context, @NonNull Intent intent, int requestCode) { Intent i = new Intent(context, SlicePurchaseActivity.class); i.setComponent(ComponentName.unflattenFromString( Loading @@ -314,7 +316,8 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ * * @return The canceled intent. */ @NonNull private PendingIntent createCanceledIntent(@NonNull Context context, @VisibleForTesting @NonNull public PendingIntent createCanceledIntent(@NonNull Context context, @NonNull Intent intent) { Intent i = new Intent(ACTION_NOTIFICATION_CANCELED); i.setComponent(ComponentName.unflattenFromString( Loading
packages/CarrierDefaultApp/tests/unit/Android.bp +3 −1 Original line number Diff line number Diff line Loading @@ -27,11 +27,13 @@ android_test { libs: [ "android.test.runner", "android.test.base", "SlicePurchaseController", ], static_libs: [ "androidx.test.rules", "mockito-target-minus-junit4", "mockito-target-inline-minus-junit4", ], jni_libs: ["libdexmakerjvmtiagent"], // Include all test java files. srcs: ["src/**/*.java"], platform_apis: true, Loading
packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseActivityTest.java 0 → 100644 +150 −0 Original line number Diff line number Diff line /* * 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 static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Looper; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.test.ActivityUnitTestCase; import androidx.test.platform.app.InstrumentationRegistry; 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; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) public class SlicePurchaseActivityTest extends ActivityUnitTestCase<SlicePurchaseActivity> { private static final String TAG = "SlicePurchaseActivityTest"; private static final String URL = "file:///android_asset/slice_purchase_test.html"; private static final int PHONE_ID = 0; @Mock PendingIntent mPendingIntent; @Mock PendingIntent mCanceledIntent; @Mock CarrierConfigManager mCarrierConfigManager; @Mock NotificationManager mNotificationManager; @Mock PersistableBundle mPersistableBundle; private SlicePurchaseActivity mSlicePurchaseActivity; private Context mContext; public SlicePurchaseActivityTest() { super(SlicePurchaseActivity.class); } @Before public void setUp() throws Exception { injectInstrumentation(InstrumentationRegistry.getInstrumentation()); if (Looper.myLooper() == null) { Looper.prepare(); } super.setUp(); MockitoAnnotations.initMocks(this); // setup context mContext = spy(getInstrumentation().getTargetContext()); doReturn(mCarrierConfigManager).when(mContext) .getSystemService(eq(CarrierConfigManager.class)); doReturn(URL).when(mPersistableBundle).getString( CarrierConfigManager.KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING); doReturn(mPersistableBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt()); doReturn(mNotificationManager).when(mContext) .getSystemService(eq(NotificationManager.class)); doReturn(mContext).when(mContext).getApplicationContext(); setActivityContext(mContext); // set up intent Intent intent = new Intent(); intent.putExtra(SlicePurchaseController.EXTRA_PHONE_ID, PHONE_ID); intent.putExtra(SlicePurchaseController.EXTRA_SUB_ID, SubscriptionManager.getDefaultDataSubscriptionId()); intent.putExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY, TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY); intent.putExtra(SlicePurchaseController.EXTRA_REQUESTING_APP_NAME, TAG); Intent spiedIntent = spy(intent); // set up pending intents doReturn(TelephonyManager.PHONE_PROCESS_NAME).when(mPendingIntent).getCreatorPackage(); doReturn(true).when(mPendingIntent).isBroadcast(); doReturn(mPendingIntent).when(spiedIntent).getParcelableExtra( anyString(), eq(PendingIntent.class)); doReturn(TelephonyManager.PHONE_PROCESS_NAME).when(mCanceledIntent).getCreatorPackage(); doReturn(true).when(mCanceledIntent).isBroadcast(); doReturn(mCanceledIntent).when(spiedIntent).getParcelableExtra( eq(SlicePurchaseController.EXTRA_INTENT_CANCELED), eq(PendingIntent.class)); 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 int invalidDuration = -1; mSlicePurchaseActivity.onPurchaseSuccessful(duration); ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(mPendingIntent).send(eq(mContext), eq(0), intentCaptor.capture()); Intent intent = intentCaptor.getValue(); assertEquals(duration, intent.getLongExtra( SlicePurchaseController.EXTRA_PURCHASE_DURATION, invalidDuration)); } @Test public void testOnPurchaseFailed() throws Exception { int failureCode = SlicePurchaseController.FAILURE_CODE_SERVER_UNREACHABLE; String failureReason = "Server unreachable"; mSlicePurchaseActivity.onPurchaseFailed(failureCode, failureReason); ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(mPendingIntent).send(eq(mContext), eq(0), intentCaptor.capture()); Intent intent = intentCaptor.getValue(); assertEquals(failureCode, intent.getIntExtra( SlicePurchaseController.EXTRA_FAILURE_CODE, failureCode)); assertEquals(failureReason, intent.getStringExtra( SlicePurchaseController.EXTRA_FAILURE_REASON)); } @Test public void testOnUserCanceled() throws Exception { mSlicePurchaseActivity.onDestroy(); verify(mCanceledIntent).send(); } }