Loading packages/CarrierDefaultApp/res/drawable/ic_network_boost.xml→packages/CarrierDefaultApp/res/drawable/ic_performance_boost.xml +0 −0 File moved. View file packages/CarrierDefaultApp/res/values/strings.xml +11 −11 Original line number Original line Diff line number Diff line Loading @@ -14,17 +14,17 @@ <string name="ssl_error_example">For example, the login page may not belong to the organization shown.</string> <string name="ssl_error_example">For example, the login page may not belong to the organization shown.</string> <string name="ssl_error_continue">Continue anyway via browser</string> <string name="ssl_error_continue">Continue anyway via browser</string> <!-- Telephony notification channel name for network boost notifications. --> <!-- Telephony notification channel name for performance boost notifications. --> <string name="network_boost_notification_channel">Network boost</string> <string name="performance_boost_notification_channel">Performance boost</string> <!-- Notification title text for the network boost notification. --> <!-- Notification title text for the performance boost notification. --> <string name="network_boost_notification_title">%s recommends a data boost</string> <string name="performance_boost_notification_title">%s recommends a performance boost</string> <!-- Notification detail text for the network boost notification. --> <!-- Notification detail text for the performance boost notification. --> <string name="network_boost_notification_detail">Buy a network boost for better performance</string> <string name="performance_boost_notification_detail">Buy a performance boost for better network performance</string> <!-- Notification button text to cancel the network boost notification. --> <!-- Notification button text to cancel the performance boost notification. --> <string name="network_boost_notification_button_not_now">Not now</string> <string name="performance_boost_notification_button_not_now">Not now</string> <!-- Notification button text to manage the network boost notification. --> <!-- Notification button text to manage the performance boost notification. --> <string name="network_boost_notification_button_manage">Manage</string> <string name="performance_boost_notification_button_manage">Manage</string> <!-- Label to display when the slice purchase application opens. --> <!-- Label to display when the slice purchase application opens. --> <string name="slice_purchase_app_label">Purchase a network boost.</string> <string name="slice_purchase_app_label">Purchase a performance boost.</string> </resources> </resources> packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java +3 −3 Original line number Original line Diff line number Diff line Loading @@ -34,7 +34,7 @@ import java.net.URL; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit; /** /** * Activity that launches when the user clicks on the network boost notification. * Activity that launches when the user clicks on the performance boost notification. * This will open a {@link WebView} for the carrier website to allow the user to complete the * This will open a {@link WebView} for the carrier website to allow the user to complete the * premium capability purchase. * premium capability purchase. * The carrier website can get the requested premium capability using the JavaScript interface * The carrier website can get the requested premium capability using the JavaScript interface Loading @@ -42,7 +42,7 @@ import java.util.concurrent.TimeUnit; * If the purchase is successful, the carrier website shall notify the slice purchase application * If the purchase is successful, the carrier website shall notify the slice purchase application * using the JavaScript interface method * using the JavaScript interface method * {@code SlicePurchaseWebInterface.notifyPurchaseSuccessful(duration)}, where {@code duration} is * {@code SlicePurchaseWebInterface.notifyPurchaseSuccessful(duration)}, where {@code duration} is * the optional duration of the network boost. * the optional duration of the performance boost. * If the purchase was not successful, the carrier website shall notify the slice purchase * If the purchase was not successful, the carrier website shall notify the slice purchase * application using the JavaScript interface method * application using the JavaScript interface method * {@code SlicePurchaseWebInterface.notifyPurchaseFailed(code, reason)}, where {@code code} is the * {@code SlicePurchaseWebInterface.notifyPurchaseFailed(code, reason)}, where {@code code} is the Loading Loading @@ -74,7 +74,7 @@ public class SlicePurchaseActivity extends Activity { logd("onCreate: subId=" + subId + ", capability=" logd("onCreate: subId=" + subId + ", capability=" + TelephonyManager.convertPremiumCapabilityToString(mCapability) + ", url=" + url); + TelephonyManager.convertPremiumCapabilityToString(mCapability) + ", url=" + url); // Cancel network boost notification // Cancel performance boost notification SlicePurchaseBroadcastReceiver.cancelNotification(mApplicationContext, mCapability); SlicePurchaseBroadcastReceiver.cancelNotification(mApplicationContext, mCapability); // Verify purchase URL is valid // Verify purchase URL is valid Loading packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiver.java +38 −33 Original line number Original line Diff line number Diff line Loading @@ -53,9 +53,9 @@ import java.util.UUID; /** /** * The SlicePurchaseBroadcastReceiver listens for * The SlicePurchaseBroadcastReceiver listens for * {@link SlicePurchaseController#ACTION_START_SLICE_PURCHASE_APP} from the SlicePurchaseController * {@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 * in the phone process to start the slice purchase application. It displays the performance boost * notification to the user and will start the {@link SlicePurchaseActivity} to display the * notification to the user and will start the {@link SlicePurchaseActivity} to display the * {@link WebView} to purchase network boosts from the user's carrier. * {@link WebView} to purchase performance boosts from the user's carrier. */ */ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ private static final String TAG = "SlicePurchaseBroadcastReceiver"; private static final String TAG = "SlicePurchaseBroadcastReceiver"; Loading @@ -66,27 +66,29 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ */ */ private static final String UUID_BAD_PENDING_INTENT = "c360246e-95dc-4abf-9dc1-929a76cd7e53"; private static final String UUID_BAD_PENDING_INTENT = "c360246e-95dc-4abf-9dc1-929a76cd7e53"; /** Channel ID for the network boost notification. */ /** Channel ID for the performance boost notification. */ private static final String NETWORK_BOOST_NOTIFICATION_CHANNEL_ID = "network_boost"; private static final String PERFORMANCE_BOOST_NOTIFICATION_CHANNEL_ID = "performance_boost"; /** Tag for the network boost notification. */ /** Tag for the performance boost notification. */ public static final String NETWORK_BOOST_NOTIFICATION_TAG = "SlicePurchaseApp.Notification"; public static final String PERFORMANCE_BOOST_NOTIFICATION_TAG = "SlicePurchaseApp.Notification"; /** Action for when the user clicks the "Not now" button on the network boost notification. */ /** * Action for when the user clicks the "Not now" button on the performance boost notification. */ private static final String ACTION_NOTIFICATION_CANCELED = private static final String ACTION_NOTIFICATION_CANCELED = "com.android.phone.slice.action.NOTIFICATION_CANCELED"; "com.android.phone.slice.action.NOTIFICATION_CANCELED"; /** /** * A map of Intents sent by {@link SlicePurchaseController} for each capability. * A map of Intents sent by {@link SlicePurchaseController} for each capability. * If this map contains an Intent for a given capability, the network boost notification to * If this map contains an Intent for a given capability, the performance boost notification to * purchase the capability is visible to the user. * purchase the capability is visible to the user. * If this map does not contain an Intent for a given capability, either the capability was * If this map does not contain an Intent for a given capability, either the capability was * never requested or the {@link SlicePurchaseActivity} is visible to the user. * never requested or the {@link SlicePurchaseActivity} is visible to the user. * An Intent is added to this map when the network boost notification is displayed to the user * An Intent is added to this map when the performance boost notification is displayed to the * and removed from the map when the notification is canceled. * user and removed from the map when the notification is canceled. */ */ private static final Map<Integer, Intent> sIntents = new HashMap<>(); private static final Map<Integer, Intent> sIntents = new HashMap<>(); /** /** * Cancel the network boost notification for the given capability and * Cancel the performance boost notification for the given capability and * remove the corresponding notification intent from the map. * remove the corresponding notification intent from the map. * * * @param context The context to cancel the notification in. * @param context The context to cancel the notification in. Loading @@ -95,7 +97,7 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ public static void cancelNotification(@NonNull Context context, public static void cancelNotification(@NonNull Context context, @TelephonyManager.PremiumCapability int capability) { @TelephonyManager.PremiumCapability int capability) { context.getSystemService(NotificationManager.class).cancelAsUser( context.getSystemService(NotificationManager.class).cancelAsUser( NETWORK_BOOST_NOTIFICATION_TAG, capability, UserHandle.ALL); PERFORMANCE_BOOST_NOTIFICATION_TAG, capability, UserHandle.ALL); sIntents.remove(capability); sIntents.remove(capability); } } Loading Loading @@ -263,7 +265,7 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ onLocaleChanged(context); onLocaleChanged(context); break; break; case SlicePurchaseController.ACTION_START_SLICE_PURCHASE_APP: case SlicePurchaseController.ACTION_START_SLICE_PURCHASE_APP: onDisplayNetworkBoostNotification(context, intent, false); onDisplayPerformanceBoostNotification(context, intent, false); break; break; case SlicePurchaseController.ACTION_SLICE_PURCHASE_APP_RESPONSE_TIMEOUT: case SlicePurchaseController.ACTION_SLICE_PURCHASE_APP_RESPONSE_TIMEOUT: onTimeout(context, intent); onTimeout(context, intent); Loading @@ -283,13 +285,13 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ if (sIntents.get(capability) != null) { if (sIntents.get(capability) != null) { // Notification is active -- update notification for new locale // Notification is active -- update notification for new locale context.getSystemService(NotificationManager.class).cancelAsUser( context.getSystemService(NotificationManager.class).cancelAsUser( NETWORK_BOOST_NOTIFICATION_TAG, capability, UserHandle.ALL); PERFORMANCE_BOOST_NOTIFICATION_TAG, capability, UserHandle.ALL); onDisplayNetworkBoostNotification(context, sIntents.get(capability), true); onDisplayPerformanceBoostNotification(context, sIntents.get(capability), true); } } } } } } private void onDisplayNetworkBoostNotification(@NonNull Context context, private void onDisplayPerformanceBoostNotification(@NonNull Context context, @NonNull Intent intent, boolean repeat) { @NonNull Intent intent, boolean repeat) { if (!repeat && !isIntentValid(intent)) { if (!repeat && !isIntentValid(intent)) { sendSlicePurchaseAppResponse(intent, sendSlicePurchaseAppResponse(intent, Loading @@ -299,8 +301,8 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ Resources res = getResources(context); Resources res = getResources(context); NotificationChannel channel = new NotificationChannel( NotificationChannel channel = new NotificationChannel( NETWORK_BOOST_NOTIFICATION_CHANNEL_ID, PERFORMANCE_BOOST_NOTIFICATION_CHANNEL_ID, res.getString(R.string.network_boost_notification_channel), res.getString(R.string.performance_boost_notification_channel), NotificationManager.IMPORTANCE_DEFAULT); NotificationManager.IMPORTANCE_DEFAULT); // CarrierDefaultApp notifications are unblockable by default. Make this channel blockable // CarrierDefaultApp notifications are unblockable by default. Make this channel blockable // to allow users to disable notifications posted to this channel without affecting other // to allow users to disable notifications posted to this channel without affecting other Loading @@ -309,36 +311,39 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ context.getSystemService(NotificationManager.class).createNotificationChannel(channel); context.getSystemService(NotificationManager.class).createNotificationChannel(channel); Notification notification = Notification notification = new Notification.Builder(context, NETWORK_BOOST_NOTIFICATION_CHANNEL_ID) new Notification.Builder(context, PERFORMANCE_BOOST_NOTIFICATION_CHANNEL_ID) .setContentTitle(String.format(res.getString( .setContentTitle(String.format(res.getString( R.string.network_boost_notification_title), R.string.performance_boost_notification_title), intent.getStringExtra( intent.getStringExtra( SlicePurchaseController.EXTRA_REQUESTING_APP_NAME))) SlicePurchaseController.EXTRA_REQUESTING_APP_NAME))) .setContentText(res.getString(R.string.network_boost_notification_detail)) .setContentText(res.getString( .setSmallIcon(R.drawable.ic_network_boost) R.string.performance_boost_notification_detail)) .setSmallIcon(R.drawable.ic_performance_boost) .setContentIntent(createContentIntent(context, intent, 1)) .setContentIntent(createContentIntent(context, intent, 1)) .setDeleteIntent(intent.getParcelableExtra( .setDeleteIntent(intent.getParcelableExtra( SlicePurchaseController.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 // Add an action for the "Not now" button, which has the same behavior as // the user canceling or closing the notification. // the user canceling or closing the notification. .addAction(new Notification.Action.Builder( .addAction(new Notification.Action.Builder( Icon.createWithResource(context, R.drawable.ic_network_boost), Icon.createWithResource(context, R.drawable.ic_performance_boost), res.getString(R.string.network_boost_notification_button_not_now), res.getString( R.string.performance_boost_notification_button_not_now), createCanceledIntent(context, intent)).build()) createCanceledIntent(context, intent)).build()) // Add an action for the "Manage" button, which has the same behavior as // Add an action for the "Manage" button, which has the same behavior as // the user clicking on the notification. // the user clicking on the notification. .addAction(new Notification.Action.Builder( .addAction(new Notification.Action.Builder( Icon.createWithResource(context, R.drawable.ic_network_boost), Icon.createWithResource(context, R.drawable.ic_performance_boost), res.getString(R.string.network_boost_notification_button_manage), res.getString( R.string.performance_boost_notification_button_manage), createContentIntent(context, intent, 2)).build()) createContentIntent(context, intent, 2)).build()) .build(); .build(); int capability = intent.getIntExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY, int capability = intent.getIntExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY, SlicePurchaseController.PREMIUM_CAPABILITY_INVALID); SlicePurchaseController.PREMIUM_CAPABILITY_INVALID); logd((repeat ? "Update" : "Display") + " the network boost notification for capability " logd((repeat ? "Update" : "Display") + " the performance boost notification for capability " + TelephonyManager.convertPremiumCapabilityToString(capability)); + TelephonyManager.convertPremiumCapabilityToString(capability)); context.getSystemService(NotificationManager.class).notifyAsUser( context.getSystemService(NotificationManager.class).notifyAsUser( NETWORK_BOOST_NOTIFICATION_TAG, capability, notification, UserHandle.ALL); PERFORMANCE_BOOST_NOTIFICATION_TAG, capability, notification, UserHandle.ALL); if (!repeat) { if (!repeat) { sIntents.put(capability, intent); sIntents.put(capability, intent); sendSlicePurchaseAppResponse(intent, sendSlicePurchaseAppResponse(intent, Loading Loading @@ -376,7 +381,7 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ } } /** /** * Create the intent for when the user clicks on the "Manage" button on the network boost * Create the intent for when the user clicks on the "Manage" button on the performance boost * notification or the notification itself. This will open {@link SlicePurchaseActivity}. * notification or the notification itself. This will open {@link SlicePurchaseActivity}. * * * @param context The Context to create the intent for. * @param context The Context to create the intent for. Loading @@ -400,9 +405,9 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ } } /** /** * Create the canceled intent for when the user clicks the "Not now" button on the network boost * Create the canceled intent for when the user clicks the "Not now" button on the performance * notification. This will send {@link #ACTION_NOTIFICATION_CANCELED} and has the same function * boost notification. This will send {@link #ACTION_NOTIFICATION_CANCELED} and has the same * as if the user had canceled or removed the notification. * behavior as if the user had canceled or removed the notification. * * * @param context The Context to create the intent for. * @param context The Context to create the intent for. * @param intent The source Intent used to launch the slice purchase application. * @param intent The source Intent used to launch the slice purchase application. Loading @@ -427,7 +432,7 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ + " timed out."); + " timed out."); if (sIntents.get(capability) != null) { if (sIntents.get(capability) != null) { // Notification is still active -- cancel pending notification // Notification is still active -- cancel pending notification logd("Closing network boost notification since the user did not respond in time."); logd("Closing performance boost notification since the user did not respond in time."); cancelNotification(context, capability); cancelNotification(context, capability); } else { } else { // SlicePurchaseActivity is still active -- ignore timer // SlicePurchaseActivity is still active -- ignore timer Loading packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiverTest.java +11 −11 Original line number Original line Diff line number Diff line Loading @@ -172,13 +172,13 @@ public class SlicePurchaseBroadcastReceiverTest { } } @Test @Test public void testDisplayNetworkBoostNotification() throws Exception { public void testDisplayPerformanceBoostNotification() throws Exception { displayNetworkBoostNotification(); displayPerformanceBoostNotification(); // verify network boost notification was shown // verify performance boost notification was shown ArgumentCaptor<Notification> captor = ArgumentCaptor.forClass(Notification.class); ArgumentCaptor<Notification> captor = ArgumentCaptor.forClass(Notification.class); verify(mNotificationManager).notifyAsUser( verify(mNotificationManager).notifyAsUser( eq(SlicePurchaseBroadcastReceiver.NETWORK_BOOST_NOTIFICATION_TAG), eq(SlicePurchaseBroadcastReceiver.PERFORMANCE_BOOST_NOTIFICATION_TAG), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), captor.capture(), captor.capture(), eq(UserHandle.ALL)); eq(UserHandle.ALL)); Loading @@ -195,7 +195,7 @@ public class SlicePurchaseBroadcastReceiverTest { verify(mNotificationShownIntent).send(); verify(mNotificationShownIntent).send(); } } private void displayNetworkBoostNotification() { private void displayPerformanceBoostNotification() { // set up pending intents // set up pending intents doReturn(TelephonyManager.PHONE_PROCESS_NAME).when(mPendingIntent).getCreatorPackage(); doReturn(TelephonyManager.PHONE_PROCESS_NAME).when(mPendingIntent).getCreatorPackage(); doReturn(true).when(mPendingIntent).isBroadcast(); doReturn(true).when(mPendingIntent).isBroadcast(); Loading Loading @@ -244,14 +244,14 @@ public class SlicePurchaseBroadcastReceiverTest { // verify notification was canceled // verify notification was canceled verify(mNotificationManager).cancelAsUser( verify(mNotificationManager).cancelAsUser( eq(SlicePurchaseBroadcastReceiver.NETWORK_BOOST_NOTIFICATION_TAG), eq(SlicePurchaseBroadcastReceiver.PERFORMANCE_BOOST_NOTIFICATION_TAG), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(UserHandle.ALL)); eq(UserHandle.ALL)); } } @Test @Test public void testNotificationTimeout() throws Exception { public void testNotificationTimeout() throws Exception { displayNetworkBoostNotification(); displayPerformanceBoostNotification(); // send ACTION_SLICE_PURCHASE_APP_RESPONSE_TIMEOUT // send ACTION_SLICE_PURCHASE_APP_RESPONSE_TIMEOUT doReturn(SlicePurchaseController.ACTION_SLICE_PURCHASE_APP_RESPONSE_TIMEOUT).when(mIntent) doReturn(SlicePurchaseController.ACTION_SLICE_PURCHASE_APP_RESPONSE_TIMEOUT).when(mIntent) Loading @@ -262,7 +262,7 @@ public class SlicePurchaseBroadcastReceiverTest { // verify notification was canceled // verify notification was canceled verify(mNotificationManager).cancelAsUser( verify(mNotificationManager).cancelAsUser( eq(SlicePurchaseBroadcastReceiver.NETWORK_BOOST_NOTIFICATION_TAG), eq(SlicePurchaseBroadcastReceiver.PERFORMANCE_BOOST_NOTIFICATION_TAG), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(UserHandle.ALL)); eq(UserHandle.ALL)); } } Loading @@ -274,7 +274,7 @@ public class SlicePurchaseBroadcastReceiverTest { Locale before = getLocale(); Locale before = getLocale(); // display notification // display notification displayNetworkBoostNotification(); displayPerformanceBoostNotification(); clearInvocations(mNotificationManager); clearInvocations(mNotificationManager); clearInvocations(mNotificationShownIntent); clearInvocations(mNotificationShownIntent); Loading @@ -291,11 +291,11 @@ public class SlicePurchaseBroadcastReceiverTest { // verify notification was updated and SlicePurchaseController was not notified // verify notification was updated and SlicePurchaseController was not notified verify(mNotificationManager).cancelAsUser( verify(mNotificationManager).cancelAsUser( eq(SlicePurchaseBroadcastReceiver.NETWORK_BOOST_NOTIFICATION_TAG), eq(SlicePurchaseBroadcastReceiver.PERFORMANCE_BOOST_NOTIFICATION_TAG), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(UserHandle.ALL)); eq(UserHandle.ALL)); verify(mNotificationManager).notifyAsUser( verify(mNotificationManager).notifyAsUser( eq(SlicePurchaseBroadcastReceiver.NETWORK_BOOST_NOTIFICATION_TAG), eq(SlicePurchaseBroadcastReceiver.PERFORMANCE_BOOST_NOTIFICATION_TAG), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), any(Notification.class), any(Notification.class), eq(UserHandle.ALL)); eq(UserHandle.ALL)); Loading Loading
packages/CarrierDefaultApp/res/drawable/ic_network_boost.xml→packages/CarrierDefaultApp/res/drawable/ic_performance_boost.xml +0 −0 File moved. View file
packages/CarrierDefaultApp/res/values/strings.xml +11 −11 Original line number Original line Diff line number Diff line Loading @@ -14,17 +14,17 @@ <string name="ssl_error_example">For example, the login page may not belong to the organization shown.</string> <string name="ssl_error_example">For example, the login page may not belong to the organization shown.</string> <string name="ssl_error_continue">Continue anyway via browser</string> <string name="ssl_error_continue">Continue anyway via browser</string> <!-- Telephony notification channel name for network boost notifications. --> <!-- Telephony notification channel name for performance boost notifications. --> <string name="network_boost_notification_channel">Network boost</string> <string name="performance_boost_notification_channel">Performance boost</string> <!-- Notification title text for the network boost notification. --> <!-- Notification title text for the performance boost notification. --> <string name="network_boost_notification_title">%s recommends a data boost</string> <string name="performance_boost_notification_title">%s recommends a performance boost</string> <!-- Notification detail text for the network boost notification. --> <!-- Notification detail text for the performance boost notification. --> <string name="network_boost_notification_detail">Buy a network boost for better performance</string> <string name="performance_boost_notification_detail">Buy a performance boost for better network performance</string> <!-- Notification button text to cancel the network boost notification. --> <!-- Notification button text to cancel the performance boost notification. --> <string name="network_boost_notification_button_not_now">Not now</string> <string name="performance_boost_notification_button_not_now">Not now</string> <!-- Notification button text to manage the network boost notification. --> <!-- Notification button text to manage the performance boost notification. --> <string name="network_boost_notification_button_manage">Manage</string> <string name="performance_boost_notification_button_manage">Manage</string> <!-- Label to display when the slice purchase application opens. --> <!-- Label to display when the slice purchase application opens. --> <string name="slice_purchase_app_label">Purchase a network boost.</string> <string name="slice_purchase_app_label">Purchase a performance boost.</string> </resources> </resources>
packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java +3 −3 Original line number Original line Diff line number Diff line Loading @@ -34,7 +34,7 @@ import java.net.URL; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit; /** /** * Activity that launches when the user clicks on the network boost notification. * Activity that launches when the user clicks on the performance boost notification. * This will open a {@link WebView} for the carrier website to allow the user to complete the * This will open a {@link WebView} for the carrier website to allow the user to complete the * premium capability purchase. * premium capability purchase. * The carrier website can get the requested premium capability using the JavaScript interface * The carrier website can get the requested premium capability using the JavaScript interface Loading @@ -42,7 +42,7 @@ import java.util.concurrent.TimeUnit; * If the purchase is successful, the carrier website shall notify the slice purchase application * If the purchase is successful, the carrier website shall notify the slice purchase application * using the JavaScript interface method * using the JavaScript interface method * {@code SlicePurchaseWebInterface.notifyPurchaseSuccessful(duration)}, where {@code duration} is * {@code SlicePurchaseWebInterface.notifyPurchaseSuccessful(duration)}, where {@code duration} is * the optional duration of the network boost. * the optional duration of the performance boost. * If the purchase was not successful, the carrier website shall notify the slice purchase * If the purchase was not successful, the carrier website shall notify the slice purchase * application using the JavaScript interface method * application using the JavaScript interface method * {@code SlicePurchaseWebInterface.notifyPurchaseFailed(code, reason)}, where {@code code} is the * {@code SlicePurchaseWebInterface.notifyPurchaseFailed(code, reason)}, where {@code code} is the Loading Loading @@ -74,7 +74,7 @@ public class SlicePurchaseActivity extends Activity { logd("onCreate: subId=" + subId + ", capability=" logd("onCreate: subId=" + subId + ", capability=" + TelephonyManager.convertPremiumCapabilityToString(mCapability) + ", url=" + url); + TelephonyManager.convertPremiumCapabilityToString(mCapability) + ", url=" + url); // Cancel network boost notification // Cancel performance boost notification SlicePurchaseBroadcastReceiver.cancelNotification(mApplicationContext, mCapability); SlicePurchaseBroadcastReceiver.cancelNotification(mApplicationContext, mCapability); // Verify purchase URL is valid // Verify purchase URL is valid Loading
packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiver.java +38 −33 Original line number Original line Diff line number Diff line Loading @@ -53,9 +53,9 @@ import java.util.UUID; /** /** * The SlicePurchaseBroadcastReceiver listens for * The SlicePurchaseBroadcastReceiver listens for * {@link SlicePurchaseController#ACTION_START_SLICE_PURCHASE_APP} from the SlicePurchaseController * {@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 * in the phone process to start the slice purchase application. It displays the performance boost * notification to the user and will start the {@link SlicePurchaseActivity} to display the * notification to the user and will start the {@link SlicePurchaseActivity} to display the * {@link WebView} to purchase network boosts from the user's carrier. * {@link WebView} to purchase performance boosts from the user's carrier. */ */ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ private static final String TAG = "SlicePurchaseBroadcastReceiver"; private static final String TAG = "SlicePurchaseBroadcastReceiver"; Loading @@ -66,27 +66,29 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ */ */ private static final String UUID_BAD_PENDING_INTENT = "c360246e-95dc-4abf-9dc1-929a76cd7e53"; private static final String UUID_BAD_PENDING_INTENT = "c360246e-95dc-4abf-9dc1-929a76cd7e53"; /** Channel ID for the network boost notification. */ /** Channel ID for the performance boost notification. */ private static final String NETWORK_BOOST_NOTIFICATION_CHANNEL_ID = "network_boost"; private static final String PERFORMANCE_BOOST_NOTIFICATION_CHANNEL_ID = "performance_boost"; /** Tag for the network boost notification. */ /** Tag for the performance boost notification. */ public static final String NETWORK_BOOST_NOTIFICATION_TAG = "SlicePurchaseApp.Notification"; public static final String PERFORMANCE_BOOST_NOTIFICATION_TAG = "SlicePurchaseApp.Notification"; /** Action for when the user clicks the "Not now" button on the network boost notification. */ /** * Action for when the user clicks the "Not now" button on the performance boost notification. */ private static final String ACTION_NOTIFICATION_CANCELED = private static final String ACTION_NOTIFICATION_CANCELED = "com.android.phone.slice.action.NOTIFICATION_CANCELED"; "com.android.phone.slice.action.NOTIFICATION_CANCELED"; /** /** * A map of Intents sent by {@link SlicePurchaseController} for each capability. * A map of Intents sent by {@link SlicePurchaseController} for each capability. * If this map contains an Intent for a given capability, the network boost notification to * If this map contains an Intent for a given capability, the performance boost notification to * purchase the capability is visible to the user. * purchase the capability is visible to the user. * If this map does not contain an Intent for a given capability, either the capability was * If this map does not contain an Intent for a given capability, either the capability was * never requested or the {@link SlicePurchaseActivity} is visible to the user. * never requested or the {@link SlicePurchaseActivity} is visible to the user. * An Intent is added to this map when the network boost notification is displayed to the user * An Intent is added to this map when the performance boost notification is displayed to the * and removed from the map when the notification is canceled. * user and removed from the map when the notification is canceled. */ */ private static final Map<Integer, Intent> sIntents = new HashMap<>(); private static final Map<Integer, Intent> sIntents = new HashMap<>(); /** /** * Cancel the network boost notification for the given capability and * Cancel the performance boost notification for the given capability and * remove the corresponding notification intent from the map. * remove the corresponding notification intent from the map. * * * @param context The context to cancel the notification in. * @param context The context to cancel the notification in. Loading @@ -95,7 +97,7 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ public static void cancelNotification(@NonNull Context context, public static void cancelNotification(@NonNull Context context, @TelephonyManager.PremiumCapability int capability) { @TelephonyManager.PremiumCapability int capability) { context.getSystemService(NotificationManager.class).cancelAsUser( context.getSystemService(NotificationManager.class).cancelAsUser( NETWORK_BOOST_NOTIFICATION_TAG, capability, UserHandle.ALL); PERFORMANCE_BOOST_NOTIFICATION_TAG, capability, UserHandle.ALL); sIntents.remove(capability); sIntents.remove(capability); } } Loading Loading @@ -263,7 +265,7 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ onLocaleChanged(context); onLocaleChanged(context); break; break; case SlicePurchaseController.ACTION_START_SLICE_PURCHASE_APP: case SlicePurchaseController.ACTION_START_SLICE_PURCHASE_APP: onDisplayNetworkBoostNotification(context, intent, false); onDisplayPerformanceBoostNotification(context, intent, false); break; break; case SlicePurchaseController.ACTION_SLICE_PURCHASE_APP_RESPONSE_TIMEOUT: case SlicePurchaseController.ACTION_SLICE_PURCHASE_APP_RESPONSE_TIMEOUT: onTimeout(context, intent); onTimeout(context, intent); Loading @@ -283,13 +285,13 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ if (sIntents.get(capability) != null) { if (sIntents.get(capability) != null) { // Notification is active -- update notification for new locale // Notification is active -- update notification for new locale context.getSystemService(NotificationManager.class).cancelAsUser( context.getSystemService(NotificationManager.class).cancelAsUser( NETWORK_BOOST_NOTIFICATION_TAG, capability, UserHandle.ALL); PERFORMANCE_BOOST_NOTIFICATION_TAG, capability, UserHandle.ALL); onDisplayNetworkBoostNotification(context, sIntents.get(capability), true); onDisplayPerformanceBoostNotification(context, sIntents.get(capability), true); } } } } } } private void onDisplayNetworkBoostNotification(@NonNull Context context, private void onDisplayPerformanceBoostNotification(@NonNull Context context, @NonNull Intent intent, boolean repeat) { @NonNull Intent intent, boolean repeat) { if (!repeat && !isIntentValid(intent)) { if (!repeat && !isIntentValid(intent)) { sendSlicePurchaseAppResponse(intent, sendSlicePurchaseAppResponse(intent, Loading @@ -299,8 +301,8 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ Resources res = getResources(context); Resources res = getResources(context); NotificationChannel channel = new NotificationChannel( NotificationChannel channel = new NotificationChannel( NETWORK_BOOST_NOTIFICATION_CHANNEL_ID, PERFORMANCE_BOOST_NOTIFICATION_CHANNEL_ID, res.getString(R.string.network_boost_notification_channel), res.getString(R.string.performance_boost_notification_channel), NotificationManager.IMPORTANCE_DEFAULT); NotificationManager.IMPORTANCE_DEFAULT); // CarrierDefaultApp notifications are unblockable by default. Make this channel blockable // CarrierDefaultApp notifications are unblockable by default. Make this channel blockable // to allow users to disable notifications posted to this channel without affecting other // to allow users to disable notifications posted to this channel without affecting other Loading @@ -309,36 +311,39 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ context.getSystemService(NotificationManager.class).createNotificationChannel(channel); context.getSystemService(NotificationManager.class).createNotificationChannel(channel); Notification notification = Notification notification = new Notification.Builder(context, NETWORK_BOOST_NOTIFICATION_CHANNEL_ID) new Notification.Builder(context, PERFORMANCE_BOOST_NOTIFICATION_CHANNEL_ID) .setContentTitle(String.format(res.getString( .setContentTitle(String.format(res.getString( R.string.network_boost_notification_title), R.string.performance_boost_notification_title), intent.getStringExtra( intent.getStringExtra( SlicePurchaseController.EXTRA_REQUESTING_APP_NAME))) SlicePurchaseController.EXTRA_REQUESTING_APP_NAME))) .setContentText(res.getString(R.string.network_boost_notification_detail)) .setContentText(res.getString( .setSmallIcon(R.drawable.ic_network_boost) R.string.performance_boost_notification_detail)) .setSmallIcon(R.drawable.ic_performance_boost) .setContentIntent(createContentIntent(context, intent, 1)) .setContentIntent(createContentIntent(context, intent, 1)) .setDeleteIntent(intent.getParcelableExtra( .setDeleteIntent(intent.getParcelableExtra( SlicePurchaseController.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 // Add an action for the "Not now" button, which has the same behavior as // the user canceling or closing the notification. // the user canceling or closing the notification. .addAction(new Notification.Action.Builder( .addAction(new Notification.Action.Builder( Icon.createWithResource(context, R.drawable.ic_network_boost), Icon.createWithResource(context, R.drawable.ic_performance_boost), res.getString(R.string.network_boost_notification_button_not_now), res.getString( R.string.performance_boost_notification_button_not_now), createCanceledIntent(context, intent)).build()) createCanceledIntent(context, intent)).build()) // Add an action for the "Manage" button, which has the same behavior as // Add an action for the "Manage" button, which has the same behavior as // the user clicking on the notification. // the user clicking on the notification. .addAction(new Notification.Action.Builder( .addAction(new Notification.Action.Builder( Icon.createWithResource(context, R.drawable.ic_network_boost), Icon.createWithResource(context, R.drawable.ic_performance_boost), res.getString(R.string.network_boost_notification_button_manage), res.getString( R.string.performance_boost_notification_button_manage), createContentIntent(context, intent, 2)).build()) createContentIntent(context, intent, 2)).build()) .build(); .build(); int capability = intent.getIntExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY, int capability = intent.getIntExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY, SlicePurchaseController.PREMIUM_CAPABILITY_INVALID); SlicePurchaseController.PREMIUM_CAPABILITY_INVALID); logd((repeat ? "Update" : "Display") + " the network boost notification for capability " logd((repeat ? "Update" : "Display") + " the performance boost notification for capability " + TelephonyManager.convertPremiumCapabilityToString(capability)); + TelephonyManager.convertPremiumCapabilityToString(capability)); context.getSystemService(NotificationManager.class).notifyAsUser( context.getSystemService(NotificationManager.class).notifyAsUser( NETWORK_BOOST_NOTIFICATION_TAG, capability, notification, UserHandle.ALL); PERFORMANCE_BOOST_NOTIFICATION_TAG, capability, notification, UserHandle.ALL); if (!repeat) { if (!repeat) { sIntents.put(capability, intent); sIntents.put(capability, intent); sendSlicePurchaseAppResponse(intent, sendSlicePurchaseAppResponse(intent, Loading Loading @@ -376,7 +381,7 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ } } /** /** * Create the intent for when the user clicks on the "Manage" button on the network boost * Create the intent for when the user clicks on the "Manage" button on the performance boost * notification or the notification itself. This will open {@link SlicePurchaseActivity}. * notification or the notification itself. This will open {@link SlicePurchaseActivity}. * * * @param context The Context to create the intent for. * @param context The Context to create the intent for. Loading @@ -400,9 +405,9 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ } } /** /** * Create the canceled intent for when the user clicks the "Not now" button on the network boost * Create the canceled intent for when the user clicks the "Not now" button on the performance * notification. This will send {@link #ACTION_NOTIFICATION_CANCELED} and has the same function * boost notification. This will send {@link #ACTION_NOTIFICATION_CANCELED} and has the same * as if the user had canceled or removed the notification. * behavior as if the user had canceled or removed the notification. * * * @param context The Context to create the intent for. * @param context The Context to create the intent for. * @param intent The source Intent used to launch the slice purchase application. * @param intent The source Intent used to launch the slice purchase application. Loading @@ -427,7 +432,7 @@ public class SlicePurchaseBroadcastReceiver extends BroadcastReceiver{ + " timed out."); + " timed out."); if (sIntents.get(capability) != null) { if (sIntents.get(capability) != null) { // Notification is still active -- cancel pending notification // Notification is still active -- cancel pending notification logd("Closing network boost notification since the user did not respond in time."); logd("Closing performance boost notification since the user did not respond in time."); cancelNotification(context, capability); cancelNotification(context, capability); } else { } else { // SlicePurchaseActivity is still active -- ignore timer // SlicePurchaseActivity is still active -- ignore timer Loading
packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseBroadcastReceiverTest.java +11 −11 Original line number Original line Diff line number Diff line Loading @@ -172,13 +172,13 @@ public class SlicePurchaseBroadcastReceiverTest { } } @Test @Test public void testDisplayNetworkBoostNotification() throws Exception { public void testDisplayPerformanceBoostNotification() throws Exception { displayNetworkBoostNotification(); displayPerformanceBoostNotification(); // verify network boost notification was shown // verify performance boost notification was shown ArgumentCaptor<Notification> captor = ArgumentCaptor.forClass(Notification.class); ArgumentCaptor<Notification> captor = ArgumentCaptor.forClass(Notification.class); verify(mNotificationManager).notifyAsUser( verify(mNotificationManager).notifyAsUser( eq(SlicePurchaseBroadcastReceiver.NETWORK_BOOST_NOTIFICATION_TAG), eq(SlicePurchaseBroadcastReceiver.PERFORMANCE_BOOST_NOTIFICATION_TAG), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), captor.capture(), captor.capture(), eq(UserHandle.ALL)); eq(UserHandle.ALL)); Loading @@ -195,7 +195,7 @@ public class SlicePurchaseBroadcastReceiverTest { verify(mNotificationShownIntent).send(); verify(mNotificationShownIntent).send(); } } private void displayNetworkBoostNotification() { private void displayPerformanceBoostNotification() { // set up pending intents // set up pending intents doReturn(TelephonyManager.PHONE_PROCESS_NAME).when(mPendingIntent).getCreatorPackage(); doReturn(TelephonyManager.PHONE_PROCESS_NAME).when(mPendingIntent).getCreatorPackage(); doReturn(true).when(mPendingIntent).isBroadcast(); doReturn(true).when(mPendingIntent).isBroadcast(); Loading Loading @@ -244,14 +244,14 @@ public class SlicePurchaseBroadcastReceiverTest { // verify notification was canceled // verify notification was canceled verify(mNotificationManager).cancelAsUser( verify(mNotificationManager).cancelAsUser( eq(SlicePurchaseBroadcastReceiver.NETWORK_BOOST_NOTIFICATION_TAG), eq(SlicePurchaseBroadcastReceiver.PERFORMANCE_BOOST_NOTIFICATION_TAG), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(UserHandle.ALL)); eq(UserHandle.ALL)); } } @Test @Test public void testNotificationTimeout() throws Exception { public void testNotificationTimeout() throws Exception { displayNetworkBoostNotification(); displayPerformanceBoostNotification(); // send ACTION_SLICE_PURCHASE_APP_RESPONSE_TIMEOUT // send ACTION_SLICE_PURCHASE_APP_RESPONSE_TIMEOUT doReturn(SlicePurchaseController.ACTION_SLICE_PURCHASE_APP_RESPONSE_TIMEOUT).when(mIntent) doReturn(SlicePurchaseController.ACTION_SLICE_PURCHASE_APP_RESPONSE_TIMEOUT).when(mIntent) Loading @@ -262,7 +262,7 @@ public class SlicePurchaseBroadcastReceiverTest { // verify notification was canceled // verify notification was canceled verify(mNotificationManager).cancelAsUser( verify(mNotificationManager).cancelAsUser( eq(SlicePurchaseBroadcastReceiver.NETWORK_BOOST_NOTIFICATION_TAG), eq(SlicePurchaseBroadcastReceiver.PERFORMANCE_BOOST_NOTIFICATION_TAG), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(UserHandle.ALL)); eq(UserHandle.ALL)); } } Loading @@ -274,7 +274,7 @@ public class SlicePurchaseBroadcastReceiverTest { Locale before = getLocale(); Locale before = getLocale(); // display notification // display notification displayNetworkBoostNotification(); displayPerformanceBoostNotification(); clearInvocations(mNotificationManager); clearInvocations(mNotificationManager); clearInvocations(mNotificationShownIntent); clearInvocations(mNotificationShownIntent); Loading @@ -291,11 +291,11 @@ public class SlicePurchaseBroadcastReceiverTest { // verify notification was updated and SlicePurchaseController was not notified // verify notification was updated and SlicePurchaseController was not notified verify(mNotificationManager).cancelAsUser( verify(mNotificationManager).cancelAsUser( eq(SlicePurchaseBroadcastReceiver.NETWORK_BOOST_NOTIFICATION_TAG), eq(SlicePurchaseBroadcastReceiver.PERFORMANCE_BOOST_NOTIFICATION_TAG), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(UserHandle.ALL)); eq(UserHandle.ALL)); verify(mNotificationManager).notifyAsUser( verify(mNotificationManager).notifyAsUser( eq(SlicePurchaseBroadcastReceiver.NETWORK_BOOST_NOTIFICATION_TAG), eq(SlicePurchaseBroadcastReceiver.PERFORMANCE_BOOST_NOTIFICATION_TAG), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), eq(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY), any(Notification.class), any(Notification.class), eq(UserHandle.ALL)); eq(UserHandle.ALL)); Loading