Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ install:
- $yarn install

script:
- if [[ "$TEST_TYPE" = objc-ios ]]; then travis_retry travis_wait ./scripts/objc-test-ios.sh; fi
- if [[ "$TEST_TYPE" = objc-ios ]]; then travis_retry travis_wait ./scripts/objc-test-ios.sh test; fi
- if [[ "$TEST_TYPE" = objc-tvos ]]; then travis_retry travis_wait ./scripts/objc-test-tvos.sh; fi
- if [[ "$TEST_TYPE" = e2e-objc ]]; then node ./scripts/run-ci-e2e-tests.js --ios --js --retries 3; fi
- if [[ ( "$TEST_TYPE" = podspecs ) && ( "$TRAVIS_PULL_REQUEST" = "false" ) ]]; then gem install cocoapods && ./scripts/process-podspecs.sh; fi
Expand Down
42 changes: 29 additions & 13 deletions Libraries/Animated/src/AnimatedImplementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -1508,32 +1508,48 @@ class AnimatedStyle extends AnimatedWithChildren {
this._style = style;
}

__getValue(): Object {
var style = {};
for (var key in this._style) {
var value = this._style[key];
// Recursively get values for nested styles (like iOS's shadowOffset)
__walkStyleAndGetValues(style) {
let updatedStyle = {};
for (let key in style) {
let value = style[key];
if (value instanceof Animated) {
if (!value.__isNative) {
// We cannot use value of natively driven nodes this way as the value we have access from
// JS may not be up to date.
style[key] = value.__getValue();
updatedStyle[key] = value.__getValue();
}
} else if (value && !Array.isArray(value) && typeof value === 'object') {
// Support animating nested values (for example: shadowOffset.height)
updatedStyle[key] = this.__walkStyleAndGetValues(value);
} else {
style[key] = value;
updatedStyle[key] = value;
}
}
return style;
return updatedStyle;
}

__getAnimatedValue(): Object {
var style = {};
for (var key in this._style) {
var value = this._style[key];
__getValue(): Object {
return this.__walkStyleAndGetValues(this._style);
}

// Recursively get animated values for nested styles (like iOS's shadowOffset)
__walkStyleAndGetAnimatedValues(style) {
let updatedStyle = {};
for (let key in style) {
let value = style[key];
if (value instanceof Animated) {
style[key] = value.__getAnimatedValue();
updatedStyle[key] = value.__getAnimatedValue();
} else if (value && !Array.isArray(value) && typeof value === 'object') {
// Support animating nested values (for example: shadowOffset.height)
updatedStyle[key] = this.__walkStyleAndGetAnimatedValues(value);
}
}
return style;
return updatedStyle;
}

__getAnimatedValue(): Object {
return this.__walkStyleAndGetAnimatedValues(this._style);
}

__attach(): void {
Expand Down
14 changes: 13 additions & 1 deletion Libraries/Animated/src/__tests__/Animated-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ describe('Animated tests', () => {
outputRange: [100, 200],
})},
{scale: anim},
]
],
shadowOffset: {
width: anim,
height: anim,
},
}
}, callback);

Expand All @@ -47,6 +51,10 @@ describe('Animated tests', () => {
{translateX: 100},
{scale: 0},
],
shadowOffset: {
width: 0,
height: 0,
},
},
});

Expand All @@ -62,6 +70,10 @@ describe('Animated tests', () => {
{translateX: 150},
{scale: 0.5},
],
shadowOffset: {
width: 0.5,
height: 0.5,
},
},
});

Expand Down
19 changes: 19 additions & 0 deletions Libraries/Core/Timers/JSTimers.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// in dependencies. NativeModules > BatchedBridge > MessageQueue > JSTimersExecution
const RCTTiming = require('NativeModules').Timing;
const JSTimersExecution = require('JSTimersExecution');
const Platform = require('Platform');

const parseErrorStack = require('parseErrorStack');

Expand Down Expand Up @@ -64,6 +65,14 @@ function _freeCallback(timerID: number) {
}
}

const MAX_TIMER_DURATION_MS = 60 * 1000;
const IS_ANDROID = Platform.OS === 'android';
const ANDROID_LONG_TIMER_MESSAGE =
'Setting a timer for a long period of time, i.e. multiple minutes, is a ' +
'performance and correctness issue on Android as it keeps the timer ' +
'module awake, and timers can only be called when the app is in the foreground. ' +
'See https://github.com/facebook/react-native/issues/12981 for more info.';

