From f3020291c413951398d3984bbc00ae9ce1994f4f Mon Sep 17 00:00:00 2001 From: JiglioNero Date: Mon, 27 Nov 2023 14:49:05 +0100 Subject: [PATCH] fix tests --- .../session/InstallStatusReceiver.java | 15 ++++++-- .../session/InstallStatusReceiverTest.java | 9 +++++ .../session/SessionReleaseInstallerTest.java | 38 +++++++++++++++++-- 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/sdk/appcenter-distribute/src/main/java/com/microsoft/appcenter/distribute/install/session/InstallStatusReceiver.java b/sdk/appcenter-distribute/src/main/java/com/microsoft/appcenter/distribute/install/session/InstallStatusReceiver.java index 212f77458..5bd0a99ee 100644 --- a/sdk/appcenter-distribute/src/main/java/com/microsoft/appcenter/distribute/install/session/InstallStatusReceiver.java +++ b/sdk/appcenter-distribute/src/main/java/com/microsoft/appcenter/distribute/install/session/InstallStatusReceiver.java @@ -7,6 +7,7 @@ import static com.microsoft.appcenter.distribute.DistributeConstants.LOG_TAG; +import android.annotation.SuppressLint; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; @@ -31,8 +32,14 @@ class InstallStatusReceiver extends BroadcastReceiver { @VisibleForTesting static final String INSTALL_STATUS_ACTION = "com.microsoft.appcenter.action.INSTALL_STATUS"; + + /** + * Raw value of PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT which will appear only in + * Android target SDK 34. + */ @VisibleForTesting - static final String FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT_NAME = "FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT"; + private static final int FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT_VALUE = 16777216; + static IntentFilter getInstallerReceiverFilter() { IntentFilter installerReceiverFilter = new IntentFilter(); @@ -52,10 +59,12 @@ static IntentSender getInstallStatusIntentSender(Context context, int requestCod if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { broadcastFlags = PendingIntent.FLAG_MUTABLE; if (Build.VERSION.SDK_INT >= 34) { - broadcastFlags |= PendingIntent.class.getDeclaredField(FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT_NAME).getInt(PendingIntent.class); + broadcastFlags |= FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT_VALUE; } } - PendingIntent pendingIntent = PendingIntent.getBroadcast( + // We use PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT on target SDK < 34. + // Suppress warning because there is no such flag in SDK < 34. + @SuppressLint("WrongConstant") PendingIntent pendingIntent = PendingIntent.getBroadcast( context, requestCode, new Intent(INSTALL_STATUS_ACTION), diff --git a/sdk/appcenter-distribute/src/test/java/com/microsoft/appcenter/distribute/install/session/InstallStatusReceiverTest.java b/sdk/appcenter-distribute/src/test/java/com/microsoft/appcenter/distribute/install/session/InstallStatusReceiverTest.java index d9f3c2bb2..9881d6fca 100644 --- a/sdk/appcenter-distribute/src/test/java/com/microsoft/appcenter/distribute/install/session/InstallStatusReceiverTest.java +++ b/sdk/appcenter-distribute/src/test/java/com/microsoft/appcenter/distribute/install/session/InstallStatusReceiverTest.java @@ -53,6 +53,7 @@ public class InstallStatusReceiverTest { private static final int SESSION_ID = 42; + private static final int FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT_VALUE = 16777216; @Rule public PowerMockRule mRule = new PowerMockRule(); @@ -216,6 +217,14 @@ public void installerReceiverFilter() throws Exception { verify(filter).addAction(INSTALL_STATUS_ACTION); } + @Test + public void createIntentSenderOnAndroid34() throws NoSuchFieldException, IllegalAccessException { + + /* Mock SDK_INT to 34 target SDK. */ + Whitebox.setInternalState(Build.VERSION.class, "SDK_INT", 34); + createIntentSender(PendingIntent.FLAG_MUTABLE | FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT_VALUE); + } + @Test public void createIntentSenderOnAndroidS() throws NoSuchFieldException, IllegalAccessException { diff --git a/sdk/appcenter-distribute/src/test/java/com/microsoft/appcenter/distribute/install/session/SessionReleaseInstallerTest.java b/sdk/appcenter-distribute/src/test/java/com/microsoft/appcenter/distribute/install/session/SessionReleaseInstallerTest.java index 4a98e311b..ec9fd594a 100644 --- a/sdk/appcenter-distribute/src/test/java/com/microsoft/appcenter/distribute/install/session/SessionReleaseInstallerTest.java +++ b/sdk/appcenter-distribute/src/test/java/com/microsoft/appcenter/distribute/install/session/SessionReleaseInstallerTest.java @@ -29,6 +29,7 @@ import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; import android.net.Uri; +import android.os.Build; import android.os.Handler; import android.os.ParcelFileDescriptor; @@ -41,12 +42,14 @@ import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatchers; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.rule.PowerMockRule; +import org.powermock.reflect.Whitebox; import java.io.FileInputStream; import java.io.IOException; @@ -58,7 +61,7 @@ InstallStatusReceiver.class, PackageInstallerListener.class, ReleaseInstallerActivity.class, - SessionReleaseInstaller.class + SessionReleaseInstaller.class, }) public class SessionReleaseInstallerTest { @@ -153,7 +156,9 @@ public Boolean answer(InvocationOnMock invocation) { } @Test - public void installSuccess() throws IOException { + public void installSuccessForSV2() throws IOException { + Whitebox.setInternalState(Build.VERSION.class, "SDK_INT", Build.VERSION_CODES.S_V2); + Uri uri = mock(Uri.class); mInstaller.install(uri); @@ -177,6 +182,33 @@ public void installSuccess() throws IOException { verify(mPackageInstaller).abandonSession(eq(SESSION_ID)); } + @Test + public void installSuccessForTiramisu() throws IOException { + Whitebox.setInternalState(Build.VERSION.class, "SDK_INT", Build.VERSION_CODES.TIRAMISU); + + Uri uri = mock(Uri.class); + mInstaller.install(uri); + + /* Verify that all required things called. */ + verify(mHandler).post(any(Runnable.class)); + verify(mContext).registerReceiver(eq(mInstallStatusReceiver), any(), anyInt()); + verify(mPackageInstaller).registerSessionCallback(eq(mPackageInstallerListener)); + verify(mInputStream).close(); + verify(mOutputStream).close(); + verify(mSession).commit(any(IntentSender.class)); + verify(mSession, never()).abandon(); + verify(mSession).close(); + verifyNoInteractions(mListener); + + /* Try to star install second time. It's valid case if something goes wrong with previous try. */ + mInstaller.install(uri); + + /* Cancel previous session and re-use callbacks. */ + verify(mContext).registerReceiver(eq(mInstallStatusReceiver), any(), anyInt()); + verify(mPackageInstaller).registerSessionCallback(eq(mPackageInstallerListener)); + verify(mPackageInstaller).abandonSession(eq(SESSION_ID)); + } + @Test public void throwIOExceptionWhenTryToOpenWriteSession() throws IOException { @@ -246,7 +278,7 @@ public void clear() { mInstaller.install(uri); /* Registering callbacks. */ - verify(mContext).registerReceiver(eq(mInstallStatusReceiver), any()); + verify(mContext).registerReceiver(eq(mInstallStatusReceiver), any(), anyInt()); verify(mPackageInstaller).registerSessionCallback(eq(mPackageInstallerListener)); /* Clear after start should clear registered callbacks and abandon the session. */