Skip to content

Commit

Permalink
Add ShadowApplicationExitInfo
Browse files Browse the repository at this point in the history
Adds support for shadowing getTraceInputStream, and updates
ApplicationExitInfoBuilder in ShadowActivityManager for ease of use.

PiperOrigin-RevId: 637069782
  • Loading branch information
Googler authored and copybara-github committed May 24, 2024
1 parent 259f25c commit 400d755
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.robolectric.shadows;

import static android.os.Build.VERSION_CODES.R;
import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;

import android.app.ApplicationExitInfo;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.primitives.Bytes;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;

@RunWith(AndroidJUnit4.class)
@Config(minSdk = R)
public final class ShadowApplicationExitInfoTest {

@Test
public void setTraceInputStream_traceInputStreamSet() throws Exception {
byte[] testBytes = "hello".getBytes(UTF_8);
InputStream in = new ByteArrayInputStream(testBytes);

ApplicationExitInfo info = new ApplicationExitInfo();
ShadowApplicationExitInfo shadow = Shadow.extract(info);

shadow.setTraceInputStream(in);

assertThat(info.getTraceInputStream()).isNotNull();

byte[] bytesFromAppExitStream = new byte[testBytes.length];
assertThat(info.getTraceInputStream().read(bytesFromAppExitStream)).isEqualTo(testBytes.length);
assertThat(bytesFromAppExitStream)
.asList()
.containsExactlyElementsIn(Bytes.asList(testBytes))
.inOrder();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import android.util.SparseIntArray;
import com.google.common.base.Preconditions;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.InputStream;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
Expand Down Expand Up @@ -389,6 +390,7 @@ public boolean isApplicationUserDataCleared() {
public static class ApplicationExitInfoBuilder {

private final ApplicationExitInfo instance;
private final ShadowApplicationExitInfo shadow;

public static ApplicationExitInfoBuilder newBuilder() {
return new ApplicationExitInfoBuilder();
Expand Down Expand Up @@ -472,12 +474,19 @@ public ApplicationExitInfoBuilder setTimestamp(long timestamp) {
return this;
}

@CanIgnoreReturnValue
public ApplicationExitInfoBuilder setTraceInputStream(InputStream in) {
shadow.setTraceInputStream(in);
return this;
}

public ApplicationExitInfo build() {
return instance;
}

private ApplicationExitInfoBuilder() {
this.instance = new ApplicationExitInfo();
this.shadow = Shadow.extract(instance);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.robolectric.shadows;

import static android.os.Build.VERSION_CODES.R;
import static org.robolectric.util.reflector.Reflector.reflector;

import android.app.ApplicationExitInfo;
import java.io.InputStream;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.util.reflector.Direct;
import org.robolectric.util.reflector.ForType;

/** Shadow for {@link android.app.ApplicationExitInfo} */
@Implements(value = ApplicationExitInfo.class, minSdk = R, isInAndroidSdk = false)
public class ShadowApplicationExitInfo {

@RealObject ApplicationExitInfo applicationExitInfo;
private InputStream traceInputStream = null;

@Implementation
protected InputStream getTraceInputStream() {
if (this.traceInputStream == null) {
return reflector(ApplicationExitInfoReflector.class, applicationExitInfo)
.getTraceInputStream();
}
return this.traceInputStream;
}

/**
* When called with a non-null InputStream, Overrides the stream returned by {@link
* ApplicationExitInfo#getTraceInputStream()}
*/
public void setTraceInputStream(InputStream in) {
this.traceInputStream = in;
}

@ForType(ApplicationExitInfo.class)
private interface ApplicationExitInfoReflector {
@Direct
InputStream getTraceInputStream();
}
}

0 comments on commit 400d755

Please sign in to comment.