Skip to content

Commit a1b70a1

Browse files
authored
Merge branch 'master' into rl.changelogup0089
2 parents 59460c1 + 56d3f13 commit a1b70a1

File tree

115 files changed

+7329
-1792
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+7329
-1792
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ buildscript {
4141
classpath 'gradle.plugin.com.github.sherter.google-java-format:google-java-format-gradle-plugin:0.9'
4242
classpath 'com.google.gms:google-services:4.3.15'
4343
classpath "com.ncorti.ktfmt.gradle:plugin:0.11.0"
44+
classpath 'com.google.firebase:firebase-appdistribution-gradle:3.0.2'
4445
}
4546
}
4647

firebase-appdistribution-api/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
# Unreleased
2+
* [feature] Adds support for in-app tester feedback. To learn more, see
3+
[Collect feedback from testers](/docs/app-distribution/collect-feedback-from-testers?platform=android).
4+
* [fixed] Fixed a bug where only the last listener added to an `UpdateTask` using
5+
`addOnProgressListener()` would receive updates.
26

37
# 16.0.0-beta05
48
* [unchanged] Updated to accommodate the release of the updated

firebase-appdistribution-api/api.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,18 @@ package com.google.firebase.appdistribution {
1414
}
1515

1616
public interface FirebaseAppDistribution {
17+
method public void cancelFeedbackNotification();
1718
method @NonNull public com.google.android.gms.tasks.Task<com.google.firebase.appdistribution.AppDistributionRelease> checkForNewRelease();
1819
method @NonNull public static com.google.firebase.appdistribution.FirebaseAppDistribution getInstance();
1920
method public boolean isTesterSignedIn();
21+
method public void showFeedbackNotification(@StringRes int, @NonNull com.google.firebase.appdistribution.InterruptionLevel);
22+
method public void showFeedbackNotification(@NonNull CharSequence, @NonNull com.google.firebase.appdistribution.InterruptionLevel);
2023
method @NonNull public com.google.android.gms.tasks.Task<java.lang.Void> signInTester();
2124
method public void signOutTester();
25+
method public void startFeedback(@StringRes int);
26+
method public void startFeedback(@NonNull CharSequence);
27+
method public void startFeedback(@StringRes int, @Nullable android.net.Uri);
28+
method public void startFeedback(@NonNull CharSequence, @Nullable android.net.Uri);
2229
method @NonNull public com.google.firebase.appdistribution.UpdateTask updateApp();
2330
method @NonNull public com.google.firebase.appdistribution.UpdateTask updateIfNewReleaseAvailable();
2431
}
@@ -42,6 +49,14 @@ package com.google.firebase.appdistribution {
4249
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status UPDATE_NOT_AVAILABLE;
4350
}
4451

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+
4560
public interface OnProgressListener {
4661
method public void onProgressUpdate(@NonNull com.google.firebase.appdistribution.UpdateProgress);
4762
}

firebase-appdistribution-api/firebase-appdistribution-api.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ android {
3838
}
3939

