1 package org.robolectric.shadows; 2 3 import static android.os.Build.VERSION_CODES.LOLLIPOP; 4 import static com.google.common.truth.Truth.assertThat; 5 import static org.mockito.Mockito.mock; 6 import static org.mockito.Mockito.verify; 7 import static org.robolectric.Shadows.shadowOf; 8 9 import android.content.IIntentSender; 10 import android.content.IntentSender; 11 import android.content.pm.PackageInstaller; 12 import android.os.Handler; 13 import androidx.test.core.app.ApplicationProvider; 14 import androidx.test.ext.junit.runners.AndroidJUnit4; 15 import java.io.OutputStream; 16 import org.junit.Before; 17 import org.junit.Test; 18 import org.junit.runner.RunWith; 19 import org.robolectric.annotation.Config; 20 import org.robolectric.util.ReflectionHelpers; 21 22 @RunWith(AndroidJUnit4.class) 23 @Config(minSdk = LOLLIPOP) 24 public class ShadowPackageInstallerTest { 25 26 private static final String TEST_PACKAGE_NAME = "com.some.other.package"; 27 private static final String TEST_PACKAGE_LABEL = "My Little App"; 28 29 private PackageInstaller packageInstaller; 30 31 @Before setUp()32 public void setUp() { 33 packageInstaller = 34 ApplicationProvider.getApplicationContext().getPackageManager().getPackageInstaller(); 35 } 36 37 @Test shouldBeNoInProcessSessionsOnRobolectricStartup()38 public void shouldBeNoInProcessSessionsOnRobolectricStartup() { 39 assertThat(packageInstaller.getAllSessions()).isEmpty(); 40 } 41 42 @Test packageInstallerCreateAndAbandonSession()43 public void packageInstallerCreateAndAbandonSession() throws Exception { 44 PackageInstaller.SessionCallback mockCallback = mock(PackageInstaller.SessionCallback.class); 45 packageInstaller.registerSessionCallback(mockCallback, new Handler()); 46 47 int sessionId = packageInstaller.createSession(createSessionParams("packageName")); 48 49 PackageInstaller.SessionInfo sessionInfo = packageInstaller.getSessionInfo(sessionId); 50 assertThat(sessionInfo.isActive()).isTrue(); 51 52 assertThat(sessionInfo.appPackageName).isEqualTo("packageName"); 53 54 packageInstaller.abandonSession(sessionId); 55 56 assertThat(packageInstaller.getSessionInfo(sessionId)).isNull(); 57 assertThat(packageInstaller.getAllSessions()).isEmpty(); 58 59 verify(mockCallback).onCreated(sessionId); 60 verify(mockCallback).onFinished(sessionId, false); 61 } 62 63 @Test packageInstallerOpenSession()64 public void packageInstallerOpenSession() throws Exception { 65 int sessionId = packageInstaller.createSession(createSessionParams("packageName")); 66 67 PackageInstaller.Session session = packageInstaller.openSession(sessionId); 68 69 assertThat(session).isNotNull(); 70 } 71 72 @Test(expected = SecurityException.class) packageInstallerOpenSession_nonExistantSessionThrowsException()73 public void packageInstallerOpenSession_nonExistantSessionThrowsException() throws Exception { 74 PackageInstaller.Session session = packageInstaller.openSession(-99); 75 } 76 77 @Test // TODO: Initial implementation has a no-op OutputStream - complete this implementation. sessionOpenWriteDoesNotThrowException()78 public void sessionOpenWriteDoesNotThrowException() throws Exception { 79 int sessionId = packageInstaller.createSession(createSessionParams("packageName")); 80 PackageInstaller.Session session = packageInstaller.openSession(sessionId); 81 82 OutputStream filename = session.openWrite("filename", 0, 0); 83 filename.write(10); 84 } 85 86 @Test sessionCommitSession_streamProperlyClosed()87 public void sessionCommitSession_streamProperlyClosed() throws Exception { 88 int sessionId = packageInstaller.createSession(createSessionParams("packageName")); 89 PackageInstaller.Session session = packageInstaller.openSession(sessionId); 90 91 OutputStream outputStream = session.openWrite("filename", 0, 0); 92 outputStream.close(); 93 94 session.commit(new IntentSender(ReflectionHelpers.createNullProxy(IIntentSender.class))); 95 } 96 97 @Test(expected = SecurityException.class) sessionCommitSession_streamStillOpen()98 public void sessionCommitSession_streamStillOpen() throws Exception { 99 int sessionId = packageInstaller.createSession(createSessionParams("packageName")); 100 PackageInstaller.Session session = packageInstaller.openSession(sessionId); 101 102 session.openWrite("filename", 0, 0); 103 104 session.commit(new IntentSender(ReflectionHelpers.createNullProxy(IIntentSender.class))); 105 } 106 107 @Test registerSessionCallback_sessionFails()108 public void registerSessionCallback_sessionFails() throws Exception { 109 PackageInstaller.SessionCallback mockCallback = mock(PackageInstaller.SessionCallback.class); 110 packageInstaller.registerSessionCallback(mockCallback, new Handler()); 111 int sessionId = packageInstaller.createSession(createSessionParams("packageName")); 112 verify(mockCallback).onCreated(sessionId); 113 114 PackageInstaller.Session session = packageInstaller.openSession(sessionId); 115 116 OutputStream outputStream = session.openWrite("filename", 0, 0); 117 outputStream.close(); 118 119 session.abandon(); 120 121 assertThat(packageInstaller.getAllSessions()).isEmpty(); 122 123 verify(mockCallback).onFinished(sessionId, false); 124 } 125 126 @Test registerSessionCallback_sessionSucceeds()127 public void registerSessionCallback_sessionSucceeds() throws Exception { 128 PackageInstaller.SessionCallback mockCallback = mock(PackageInstaller.SessionCallback.class); 129 packageInstaller.registerSessionCallback(mockCallback, new Handler()); 130 int sessionId = packageInstaller.createSession(createSessionParams("packageName")); 131 verify(mockCallback).onCreated(sessionId); 132 133 PackageInstaller.Session session = packageInstaller.openSession(sessionId); 134 135 OutputStream outputStream = session.openWrite("filename", 0, 0); 136 outputStream.close(); 137 138 session.commit(new IntentSender(ReflectionHelpers.createNullProxy(IIntentSender.class))); 139 140 shadowOf(packageInstaller).setSessionProgress(sessionId, 50.0f); 141 verify(mockCallback).onProgressChanged(sessionId, 50.0f); 142 143 verify(mockCallback).onFinished(sessionId, true); 144 } 145 createSessionParams(String appPackageName)146 private static PackageInstaller.SessionParams createSessionParams(String appPackageName) { 147 PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL); 148 params.setAppPackageName(appPackageName); 149 return params; 150 } 151 } 152