Skip to content

Commit 9075240

Browse files
Merge pull request #1718 from microsoft/develop
2 parents d406e11 + 94e17ea commit 9075240

File tree

8 files changed

+83
-10
lines changed

8 files changed

+83
-10
lines changed

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
# App Center SDK for Android Change Log
22

3-
## Version 5.0.3 (In development)
3+
## Version 5.0.4
4+
5+
### App Center Distribute
6+
7+
* **[Fix]** Add RECEIVER_EXPORTED flag for install receiver.
8+
* **[Fix]** Add FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT flag for broadcast pending intent.
9+
10+
## Version 5.0.3
11+
12+
### AppCenter
13+
14+
* **[Internal]** Add `dataResidencyRegion` option.
15+
416

517
## Version 5.0.2
618

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[![Coverage Status](https://coveralls.io/repos/github/Microsoft/AppCenter-SDK-Android/badge.svg?branch=develop)](https://coveralls.io/github/Microsoft/AppCenter-SDK-Android?branch=develop)
22
[![GitHub Release](https://img.shields.io/github/release/microsoft/appcenter-sdk-android.svg)](https://github.com/microsoft/appcenter-sdk-android/releases/latest)
3-
[![Bintray](https://api.bintray.com/packages/vsappcenter/appcenter/appcenter/images/download.svg)](https://bintray.com/vsappcenter/appcenter)
43
[![license](https://img.shields.io/badge/license-MIT%20License-00AAAA.svg)](https://github.com/microsoft/appcenter-sdk-android/blob/master/license.txt)
4+
[![Project Map](https://img.shields.io/badge/SourceSpy-Project_Map-blue.svg)](https://sourcespy.com/github/microsoftappcentersdkandroid/)
55

66
# Visual Studio App Center SDK for Android
77

apps/sasquatch/src/main/java/com/microsoft/appcenter/sasquatch/activities/SettingsActivity.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import android.content.Intent;
1414
import android.content.SharedPreferences;
1515
import android.net.Uri;
16+
import android.os.Build;
1617
import android.os.Bundle;
1718
import android.os.FileObserver;
1819
import android.preference.CheckBoxPreference;
@@ -738,7 +739,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
738739
if (requestCode == FILE_ATTACHMENT_DIALOG_ID) {
739740
Uri fileAttachment = resultCode == RESULT_OK && data != null ? data.getData() : null;
740741
if (fileAttachment != null) {
741-
getActivity().getContentResolver().takePersistableUriPermission(fileAttachment, data.getFlags() & Intent.FLAG_GRANT_READ_URI_PERMISSION);
742+
getActivity().getContentResolver().takePersistableUriPermission(fileAttachment, Intent.FLAG_GRANT_READ_URI_PERMISSION);
742743
}
743744
MainActivity.setFileAttachment(fileAttachment);
744745
Preference preference = getPreferenceManager().findPreference(getString(R.string.appcenter_crashes_file_attachment_key));

sdk/appcenter-distribute/src/main/java/com/microsoft/appcenter/distribute/install/session/InstallStatusReceiver.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import static com.microsoft.appcenter.distribute.DistributeConstants.LOG_TAG;
99

10+
import android.annotation.SuppressLint;
1011
import android.app.PendingIntent;
1112
import android.content.BroadcastReceiver;
1213
import android.content.Context;
@@ -32,6 +33,15 @@ class InstallStatusReceiver extends BroadcastReceiver {
3233
@VisibleForTesting
3334
static final String INSTALL_STATUS_ACTION = "com.microsoft.appcenter.action.INSTALL_STATUS";
3435

36+
/**
37+
* Raw value of PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT.
38+
* https://developer.android.com/reference/android/app/PendingIntent#FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT
39+
* This flag will appear only in Android target SDK 34.
40+
*/
41+
@VisibleForTesting
42+
private static final int FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT_VALUE = 16777216;
43+
44+
3545
static IntentFilter getInstallerReceiverFilter() {
3646
IntentFilter installerReceiverFilter = new IntentFilter();
3747
installerReceiverFilter.addAction(INSTALL_STATUS_ACTION);
@@ -49,8 +59,12 @@ static IntentSender getInstallStatusIntentSender(Context context, int requestCod
4959
int broadcastFlags = 0;
5060
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
5161
broadcastFlags = PendingIntent.FLAG_MUTABLE;
62+
if (Build.VERSION.SDK_INT >= 34) {
63+
broadcastFlags |= FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT_VALUE;
64+
}
5265
}
53-
PendingIntent pendingIntent = PendingIntent.getBroadcast(
66+
// Suppress the warning as the flag PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT is unavailable on Android SDK < 34.
67+
@SuppressLint("WrongConstant") PendingIntent pendingIntent = PendingIntent.getBroadcast(
5468
context,
5569
requestCode,
5670
new Intent(INSTALL_STATUS_ACTION),

sdk/appcenter-distribute/src/main/java/com/microsoft/appcenter/distribute/install/session/SessionReleaseInstaller.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import android.content.IntentSender;
1515
import android.content.pm.PackageInstaller;
1616
import android.net.Uri;
17+
import android.os.Build;
1718
import android.os.Handler;
1819
import android.os.ParcelFileDescriptor;
1920

@@ -233,7 +234,11 @@ private synchronized void registerListeners() {
233234
if (mInstallStatusReceiver == null) {
234235
AppCenterLog.debug(LOG_TAG, "Register receiver for installing a new release.");
235236
mInstallStatusReceiver = new InstallStatusReceiver(this);
236-
mContext.registerReceiver(mInstallStatusReceiver, InstallStatusReceiver.getInstallerReceiverFilter());
237+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
238+
mContext.registerReceiver(mInstallStatusReceiver, InstallStatusReceiver.getInstallerReceiverFilter(), Context.RECEIVER_EXPORTED);
239+
} else {
240+
mContext.registerReceiver(mInstallStatusReceiver, InstallStatusReceiver.getInstallerReceiverFilter());
241+
}
237242
}
238243
if (mSessionCallback == null) {
239244
PackageInstaller packageInstaller = getPackageInstaller();

sdk/appcenter-distribute/src/test/java/com/microsoft/appcenter/distribute/install/session/InstallStatusReceiverTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
public class InstallStatusReceiverTest {
5454

5555
private static final int SESSION_ID = 42;
56+
private static final int FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT_VALUE = 16777216;
5657

5758
@Rule
5859
public PowerMockRule mRule = new PowerMockRule();
@@ -216,6 +217,14 @@ public void installerReceiverFilter() throws Exception {
216217
verify(filter).addAction(INSTALL_STATUS_ACTION);
217218
}
218219

220+
@Test
221+
public void createIntentSenderOnAndroid34() {
222+
223+
/* Mock SDK_INT to 34 target SDK. */
224+
Whitebox.setInternalState(Build.VERSION.class, "SDK_INT", 34);
225+
createIntentSender(PendingIntent.FLAG_MUTABLE | FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT_VALUE);
226+
}
227+
219228
@Test
220229
public void createIntentSenderOnAndroidS() {
221230

sdk/appcenter-distribute/src/test/java/com/microsoft/appcenter/distribute/install/session/SessionReleaseInstallerTest.java

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import android.content.pm.PackageInstaller;
3030
import android.content.pm.PackageManager;
3131
import android.net.Uri;
32+
import android.os.Build;
3233
import android.os.Handler;
3334
import android.os.ParcelFileDescriptor;
3435

@@ -41,12 +42,14 @@
4142
import org.junit.Rule;
4243
import org.junit.Test;
4344
import org.mockito.ArgumentCaptor;
45+
import org.mockito.ArgumentMatchers;
4446
import org.mockito.Captor;
4547
import org.mockito.Mock;
4648
import org.mockito.invocation.InvocationOnMock;
4749
import org.mockito.stubbing.Answer;
4850
import org.powermock.core.classloader.annotations.PrepareForTest;
4951
import org.powermock.modules.junit4.rule.PowerMockRule;
52+
import org.powermock.reflect.Whitebox;
5053

5154
import java.io.FileInputStream;
5255
import java.io.IOException;
@@ -58,7 +61,7 @@
5861
InstallStatusReceiver.class,
5962
PackageInstallerListener.class,
6063
ReleaseInstallerActivity.class,
61-
SessionReleaseInstaller.class
64+
SessionReleaseInstaller.class,
6265
})
6366
public class SessionReleaseInstallerTest {
6467

@@ -153,7 +156,9 @@ public Boolean answer(InvocationOnMock invocation) {
153156
}
154157

155158
@Test
156-
public void installSuccess() throws IOException {
159+
public void installSuccessForSV2() throws IOException {
160+
Whitebox.setInternalState(Build.VERSION.class, "SDK_INT", Build.VERSION_CODES.S_V2);
161+
157162
Uri uri = mock(Uri.class);
158163
mInstaller.install(uri);
159164

@@ -177,6 +182,33 @@ public void installSuccess() throws IOException {
177182
verify(mPackageInstaller).abandonSession(eq(SESSION_ID));
178183
}
179184

185+
@Test
186+
public void installSuccessForTiramisu() throws IOException {
187+
Whitebox.setInternalState(Build.VERSION.class, "SDK_INT", Build.VERSION_CODES.TIRAMISU);
188+
189+
Uri uri = mock(Uri.class);
190+
mInstaller.install(uri);
191+
192+
/* Verify that all required things called. */
193+
verify(mHandler).post(any(Runnable.class));
194+
verify(mContext).registerReceiver(eq(mInstallStatusReceiver), any(), anyInt());
195+
verify(mPackageInstaller).registerSessionCallback(eq(mPackageInstallerListener));
196+
verify(mInputStream).close();
197+
verify(mOutputStream).close();
198+
verify(mSession).commit(any(IntentSender.class));
199+
verify(mSession, never()).abandon();
200+
verify(mSession).close();
201+
verifyNoInteractions(mListener);
202+
203+
/* Try to star install second time. It's valid case if something goes wrong with previous try. */
204+
mInstaller.install(uri);
205+
206+
/* Cancel previous session and re-use callbacks. */
207+
verify(mContext).registerReceiver(eq(mInstallStatusReceiver), any(), anyInt());
208+
verify(mPackageInstaller).registerSessionCallback(eq(mPackageInstallerListener));
209+
verify(mPackageInstaller).abandonSession(eq(SESSION_ID));
210+
}
211+
180212
@Test
181213
public void throwIOExceptionWhenTryToOpenWriteSession() throws IOException {
182214

@@ -246,7 +278,7 @@ public void clear() {
246278
mInstaller.install(uri);
247279

248280
/* Registering callbacks. */
249-
verify(mContext).registerReceiver(eq(mInstallStatusReceiver), any());
281+
verify(mContext).registerReceiver(eq(mInstallStatusReceiver), any(), anyInt());
250282
verify(mPackageInstaller).registerSessionCallback(eq(mPackageInstallerListener));
251283

252284
/* Clear after start should clear registered callbacks and abandon the session. */

versions.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
// Version constants
77

88
ext {
9-
versionCode = 72
10-
versionName = '5.0.3'
9+
versionCode = 73
10+
versionName = '5.0.4'
1111
minSdkVersion = 21
1212
compileSdkVersion = 33
1313
targetSdkVersion = 33

0 commit comments

Comments
 (0)