4040
dependencies {
41-
implementation 'org.jetbrains:annotations:15.0'
4241
implementation project(':firebase-components')
4342
implementation project(':firebase-common')
4443
implementation 'com.google.android.gms:play-services-tasks:18.0.1'

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

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414

1515
package com.google.firebase.appdistribution;
1616

17+
import android.net.Uri;
1718
import androidx.annotation.NonNull;
19+
import androidx.annotation.Nullable;
20+
import androidx.annotation.StringRes;
1821
import com.google.android.gms.tasks.Task;
1922
import com.google.firebase.FirebaseApp;
2023
import com.google.firebase.appdistribution.internal.FirebaseAppDistributionProxy;
@@ -32,6 +35,7 @@
3235
* <p>Call {@link #getInstance()} to get the singleton instance of {@link FirebaseAppDistribution}.
3336
*/
3437
public interface FirebaseAppDistribution {
38+
3539
/**
3640
* Updates the app to the newest release, if one is available.
3741
*
@@ -109,6 +113,142 @@ public interface FirebaseAppDistribution {
109113
@NonNull
110114
UpdateTask updateApp();
111115

116+
/**
117+
* Takes a screenshot, and starts an activity to collect and submit feedback from the tester.
118+
*
119+
* <p>Performs the following actions:
120+
*
121+
* <ol>
122+
* <li>Takes a screenshot of the current activity
123+
* <li>If tester is not signed in, presents the tester with a Google Sign-in UI
124+
* <li>Starts a full screen activity for the tester to compose and submit the feedback
125+
* </ol>
126+
*
127+
* @param additionalFormText string resource ID of text that will be shown to the tester before
128+
* they submit feedback. If you’re a customer who would like to provide notice to your testers
129+
* about collection and processing of their feedback data, you can use this text to provide
130+
* such notice.
131+
*/
132+
void startFeedback(@StringRes int additionalFormText);
133+
134+
/**
135+
* Takes a screenshot, and starts an activity to collect and submit feedback from the tester.
136+
*
137+
* <p>Performs the following actions:
138+
*
139+
* <ol>
140+
* <li>Takes a screenshot of the current activity
141+
* <li>If tester is not signed in, presents the tester with a Google Sign-in UI
142+
* <li>Starts a full screen activity for the tester to compose and submit the feedback
143+
* </ol>
144+
*
145+
* @param additionalFormText text that will be shown to the tester before they submit feedback. If
146+
* you’re a customer who would like to provide notice to your testers about collection and
147+
* processing of their feedback data, you can use this text to provide such notice.
148+
*/
149+
void startFeedback(@NonNull CharSequence additionalFormText);
150+
151+
/**
152+
* Starts an activity to collect and submit feedback from the tester, along with the given
153+
* screenshot.
154+
*
155+
* <p>Performs the following actions:
156+
*
157+
* <ol>
158+
* <li>If tester is not signed in, presents the tester with a Google Sign-in UI
159+
* <li>Starts a full screen activity for the tester to compose and submit the feedback
160+
* </ol>
161+
*
162+
* @param additionalFormText string resource ID of text that will be shown to the tester before
163+
* they submit feedback. If you’re a customer who would like to provide notice to your testers
164+
* about collection and processing of their feedback data, you can use this text to provide
165+
* such notice.
166+
* @param screenshot URI to a bitmap containing a screenshot that will be included with the
167+
* report, or null to not include a screenshot
168+
*/
169+
void startFeedback(@StringRes int additionalFormText, @Nullable Uri screenshot);
170+
171+
/**
172+
* Starts an activity to collect and submit feedback from the tester, along with the given
173+
* screenshot.
174+
*
175+
* <p>Performs the following actions:
176+
*
177+
* <ol>
178+
* <li>If tester is not signed in, presents the tester with a Google Sign-in UI
179+
* <li>Starts a full screen activity for the tester to compose and submit the feedback
180+
* </ol>
181+
*
182+
* @param additionalFormText text that will be shown to the tester before they submit feedback. If
183+
* you’re a customer who would like to provide notice to your testers about collection and
184+
* processing of their feedback data, you can use this text to provide such notice.
185+
* @param screenshot URI to a bitmap containing a screenshot that will be included with the
186+
* report, or null to not include a screenshot
187+
*/
188+
void startFeedback(@NonNull CharSequence additionalFormText, @Nullable Uri screenshot);
189+
190+
/**
191+
* Displays a notification that, when tapped, will take a screenshot of the current activity, then
192+
* start a new activity to collect and submit feedback from the tester along with the screenshot.
193+
*
194+
* <p>On Android 13 and above, this method requires the <a
195+
* href="https://developer.android.com/develop/ui/views/notifications/notification-permission">runtime
196+
* permission for sending notifications</a>: {@code POST_NOTIFICATIONS}. If your app targets
197+
* Android 13 (API level 33) or above, you should <a
198+
* href="https://developer.android.com/training/permissions/requesting">request the
199+
* permission</a>.
200+
*
201+
* <p>When the notification is tapped:
202+
*
203+
* <ol>
204+
* <li>If the app is open, take a screenshot of the current activity
205+
* <li>If tester is not signed in, presents the tester with a Google Sign-in UI
206+
* <li>Starts a full screen activity for the tester to compose and submit the feedback
207+
* </ol>
208+
*
209+
* @param additionalFormText string resource ID of text that will be shown to the tester before
210+
* they submit feedback. If you’re a customer who would like to provide notice to your testers
211+
* about collection and processing of their feedback data, you can use this text to provide
212+
* such notice.
213+
* @param interruptionLevel the level of interruption for the feedback notification. On platforms
214+
* below Android 8, this corresponds to a notification channel importance and once set cannot
215+
* be changed except by the user.
216+
*/
217+
void showFeedbackNotification(
218+
@StringRes int additionalFormText, @NonNull InterruptionLevel interruptionLevel);
219+
220+
/**
221+
* Displays a notification that, when tapped, will take a screenshot of the current activity, then
222+
* start a new activity to collect and submit feedback from the tester along with the screenshot.
223+
*
224+
* <p>On Android 13 and above, this method requires the <a
225+
* href="https://developer.android.com/develop/ui/views/notifications/notification-permission">runtime
226+
* permission for sending notifications</a>: {@code POST_NOTIFICATIONS}. If your app targets
227+
* Android 13 (API level 33) or above, you should <a
228+
* href="https://developer.android.com/training/permissions/requesting">request the
229+
* permission</a>.
230+
*
231+
* <p>When the notification is tapped:
232+
*
233+
* <ol>
234+
* <li>If the app is open, take a screenshot of the current activity
235+
* <li>If tester is not signed in, presents the tester with a Google Sign-in UI
236+
* <li>Starts a full screen activity for the tester to compose and submit the feedback
237+
* </ol>
238+
*
239+
* @param additionalFormText text that will be shown to the tester before they submit feedback. If
240+
* you’re a customer who would like to provide notice to your testers about collection and
241+
* processing of their feedback data, you can use this text to provide such notice.
242+
* @param interruptionLevel the level of interruption for the feedback notification. On platforms
243+
* below Android 8, this corresponds to a notification channel importance and once set cannot
244+
* be changed except by the user.
245+
*/
246+
void showFeedbackNotification(
247+
@NonNull CharSequence additionalFormText, @NonNull InterruptionLevel interruptionLevel);
248+
249+
/** Hides the notification shown with {@link #showFeedbackNotification}. */
250+
void cancelFeedbackNotification();
251+
112252
/** Gets the singleton {@link FirebaseAppDistribution} instance. */
113253
@NonNull
114254
static FirebaseAppDistribution getInstance() {
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: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@
1414

1515
package com.google.firebase.appdistribution.internal;
1616

17+
import android.net.Uri;
1718
import androidx.annotation.NonNull;
19+
import androidx.annotation.Nullable;
20+
import androidx.annotation.StringRes;
1821
import com.google.android.gms.tasks.Task;
1922
import com.google.firebase.appdistribution.AppDistributionRelease;
2023
import com.google.firebase.appdistribution.FirebaseAppDistribution;
2124
import com.google.firebase.appdistribution.FirebaseAppDistributionException;
25+
import com.google.firebase.appdistribution.InterruptionLevel;
2226
import com.google.firebase.appdistribution.UpdateTask;
2327
import com.google.firebase.inject.Provider;
2428

@@ -71,4 +75,41 @@ public synchronized Task<AppDistributionRelease> checkForNewRelease() {
7175
public UpdateTask updateApp() {
7276
return delegate.updateApp();
7377
}
78+
79+
@Override
80+
public void startFeedback(@StringRes int additionalFormText) {
81+
delegate.startFeedback(additionalFormText);
82+
}
83+
84+
@Override
85+
public void startFeedback(@NonNull CharSequence additionalFormText) {
86+
delegate.startFeedback(additionalFormText);
87+
}
88+
89+
@Override
90+
public void startFeedback(@StringRes int additionalFormText, @Nullable Uri screenshotUri) {
91+
delegate.startFeedback(additionalFormText, screenshotUri);
92+
}
93+
94+
@Override
95+
public void startFeedback(@NonNull CharSequence additionalFormText, @Nullable Uri screenshotUri) {
96+
delegate.startFeedback(additionalFormText, screenshotUri);
97+
}
98+
99+
@Override
100+
public void showFeedbackNotification(
101+
@StringRes int additionalFormText, @NonNull InterruptionLevel interruptionLevel) {
102+
delegate.showFeedbackNotification(additionalFormText, interruptionLevel);
103+
}
104+
105+
@Override
106+
public void showFeedbackNotification(
107+
@NonNull CharSequence additionalFormText, @NonNull InterruptionLevel interruptionLevel) {
108+
delegate.showFeedbackNotification(additionalFormText, interruptionLevel);
109+
}
110+
111+
@Override
112+
public void cancelFeedbackNotification() {
113+
delegate.cancelFeedbackNotification();
114+
}
74115
}

0 commit comments

Comments
 (0)