Android: add support for headless js tasks

Summary: Provide a base `HeadlessJsTaskService` class that can be extended to run JS in headless mode in response to some event. Added `HeadlessJsTaskEventListener` for modules that are interested in background lifecycle events, and `HeadlessJsTaskContext` that basically extends `ReactContext` without touching it. The react instance is shared with the rest of the app (e.g. activities) through the `ReactNativeHost`.

Reviewed By: astreet

Differential Revision: D3225753

fbshipit-source-id: 2c5e7679636f31e0e7842d8a67aeb95baf47c563
This commit is contained in:
Felix Oghina
2016-09-29 03:43:59 -07:00
committed by Facebook Github Bot
parent 542ab8643e
commit 3080b8d26c
14 changed files with 650 additions and 31 deletions

View File

@@ -22,22 +22,17 @@ import com.facebook.react.common.SystemClock;
import com.facebook.react.modules.core.JSTimersExecution;
import com.facebook.react.modules.core.Timing;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import static org.mockito.Mockito.*;
@@ -189,6 +184,62 @@ public class TimingModuleTest {
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(41));
}
@Test
public void testHeadlessJsTaskInBackground() {
mTiming.onHostPause();
mTiming.onHeadlessJsTaskStart(42);
mTiming.createTimer(mExecutorTokenMock, 41, 1, 0, true);
stepChoreographerFrame();
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(41));
reset(mJSTimersMock);
mTiming.onHeadlessJsTaskFinish(42);
stepChoreographerFrame();
verifyNoMoreInteractions(mJSTimersMock);
}
@Test
public void testHeadlessJsTaskInForeground() {
mTiming.onHostResume();
mTiming.onHeadlessJsTaskStart(42);
mTiming.createTimer(mExecutorTokenMock, 41, 1, 0, true);
stepChoreographerFrame();
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(41));
reset(mJSTimersMock);
mTiming.onHeadlessJsTaskFinish(42);
stepChoreographerFrame();
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(41));
reset(mJSTimersMock);
mTiming.onHostPause();
verifyNoMoreInteractions(mJSTimersMock);
}
@Test
public void testHeadlessJsTaskIntertwine() {
mTiming.onHostResume();
mTiming.onHeadlessJsTaskStart(42);
mTiming.createTimer(mExecutorTokenMock, 41, 1, 0, true);
mTiming.onHostPause();
stepChoreographerFrame();
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(41));
reset(mJSTimersMock);
mTiming.onHostResume();
mTiming.onHeadlessJsTaskFinish(42);
stepChoreographerFrame();
verify(mJSTimersMock).callTimers(JavaOnlyArray.of(41));
reset(mJSTimersMock);
mTiming.onHostPause();
stepChoreographerFrame();
verifyNoMoreInteractions(mJSTimersMock);
}
@Test
public void testSetTimeoutZero() {
mTiming.createTimer(mExecutorTokenMock, 100, 0, 0, false);