/**
* JS implementation of timer functions. Must be completely driven by an
* external clock signal, all that's stored here is timerID, timer type, and
Expand All @@ -75,6 +84,11 @@ const JSTimers = {
* @param {number} duration Number of milliseconds.
*/
setTimeout: function(func: Function, duration: number, ...args?: any): number {
if (IS_ANDROID && duration > MAX_TIMER_DURATION_MS) {
console.warn(
ANDROID_LONG_TIMER_MESSAGE + '\n' + '(Saw setTimeout with duration ' +
duration + 'ms)');
}
const id = _allocateCallback(() => func.apply(undefined, args), 'setTimeout');
RCTTiming.createTimer(id, duration || 0, Date.now(), /* recurring */ false);
return id;
Expand All @@ -85,6 +99,11 @@ const JSTimers = {
* @param {number} duration Number of milliseconds.
*/
setInterval: function(func: Function, duration: number, ...args?: any): number {
if (IS_ANDROID && duration > MAX_TIMER_DURATION_MS) {
console.warn(
ANDROID_LONG_TIMER_MESSAGE + '\n' + '(Saw setInterval with duration ' +
duration + 'ms)');
}
const id = _allocateCallback(() => func.apply(undefined, args), 'setInterval');
RCTTiming.createTimer(id, duration || 0, Date.now(), /* recurring */ true);
return id;
Expand Down
2 changes: 1 addition & 1 deletion React/CxxModule/RCTCxxUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ template <>
struct ValueEncoder<NSArray *> {
static Value toValue(JSGlobalContextRef ctx, NSArray *const __strong array)
{
JSValue *value = [JSValue valueWithObject:array inContext:contextForGlobalContextRef(ctx)];
JSValue *value = [JSC_JSValue(ctx) valueWithObject:array inContext:contextForGlobalContextRef(ctx)];
return {ctx, [value JSValueRef]};
}
};
Expand Down
14 changes: 14 additions & 0 deletions React/Profiler/RCTProfile.m
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,20 @@ static dispatch_group_t RCTProfileGetUnhookGroup(void)
return unhookGroup;
}

// Used by RCTProfileTrampoline assembly file to call libc`malloc
RCT_EXTERN void *RCTProfileMalloc(size_t size);
void *RCTProfileMalloc(size_t size)
{
return malloc(size);
}

// Used by RCTProfileTrampoline assembly file to call libc`free
RCT_EXTERN void RCTProfileFree(void *buf);
void RCTProfileFree(void *buf)
{
free(buf);
}

RCT_EXTERN IMP RCTProfileGetImplementation(id obj, SEL cmd);
IMP RCTProfileGetImplementation(id obj, SEL cmd)
{
Expand Down
21 changes: 2 additions & 19 deletions React/Profiler/RCTProfileTrampoline-arm.S
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,7 @@ SYMBOL_NAME(RCTProfileTrampoline):
* profile
*/
mov r0, #0xc
movw ip, :lower16:(L_malloc-(LPC1_0+4))
movt ip, :upper16:(L_malloc-(LPC1_0+4))
LPC1_0:
add ip, pc
ldr ip, [ip]
blx ip
bl SYMBOL_NAME(RCTProfileMalloc)
/**
* r4 is the callee saved register we'll use to refer to the allocated memory,
* store its initial value, so we can restore it later
Expand Down Expand Up @@ -92,24 +87,12 @@ LPC1_0:
ldr r1, [r4, #0x8]
ldr r4, [r4]
push {r1} // save the caller on the stack
movw ip, :lower16:(L_free-(LPC1_1+4))
movt ip, :upper16:(L_free-(LPC1_1+4))
LPC1_1:
add ip, pc
ldr ip, [ip]
blx ip
bl SYMBOL_NAME(RCTProfileFree)

pop {lr} // pop the caller
pop {r0} // pop the return value
bx lr // jump to the calleer

trap

.data
.p2align 2
L_malloc:
.long SYMBOL_NAME(malloc)
L_free:
.long SYMBOL_NAME(free)

#endif
4 changes: 2 additions & 2 deletions React/Profiler/RCTProfileTrampoline-arm64.S
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ SYMBOL_NAME(RCTProfileTrampoline):
* the implementation and the caller address.
*/
mov x0, #0x10
bl SYMBOL_NAME(malloc)
bl SYMBOL_NAME(RCTProfileMalloc)
// store the initial value of r19, the callee saved register we'll use
str x19, [x0]
mov x19, x0
Expand Down Expand Up @@ -111,7 +111,7 @@ SYMBOL_NAME(RCTProfileTrampoline):
ldr x10, [x19, #0x8] // load the caller address
ldr x19, [x19] // restore x19
str x10, [sp, #0x18] // store x10 on the stack space allocated above
bl SYMBOL_NAME(free)
bl SYMBOL_NAME(RCTProfileFree)

// Load both return values and link register from the stack
ldr q0, [sp, #0x0]
Expand Down
4 changes: 2 additions & 2 deletions React/Profiler/RCTProfileTrampoline-i386.S
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ SYMBOL_NAME(RCTProfileTrampoline):
*/
subl $0x8, %esp // stack padding (16-byte alignment for function calls)
pushl $0xc // allocate 12-bytes
calll SYMBOL_NAME(malloc)
calll SYMBOL_NAME(RCTProfileMalloc)
addl $0xc, %esp // restore stack (8-byte padding + 4-byte argument)

/**
Expand Down Expand Up @@ -85,7 +85,7 @@ SYMBOL_NAME(RCTProfileTrampoline):
* the stack has already been padded and the first and only argument, the
* memory address, is already in the bottom of the stack.
*/
calll SYMBOL_NAME(free)
calll SYMBOL_NAME(RCTProfileFree)
addl $0x8, %esp

/**
Expand Down
4 changes: 2 additions & 2 deletions React/Profiler/RCTProfileTrampoline-x86_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ SYMBOL_NAME(RCTProfileTrampoline):

// allocate 16 bytes
movq $0x10, %rdi
callq SYMBOL_NAME_PIC(malloc)
callq SYMBOL_NAME_PIC(RCTProfileMalloc)

// store the initial value of calle saved registers %r13 and %r14
movq %r13, 0x0(%rax)
Expand Down Expand Up @@ -169,7 +169,7 @@ SYMBOL_NAME(RCTProfileTrampoline):
andq $-0x10, %rsp

// Free the memory allocated to stash callee saved registers
callq SYMBOL_NAME_PIC(free)
callq SYMBOL_NAME_PIC(RCTProfileFree)

// unalign stack and restore %r12
movq %r12, %rsp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import com.facebook.react.devsupport.DevSupportManagerFactory;
import com.facebook.react.devsupport.ReactInstanceDevCommandsHandler;
import com.facebook.react.devsupport.RedBoxHandler;
import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener;
import com.facebook.react.devsupport.interfaces.DevSupportManager;
import com.facebook.react.devsupport.interfaces.PackagerStatusCallback;
import com.facebook.react.modules.appregistry.AppRegistry;
Expand Down Expand Up @@ -310,7 +311,8 @@ public static ReactInstanceManagerBuilder builder() {
JSCConfig jscConfig,
@Nullable RedBoxHandler redBoxHandler,
boolean lazyNativeModulesEnabled,
boolean lazyViewManagersEnabled) {
boolean lazyViewManagersEnabled,
@Nullable DevBundleDownloadListener devBundleDownloadListener) {

initializeSoLoaderIfNecessary(applicationContext);

Expand All @@ -330,7 +332,8 @@ public static ReactInstanceManagerBuilder builder() {
mDevInterface,
mJSMainModuleName,
useDeveloperSupport,
redBoxHandler);
redBoxHandler,
devBundleDownloadListener);
mBridgeIdleDebugListener = bridgeIdleDebugListener;
mLifecycleState = initialLifecycleState;
mUIImplementationProvider = uiImplementationProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.facebook.react.bridge.NotThreadSafeBridgeIdleDebugListener;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.cxxbridge.JSBundleLoader;
import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener;
import com.facebook.react.devsupport.interfaces.DevSupportManager;
import com.facebook.react.devsupport.RedBoxHandler;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
Expand Down Expand Up @@ -42,6 +43,7 @@ public class ReactInstanceManagerBuilder {
protected @Nullable RedBoxHandler mRedBoxHandler;
protected boolean mLazyNativeModulesEnabled;
protected boolean mLazyViewManagersEnabled;
protected @Nullable DevBundleDownloadListener mDevBundleDownloadListener;

/* package protected */ ReactInstanceManagerBuilder() {
}
Expand Down Expand Up @@ -186,6 +188,11 @@ public ReactInstanceManagerBuilder setLazyViewManagersEnabled(boolean lazyViewMa
return this;
}

public ReactInstanceManagerBuilder setDevBundleDownloadListener(@Nullable DevBundleDownloadListener listener) {
mDevBundleDownloadListener = listener;
return this;
}

/**
* Instantiates a new {@link ReactInstanceManager}.
* Before calling {@code build}, the following must be called:
Expand Down Expand Up @@ -230,6 +237,7 @@ public ReactInstanceManager build() {
mJSCConfig,
mRedBoxHandler,
mLazyNativeModulesEnabled,
mLazyViewManagersEnabled);
mLazyViewManagersEnabled,
mDevBundleDownloadListener);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.network.OkHttpCallUtil;
import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener;
import com.facebook.react.devsupport.interfaces.PackagerStatusCallback;
import com.facebook.react.modules.systeminfo.AndroidInfoHelpers;
import com.facebook.react.packagerconnection.FileIoHandler;
Expand Down Expand Up @@ -84,12 +85,6 @@ public class DevServerHelper {
private static final int LONG_POLL_FAILURE_DELAY_MS = 5000;
private static final int HTTP_CONNECT_TIMEOUT_MS = 5000;

public interface BundleDownloadCallback {
void onSuccess();
void onProgress(@Nullable String status, @Nullable Integer done, @Nullable Integer total);
void onFailure(Exception cause);
}

public interface OnServerContentChangeListener {
void onServerContentChanged();
}
Expand Down Expand Up @@ -302,7 +297,7 @@ public String getDevServerBundleURL(final String jsModulePath) {
}

public void downloadBundleFromURL(
final BundleDownloadCallback callback,
final DevBundleDownloadListener callback,
final File outputFile,
final String bundleURL) {
final Request request = new Request.Builder()
Expand Down Expand Up @@ -400,7 +395,7 @@ private void processBundleResult(
int statusCode,
BufferedSource body,
File outputFile,
BundleDownloadCallback callback) throws IOException {
DevBundleDownloadListener callback) throws IOException {
// Check for server errors. If the server error has the expected form, fail with more info.
if (statusCode != 200) {
String bodyString = body.readUtf8();
Expand Down
Loading