Skip to content

Commit dd1967f

Browse files
authored
Add InterruptionLevel to notification trigger API (#4205)
* Add InterruptionLevel to API * Move interruption and priority levels to InterruptionLevel enum * Mark interruptionLevel as @nonnull
1 parent bfa8ca1 commit dd1967f

File tree

9 files changed

+136
-59
lines changed

9 files changed

+136
-59
lines changed

firebase-appdistribution-api/api.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ package com.google.firebase.appdistribution {
1818
method @NonNull public com.google.android.gms.tasks.Task<com.google.firebase.appdistribution.AppDistributionRelease> checkForNewRelease();
1919
method @NonNull public static com.google.firebase.appdistribution.FirebaseAppDistribution getInstance();
2020
method public boolean isTesterSignedIn();
21-
method public void showFeedbackNotification(int, int);
22-
method public void showFeedbackNotification(@NonNull CharSequence, int);
21+
method public void showFeedbackNotification(int, @NonNull com.google.firebase.appdistribution.InterruptionLevel);
22+
method public void showFeedbackNotification(@NonNull CharSequence, @NonNull com.google.firebase.appdistribution.InterruptionLevel);
2323
method @NonNull public com.google.android.gms.tasks.Task<java.lang.Void> signInTester();
2424
method public void signOutTester();
2525
method public void startFeedback(int);
@@ -49,6 +49,14 @@ package com.google.firebase.appdistribution {
4949
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status UPDATE_NOT_AVAILABLE;
5050
}
5151

52+
public enum InterruptionLevel {
53+
enum_constant public static final com.google.firebase.appdistribution.InterruptionLevel DEFAULT;
54+
enum_constant public static final com.google.firebase.appdistribution.InterruptionLevel HIGH;
55+
enum_constant public static final com.google.firebase.appdistribution.InterruptionLevel LOW;
56+
enum_constant public static final com.google.firebase.appdistribution.InterruptionLevel MAX;
57+
enum_constant public static final com.google.firebase.appdistribution.InterruptionLevel MIN;
58+
}
59+
5260
public interface OnProgressListener {
5361
method public void onProgressUpdate(@NonNull com.google.firebase.appdistribution.UpdateProgress);
5462
}

firebase-appdistribution-api/src/main/java/com/google/firebase/appdistribution/FirebaseAppDistribution.java

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@
1515
package com.google.firebase.appdistribution;
1616

1717
import android.app.Activity;
18-
import android.app.NotificationChannel;
1918
import android.net.Uri;
2019
import androidx.annotation.NonNull;
2120
import androidx.annotation.Nullable;
22-
import androidx.core.app.NotificationCompat;
2321
import com.google.android.gms.tasks.Task;
2422
import com.google.firebase.FirebaseApp;
2523
import com.google.firebase.appdistribution.internal.FirebaseAppDistributionProxy;
@@ -202,17 +200,14 @@ public interface FirebaseAppDistribution {
202200
* <li>Starts a full screen activity for the tester to compose and submit the feedback
203201
* </ol>
204202
*
205-
* <p>On Android 8 and above, the notification will be created in its own notification channel.
206-
*
207203
* @param infoTextResourceId string resource ID of text to display to the tester before collecting
208204
* feedback data (e.g. Terms and Conditions)
209-
* @param importance the level of interruption for the feedback notification channel. Once the
210-
* channel's importance is set it cannot be changed except by the user. See {@link
211-
* NotificationChannel#setImportance}. On platforms below Android 8, the importance will be
212-
* translated into a comparable notification priority (see {@link
213-
* NotificationCompat.Builder#setPriority}).
205+
* @param interruptionLevel the level of interruption for the feedback notification. On platforms
206+
* below Android 8, this corresponds to a notification channel importance and once set cannot
207+
* be changed except by the user.
214208
*/
215-
void showFeedbackNotification(int infoTextResourceId, int importance);
209+
void showFeedbackNotification(
210+
int infoTextResourceId, @NonNull InterruptionLevel interruptionLevel);
216211

217212
/**
218213
* Displays a notification that, when tapped, will take a screenshot of the current activity, then
@@ -233,17 +228,14 @@ public interface FirebaseAppDistribution {
233228
* <li>Starts a full screen activity for the tester to compose and submit the feedback
234229
* </ol>
235230
*
236-
* <p>On Android 8 and above, the notification will be created in its own notification channel.
237-
*
238231
* @param infoText text to display to the tester before collecting feedback data (e.g. Terms and
239232
* Conditions)
240-
* @param importance the level of interruption for the feedback notification channel. Once the
241-
* channel's importance is set it cannot be changed except by the user. See {@link
242-
* NotificationChannel#setImportance}. On platforms below Android 8, the importance will be
243-
* translated into a comparable notification priority (see {@link
244-
* NotificationCompat.Builder#setPriority}).
233+
* @param interruptionLevel the level of interruption for the feedback notification. On platforms
234+
* below Android 8, this corresponds to a notification channel importance and once set cannot
235+
* be changed except by the user.
245236
*/
246-
void showFeedbackNotification(@NonNull CharSequence infoText, int importance);
237+
void showFeedbackNotification(
238+
@NonNull CharSequence infoText, @NonNull InterruptionLevel interruptionLevel);
247239

248240
/**
249241
* Hides the notification shown with {@link #showFeedbackNotification}.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.firebase.appdistribution;
16+
17+
import android.app.NotificationManager;
18+
import androidx.core.app.NotificationCompat;
19+
20+
/** An enum specifying the level of interruption of a notification when it is created. */
21+
public enum InterruptionLevel {
22+
23+
/**
24+
* Minimum interruption level.
25+
*
26+
* <p>Translates to {@link NotificationManager#IMPORTANCE_MIN} on Android O+ and {@link
27+
* NotificationCompat#PRIORITY_MIN} on older platforms.
28+
*/
29+
MIN(NotificationManager.IMPORTANCE_MIN, NotificationCompat.PRIORITY_MIN),
30+
31+
/**
32+
* Low interruption level.
33+
*
34+
* <p>Translates to {@link NotificationManager#IMPORTANCE_LOW} on Android O+ and {@link
35+
* NotificationCompat#PRIORITY_LOW} on older platforms.
36+
*/
37+
LOW(NotificationManager.IMPORTANCE_LOW, NotificationCompat.PRIORITY_LOW),
38+
39+
/**
40+
* Default interruption level.
41+
*
42+
* <p>Translates to {@link NotificationManager#IMPORTANCE_DEFAULT} on Android O+ and {@link
43+
* NotificationCompat#PRIORITY_DEFAULT} on older platforms.
44+
*/
45+
DEFAULT(NotificationManager.IMPORTANCE_DEFAULT, NotificationCompat.PRIORITY_DEFAULT),
46+
47+
/**
48+
* High interruption level.
49+
*
50+
* <p>Translates to {@link NotificationManager#IMPORTANCE_HIGH} on Android O+ and {@link
51+
* NotificationCompat#PRIORITY_HIGH} on older platforms.
52+
*/
53+
HIGH(NotificationManager.IMPORTANCE_HIGH, NotificationCompat.PRIORITY_HIGH),
54+
55+
/**
56+
* Maximum interruption level.
57+
*
58+
* <p>Translates to {@link NotificationManager#IMPORTANCE_HIGH} on Android O+ and {@link
59+
* NotificationCompat#PRIORITY_MAX} on older platforms.
60+
*/
61+
MAX(NotificationManager.IMPORTANCE_HIGH, NotificationCompat.PRIORITY_MAX);
62+
63+
/**
64+
* The notification channel importance corresponding to this interruption level on Android O+.
65+
*
66+
* @hide
67+
*/
68+
public final int channelImportance;
69+
70+
/**
71+
* The notification priority corresponding to this interruption level on older platforms.
72+
*
73+
* @hide
74+
*/
75+
public final int notificationPriority;
76+
77+
InterruptionLevel(int channelImportance, int notificationPriority) {
78+
this.channelImportance = channelImportance;
79+
this.notificationPriority = notificationPriority;
80+
}
81+
}

firebase-appdistribution-api/src/main/java/com/google/firebase/appdistribution/internal/FirebaseAppDistributionProxy.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.google.firebase.appdistribution.AppDistributionRelease;
2222
import com.google.firebase.appdistribution.FirebaseAppDistribution;
2323
import com.google.firebase.appdistribution.FirebaseAppDistributionException;
24+
import com.google.firebase.appdistribution.InterruptionLevel;
2425
import com.google.firebase.appdistribution.UpdateTask;
2526
import com.google.firebase.inject.Provider;
2627

@@ -95,13 +96,15 @@ public void startFeedback(@NonNull CharSequence infoText, @Nullable Uri screensh
9596
}
9697

9798
@Override
98-
public void showFeedbackNotification(int infoTextResourceId, int importance) {
99-
delegate.showFeedbackNotification(infoTextResourceId, importance);
99+
public void showFeedbackNotification(
100+
int infoTextResourceId, @NonNull InterruptionLevel interruptionLevel) {
101+
delegate.showFeedbackNotification(infoTextResourceId, interruptionLevel);
100102
}
101103

102104
@Override
103-
public void showFeedbackNotification(@NonNull CharSequence infoText, int importance) {
104-
delegate.showFeedbackNotification(infoText, importance);
105+
public void showFeedbackNotification(
106+
@NonNull CharSequence infoText, @NonNull InterruptionLevel interruptionLevel) {
107+
delegate.showFeedbackNotification(infoText, interruptionLevel);
105108
}
106109

107110
@Override

firebase-appdistribution-api/src/main/java/com/google/firebase/appdistribution/internal/FirebaseAppDistributionStub.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.google.firebase.appdistribution.FirebaseAppDistribution;
3131
import com.google.firebase.appdistribution.FirebaseAppDistributionException;
3232
import com.google.firebase.appdistribution.FirebaseAppDistributionException.Status;
33+
import com.google.firebase.appdistribution.InterruptionLevel;
3334
import com.google.firebase.appdistribution.OnProgressListener;
3435
import com.google.firebase.appdistribution.UpdateTask;
3536
import java.util.concurrent.Executor;
@@ -85,10 +86,12 @@ public void startFeedback(int infoTextResourceId, @Nullable Uri screenshotUri) {
8586
public void startFeedback(@NonNull CharSequence infoText, @Nullable Uri screenshotUri) {}
8687

8788
@Override
88-
public void showFeedbackNotification(int infoTextResourceId, int importance) {}
89+
public void showFeedbackNotification(
90+
int infoTextResourceId, @NonNull InterruptionLevel interruptionLevel) {}
8991

9092
@Override
91-
public void showFeedbackNotification(@NonNull CharSequence infoText, int importance) {}
93+
public void showFeedbackNotification(
94+
@NonNull CharSequence infoText, @NonNull InterruptionLevel interruptionLevel) {}
9295

9396
@Override
9497
public void cancelFeedbackNotification() {}

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/impl/FirebaseAppDistributionImpl.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.google.firebase.appdistribution.FirebaseAppDistribution;
4040
import com.google.firebase.appdistribution.FirebaseAppDistributionException;
4141
import com.google.firebase.appdistribution.FirebaseAppDistributionException.Status;
42+
import com.google.firebase.appdistribution.InterruptionLevel;
4243
import com.google.firebase.appdistribution.UpdateProgress;
4344
import com.google.firebase.appdistribution.UpdateStatus;
4445
import com.google.firebase.appdistribution.UpdateTask;
@@ -352,13 +353,15 @@ public void startFeedback(@NonNull CharSequence infoText, @Nullable Uri screensh
352353
}
353354

354355
@Override
355-
public void showFeedbackNotification(int infoTextResourceId, int importance) {
356-
showFeedbackNotification(getText(infoTextResourceId), importance);
356+
public void showFeedbackNotification(
357+
int infoTextResourceId, @NonNull InterruptionLevel interruptionLevel) {
358+
showFeedbackNotification(getText(infoTextResourceId), interruptionLevel);
357359
}
358360

359361
@Override
360-
public void showFeedbackNotification(@NonNull CharSequence infoText, int importance) {
361-
notificationsManager.showFeedbackNotification(infoText, importance);
362+
public void showFeedbackNotification(
363+
@NonNull CharSequence infoText, @NonNull InterruptionLevel interruptionLevel) {
364+
notificationsManager.showFeedbackNotification(infoText, interruptionLevel);
362365
}
363366

364367
@Override

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/impl/FirebaseAppDistributionNotificationsManager.java

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
import android.app.NotificationChannel;
1818
import android.app.NotificationChannelGroup;
19-
import android.app.NotificationManager;
2019
import android.app.PendingIntent;
2120
import android.content.Context;
2221
import android.content.Intent;
@@ -29,6 +28,7 @@
2928
import androidx.annotation.VisibleForTesting;
3029
import androidx.core.app.NotificationCompat;
3130
import androidx.core.app.NotificationManagerCompat;
31+
import com.google.firebase.appdistribution.InterruptionLevel;
3232

3333
class FirebaseAppDistributionNotificationsManager {
3434
private static final String TAG = "FirebaseAppDistributionNotificationsManager";
@@ -78,7 +78,7 @@ void showAppUpdateNotification(long totalBytes, long downloadedBytes, int string
7878
Notification.APP_UPDATE,
7979
R.string.app_update_notification_channel_name,
8080
R.string.app_update_notification_channel_description,
81-
NotificationManager.IMPORTANCE_DEFAULT);
81+
InterruptionLevel.DEFAULT);
8282
}
8383

8484
if (!notificationManager.areNotificationsEnabled()) {
@@ -129,7 +129,8 @@ private static int getPendingIntentFlags(int baseFlags) {
129129
: baseFlags;
130130
}
131131

132-
public void showFeedbackNotification(@NonNull CharSequence infoText, int importance) {
132+
public void showFeedbackNotification(
133+
@NonNull CharSequence infoText, @NonNull InterruptionLevel interruptionLevel) {
133134
// Create the NotificationChannel, but only on API 26+ because
134135
// the NotificationChannel class is new and not in the support library
135136
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@@ -138,7 +139,7 @@ public void showFeedbackNotification(@NonNull CharSequence infoText, int importa
138139
Notification.FEEDBACK,
139140
R.string.feedback_notification_channel_name,
140141
R.string.feedback_notification_channel_description,
141-
importance);
142+
interruptionLevel);
142143
}
143144

144145
if (!notificationManager.areNotificationsEnabled()) {
@@ -161,7 +162,7 @@ public void showFeedbackNotification(@NonNull CharSequence infoText, int importa
161162
.setSmallIcon(appIconSource.getNonAdaptiveIconOrDefault(context))
162163
.setContentTitle(context.getString(R.string.feedback_notification_title))
163164
.setContentText(context.getString(R.string.feedback_notification_text, appLabel))
164-
.setPriority(convertImportanceToPriority(importance))
165+
.setPriority(interruptionLevel.notificationPriority)
165166
.setOngoing(true)
166167
.setOnlyAlertOnce(true)
167168
.setAutoCancel(false)
@@ -177,31 +178,15 @@ public void cancelFeedbackNotification() {
177178
.cancel(Notification.FEEDBACK.tag, Notification.FEEDBACK.id);
178179
}
179180

180-
private int convertImportanceToPriority(int importance) {
181-
switch (importance) {
182-
case NotificationManagerCompat.IMPORTANCE_MIN:
183-
return NotificationCompat.PRIORITY_MIN;
184-
case NotificationManagerCompat.IMPORTANCE_LOW:
185-
return NotificationCompat.PRIORITY_LOW;
186-
case NotificationManagerCompat.IMPORTANCE_HIGH:
187-
return NotificationCompat.PRIORITY_HIGH;
188-
case NotificationManagerCompat.IMPORTANCE_MAX:
189-
return NotificationCompat.PRIORITY_MAX;
190-
case NotificationManagerCompat.IMPORTANCE_UNSPECIFIED:
191-
case NotificationManagerCompat.IMPORTANCE_NONE:
192-
case NotificationManagerCompat.IMPORTANCE_DEFAULT:
193-
default:
194-
return NotificationCompat.PRIORITY_DEFAULT;
195-
}
196-
}
197-
198181
@RequiresApi(Build.VERSION_CODES.O)
199-
private void createChannel(Notification notification, int name, int description, int importance) {
182+
private void createChannel(
183+
Notification notification, int name, int description, InterruptionLevel interruptionLevel) {
200184
notificationManager.createNotificationChannelGroup(
201185
new NotificationChannelGroup(
202186
CHANNEL_GROUP_ID, context.getString(R.string.notifications_group_name)));
203187
NotificationChannel channel =
204-
new NotificationChannel(notification.channelId, context.getString(name), importance);
188+
new NotificationChannel(
189+
notification.channelId, context.getString(name), interruptionLevel.channelImportance);
205190
channel.setDescription(context.getString(description));
206191
channel.setGroup(CHANNEL_GROUP_ID);
207192
// Register the channel with the system; you can't change the importance

firebase-appdistribution/src/test/java/com/google/firebase/appdistribution/impl/FirebaseAppDistributionNotificationsManagerTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import android.content.Intent;
2929
import androidx.test.core.app.ApplicationProvider;
3030
import com.google.firebase.FirebaseApp;
31+
import com.google.firebase.appdistribution.InterruptionLevel;
3132
import org.junit.Before;
3233
import org.junit.Test;
3334
import org.junit.runner.RunWith;
@@ -110,7 +111,7 @@ public void showAppUpdateNotification_withZeroTotalBytes_shows0Percent() {
110111
@Test
111112
public void showFeedbackNotification_createsGroupAndChannel() {
112113
firebaseAppDistributionNotificationsManager.showFeedbackNotification(
113-
"Terms and conditions", IMPORTANCE_HIGH);
114+
"Terms and conditions", InterruptionLevel.HIGH);
114115
assertThat(shadowOf(notificationManager).getNotificationChannelGroup(CHANNEL_GROUP_ID))
115116
.isNotNull();
116117
assertThat(shadowOf(notificationManager).getNotificationChannels()).hasSize(1);
@@ -123,7 +124,7 @@ public void showFeedbackNotification_createsGroupAndChannel() {
123124
@Test
124125
public void showFeedbackNotification_setsIntentToScreenshotActivity() {
125126
firebaseAppDistributionNotificationsManager.showFeedbackNotification(
126-
"Terms and conditions", IMPORTANCE_HIGH);
127+
"Terms and conditions", InterruptionLevel.HIGH);
127128
assertThat(shadowOf(notificationManager).size()).isEqualTo(1);
128129
Notification notification =
129130
shadowOf(notificationManager).getNotification(FEEDBACK.tag, FEEDBACK.id);
@@ -141,7 +142,7 @@ public void showFeedbackNotification_setsIntentToScreenshotActivity() {
141142
@Test
142143
public void showFeedbackNotification_convertsImportanceToPriority() {
143144
firebaseAppDistributionNotificationsManager.showFeedbackNotification(
144-
"Terms and conditions", IMPORTANCE_HIGH);
145+
"Terms and conditions", InterruptionLevel.HIGH);
145146
assertThat(shadowOf(notificationManager).size()).isEqualTo(1);
146147
Notification notification =
147148
shadowOf(notificationManager).getNotification(FEEDBACK.tag, FEEDBACK.id);

firebase-appdistribution/test-app/src/main/java/com/googletest/firebase/appdistribution/testapp/MainActivity.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import androidx.core.widget.doOnTextChanged
2020
import com.google.android.gms.tasks.Task
2121
import com.google.android.material.textfield.TextInputLayout
2222
import com.google.firebase.appdistribution.AppDistributionRelease
23+
import com.google.firebase.appdistribution.InterruptionLevel
2324
import com.google.firebase.appdistribution.UpdateProgress
2425
import com.google.firebase.appdistribution.ktx.appDistribution
2526
import com.google.firebase.ktx.Firebase
@@ -94,7 +95,7 @@ class MainActivity : AppCompatActivity() {
9495
disableAllFeedbackTriggers()
9596
Log.i(TAG, "Enabling notification trigger (SDK)")
9697
firebaseAppDistribution.showFeedbackNotification(
97-
R.string.termsAndConditions, NotificationManagerCompat.IMPORTANCE_HIGH)
98+
R.string.termsAndConditions, InterruptionLevel.HIGH)
9899
}
99100
FeedbackTrigger.CUSTOM_NOTIFICATION.label -> {
100101
disableAllFeedbackTriggers()

0 commit comments

Comments
 (0)