Support testing Direct Reply with EditTextVariations on API 24/25

This is a follow up CL to my previous CL [1], which enabled us to test
Direct-Reply with EditTextVariations.

What this CL does are:

 * Specyfing min_sdk_version to avoid INSTALL_FAILED_OLDER_SDK error
   when installing on older devices.
 * Avoiding NoSuchMethodError on pre-O devices where
   Notification.Builder does not have a constructor that takes
   notification channel.
 * Fixing a race condition where notification can be sent before
   notification channel is created.

 [1]: Iafffcc7d138b0f502116a5e557f0c3f17e9d0b73
      da2486fd63

Bug: 122957841
Test: Made sure that we can install EditTextVariations on N devices
      and "Direct-Reply" on EditTextVariations works there.
Change-Id: Ib4fbd447608b111e763fde4287226cf7e206e65e
This commit is contained in:
Yohei Yukawa 2019-02-05 22:46:42 -08:00
parent a55797bfba
commit bdf7d6f56d
2 changed files with 22 additions and 18 deletions

View File

@ -18,4 +18,5 @@ android_test {
srcs: ["src/**/*.java"], srcs: ["src/**/*.java"],
sdk_version: "current", sdk_version: "current",
min_sdk_version: "11",
} }

View File

@ -38,28 +38,33 @@ final class NotificationUtils {
private static final String CHANNEL_NAME = "Channel Name"; private static final String CHANNEL_NAME = "Channel Name";
private static final String CHANNEL_DESCRIPTION = "Channel Description"; private static final String CHANNEL_DESCRIPTION = "Channel Description";
private static final String CHANNEL_ID = "Channel ID"; private static final String CHANNEL_ID = "Channel ID";
private static final AtomicBoolean sNotificationChannelInitialized = new AtomicBoolean();
private static final AtomicInteger sNextNotificationId = new AtomicInteger(1); private static final AtomicInteger sNextNotificationId = new AtomicInteger(1);
private static final Object sLock = new Object();
private static boolean sNotificationChannelInitialized = false;
static final boolean NOTIFICATION_CHANNEL_REQUIRED =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
static final boolean DIRECT_REPLY_SUPPORTED = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N; static final boolean DIRECT_REPLY_SUPPORTED = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;
static void ensureNotificationChannel(Context context) { private static Notification.Builder createNotificationBuilder(Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { if (!NOTIFICATION_CHANNEL_REQUIRED) {
// NotificationChannel is not implemented. No need to set up notification channel. // NotificationChannel is not implemented. No need to set up notification channel.
return; return new Notification.Builder(context);
}
if (!sNotificationChannelInitialized.compareAndSet(false, true)) {
// Already initialized.
return;
} }
// Create the NotificationChannel // Make sure that a notification channel is created *before* we send a notification.
final NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, synchronized (sLock) {
NotificationManager.IMPORTANCE_DEFAULT); if (!sNotificationChannelInitialized) {
channel.setDescription(CHANNEL_DESCRIPTION); final NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
// Register the channel with the system; you can't change the importance CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
// or other notification behaviors after this channel.setDescription(CHANNEL_DESCRIPTION);
context.getSystemService(NotificationManager.class).createNotificationChannel(channel); context.getSystemService(NotificationManager.class)
.createNotificationChannel(channel);
sNotificationChannelInitialized = true;
}
}
return new Notification.Builder(context, CHANNEL_ID);
} }
static void sendDirectReplyNotification(Context context) { static void sendDirectReplyNotification(Context context) {
@ -68,8 +73,6 @@ final class NotificationUtils {
return; return;
} }
ensureNotificationChannel(context);
RemoteInput remoteInput = new RemoteInput.Builder(KEY_REPLY) RemoteInput remoteInput = new RemoteInput.Builder(KEY_REPLY)
.setLabel("Reply Label") .setLabel("Reply Label")
.build(); .build();
@ -80,7 +83,7 @@ final class NotificationUtils {
new Notification.Action.Builder(null, "Direct Reply Test", pendingIntent) new Notification.Action.Builder(null, "Direct Reply Test", pendingIntent)
.addRemoteInput(remoteInput) .addRemoteInput(remoteInput)
.build(); .build();
final Notification notification = new Notification.Builder(context, CHANNEL_ID) final Notification notification = createNotificationBuilder(context)
.setContentText("Content Title") .setContentText("Content Title")
.setSmallIcon(R.drawable.ic_launcher) .setSmallIcon(R.drawable.ic_launcher)
.setContentText("Message from " + UserHandle.getUserHandleForUid(Process.myUid())) .setContentText("Message from " + UserHandle.getUserHandleForUid(Process.myUid()))