Make NativeModules TurboModule-compatible

Summary:
All these NativeModules are now: (1) type-safe, (2) TurboModule-compatible.

**Note:** We still need to update `{Catalyst,Work,Fb4a}TurboModuleManagerDelegate` to understand these TurboModules. I'll most likely write up that diff and stack this one on top of it.

Changelog:
[Android][Added] - Make NativeModules TurboModule-compatible

Reviewed By: mdvacca

Differential Revision: D18888735

fbshipit-source-id: 34df64dc70e3f3a0a0303c049861205f9d3fd2ed
This commit is contained in:
Ramanpreet Nara
2019-12-15 16:56:53 -08:00
committed by Facebook Github Bot
parent 80bc51195e
commit 96a6ffb3e8
28 changed files with 342 additions and 222 deletions
@@ -9,13 +9,12 @@ package com.facebook.react.animated;
import androidx.annotation.Nullable;
import com.facebook.common.logging.FLog;
import com.facebook.fbreact.specs.NativeAnimatedModuleSpec;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.ReactConstants;
@@ -75,7 +74,7 @@ import java.util.ArrayList;
* while UI thread is "executing" the animation loop.
*/
@ReactModule(name = NativeAnimatedModule.NAME)
public class NativeAnimatedModule extends ReactContextBaseJavaModule
public class NativeAnimatedModule extends NativeAnimatedModuleSpec
implements LifecycleEventListener, UIManagerModuleListener {
public static final String NAME = "NativeAnimatedModule";
@@ -110,7 +109,7 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
// and no outstanding tasks on the operations queue. Apparently frame callbacks can
// only
// be posted from the UI thread and therefore we cannot schedule them directly from
// @ReactMethod methods
// @Override
Assertions.assertNotNull(mReactChoreographer)
.postFrameCallback(
ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE,
@@ -216,8 +215,10 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
mNodesManager = nodesManager;
}
@ReactMethod
public void createAnimatedNode(final int tag, final ReadableMap config) {
@Override
public void createAnimatedNode(final double tagDouble, final ReadableMap config) {
final int tag = (int) tagDouble;
mOperations.add(
new UIThreadOperation() {
@Override
@@ -227,8 +228,10 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
public void startListeningToAnimatedNodeValue(final int tag) {
@Override
public void startListeningToAnimatedNodeValue(final double tagDouble) {
final int tag = (int) tagDouble;
final AnimatedNodeValueListener listener =
new AnimatedNodeValueListener() {
public void onValueUpdate(double value) {
@@ -255,8 +258,10 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
public void stopListeningToAnimatedNodeValue(final int tag) {
@Override
public void stopListeningToAnimatedNodeValue(final double tagDouble) {
final int tag = (int) tagDouble;
mOperations.add(
new UIThreadOperation() {
@Override
@@ -266,8 +271,10 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
public void dropAnimatedNode(final int tag) {
@Override
public void dropAnimatedNode(final double tagDouble) {
final int tag = (int) tagDouble;
mOperations.add(
new UIThreadOperation() {
@Override
@@ -277,8 +284,10 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
public void setAnimatedNodeValue(final int tag, final double value) {
@Override
public void setAnimatedNodeValue(final double tagDouble, final double value) {
final int tag = (int) tagDouble;
mOperations.add(
new UIThreadOperation() {
@Override
@@ -288,8 +297,10 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
public void setAnimatedNodeOffset(final int tag, final double value) {
@Override
public void setAnimatedNodeOffset(final double tagDouble, final double value) {
final int tag = (int) tagDouble;
mOperations.add(
new UIThreadOperation() {
@Override
@@ -299,8 +310,10 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
public void flattenAnimatedNodeOffset(final int tag) {
@Override
public void flattenAnimatedNodeOffset(final double tagDouble) {
final int tag = (int) tagDouble;
mOperations.add(
new UIThreadOperation() {
@Override
@@ -310,8 +323,10 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
public void extractAnimatedNodeOffset(final int tag) {
@Override
public void extractAnimatedNodeOffset(final double tagDouble) {
final int tag = (int) tagDouble;
mOperations.add(
new UIThreadOperation() {
@Override
@@ -321,12 +336,15 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
@Override
public void startAnimatingNode(
final int animationId,
final int animatedNodeTag,
final double animationIdDouble,
final double animatedNodeTagDouble,
final ReadableMap animationConfig,
final Callback endCallback) {
final int animationId = (int) animationIdDouble;
final int animatedNodeTag = (int) animatedNodeTagDouble;
mOperations.add(
new UIThreadOperation() {
@Override
@@ -337,8 +355,10 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
public void stopAnimation(final int animationId) {
@Override
public void stopAnimation(final double animationIdDouble) {
final int animationId = (int) animationIdDouble;
mOperations.add(
new UIThreadOperation() {
@Override
@@ -348,8 +368,12 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
public void connectAnimatedNodes(final int parentNodeTag, final int childNodeTag) {
@Override
public void connectAnimatedNodes(
final double parentNodeTagDouble, final double childNodeTagDouble) {
final int parentNodeTag = (int) parentNodeTagDouble;
final int childNodeTag = (int) childNodeTagDouble;
mOperations.add(
new UIThreadOperation() {
@Override
@@ -359,8 +383,12 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
public void disconnectAnimatedNodes(final int parentNodeTag, final int childNodeTag) {
@Override
public void disconnectAnimatedNodes(
final double parentNodeTagDouble, final double childNodeTagDouble) {
final int parentNodeTag = (int) parentNodeTagDouble;
final int childNodeTag = (int) childNodeTagDouble;
mOperations.add(
new UIThreadOperation() {
@Override
@@ -370,8 +398,12 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
public void connectAnimatedNodeToView(final int animatedNodeTag, final int viewTag) {
@Override
public void connectAnimatedNodeToView(
final double animatedNodeTagDouble, final double viewTagDouble) {
final int animatedNodeTag = (int) animatedNodeTagDouble;
final int viewTag = (int) viewTagDouble;
mOperations.add(
new UIThreadOperation() {
@Override
@@ -381,8 +413,12 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
public void disconnectAnimatedNodeFromView(final int animatedNodeTag, final int viewTag) {
@Override
public void disconnectAnimatedNodeFromView(
final double animatedNodeTagDouble, final double viewTagDouble) {
final int animatedNodeTag = (int) animatedNodeTagDouble;
final int viewTag = (int) viewTagDouble;
mOperations.add(
new UIThreadOperation() {
@Override
@@ -392,8 +428,10 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
public void restoreDefaultValues(final int animatedNodeTag) {
@Override
public void restoreDefaultValues(final double animatedNodeTagDouble) {
final int animatedNodeTag = (int) animatedNodeTagDouble;
mPreOperations.add(
new UIThreadOperation() {
@Override
@@ -403,9 +441,11 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
@Override
public void addAnimatedEventToView(
final int viewTag, final String eventName, final ReadableMap eventMapping) {
final double viewTagDouble, final String eventName, final ReadableMap eventMapping) {
final int viewTag = (int) viewTagDouble;
mOperations.add(
new UIThreadOperation() {
@Override
@@ -415,9 +455,12 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
});
}
@ReactMethod
@Override
public void removeAnimatedEventFromView(
final int viewTag, final String eventName, final int animatedValueTag) {
final double viewTagDouble, final String eventName, final double animatedValueTagDouble) {
final int viewTag = (int) viewTagDouble;
final int animatedValueTag = (int) animatedValueTagDouble;
mOperations.add(
new UIThreadOperation() {
@Override
@@ -426,4 +469,14 @@ public class NativeAnimatedModule extends ReactContextBaseJavaModule
}
});
}
@Override
public void addListener(String eventName) {
// iOS only
}
@Override
public void removeListeners(double count) {
// iOS only
}
}
@@ -10,16 +10,15 @@ package com.facebook.react.devsupport;
import android.util.Pair;
import android.view.View;
import androidx.annotation.Nullable;
import com.facebook.fbreact.specs.NativeJSDevSupportSpec;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;
import java.util.HashMap;
import java.util.Map;
@ReactModule(name = JSDevSupport.MODULE_NAME)
public class JSDevSupport extends ReactContextBaseJavaModule {
public class JSDevSupport extends NativeJSDevSupportSpec {
public static final String MODULE_NAME = "JSDevSupport";
public static final int ERROR_CODE_EXCEPTION = 0;
@@ -72,7 +71,7 @@ public class JSDevSupport extends ReactContextBaseJavaModule {
}
@SuppressWarnings("unused")
@ReactMethod
@Override
public synchronized void onSuccess(String data) {
if (mCurrentCallback != null) {
mCurrentCallback.onSuccess(data);
@@ -80,15 +79,17 @@ public class JSDevSupport extends ReactContextBaseJavaModule {
}
@SuppressWarnings("unused")
@ReactMethod
public synchronized void onFailure(int errorCode, String error) {
@Override
public synchronized void onFailure(double errorCodeDouble, String error) {
int errorCode = (int) errorCodeDouble;
if (mCurrentCallback != null) {
mCurrentCallback.onFailure(errorCode, new RuntimeException(error));
}
}
@Override
public Map<String, Object> getConstants() {
public Map<String, Object> getTypedExportedConstants() {
HashMap<String, Object> constants = new HashMap<>();
constants.put("ERROR_CODE_EXCEPTION", ERROR_CODE_EXCEPTION);
constants.put("ERROR_CODE_VIEW_NOT_FOUND", ERROR_CODE_VIEW_NOT_FOUND);
@@ -19,11 +19,10 @@ import android.provider.Settings;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import androidx.annotation.Nullable;
import com.facebook.fbreact.specs.NativeAccessibilityInfoSpec;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;
@@ -32,7 +31,7 @@ import com.facebook.react.modules.core.DeviceEventManagerModule;
* device. For API >= 19.
*/
@ReactModule(name = AccessibilityInfoModule.NAME)
public class AccessibilityInfoModule extends ReactContextBaseJavaModule
public class AccessibilityInfoModule extends NativeAccessibilityInfoSpec
implements LifecycleEventListener {
public static final String NAME = "AccessibilityInfo";
@@ -101,12 +100,12 @@ public class AccessibilityInfoModule extends ReactContextBaseJavaModule
return value != null && value.equals("0.0");
}
@ReactMethod
@Override
public void isReduceMotionEnabled(Callback successCallback) {
successCallback.invoke(mReduceMotionEnabled);
}
@ReactMethod
@Override
public void isTouchExplorationEnabled(Callback successCallback) {
successCallback.invoke(mTouchExplorationEnabled);
}
@@ -183,7 +182,7 @@ public class AccessibilityInfoModule extends ReactContextBaseJavaModule
@Override
public void onHostDestroy() {}
@ReactMethod
@Override
public void announceForAccessibility(String message) {
if (mAccessibilityManager == null || !mAccessibilityManager.isEnabled()) {
return;
@@ -196,4 +195,9 @@ public class AccessibilityInfoModule extends ReactContextBaseJavaModule
mAccessibilityManager.sendAccessibilityEvent(event);
}
@Override
public void setAccessibilityFocus(double reactTag) {
// iOS only
}
}
@@ -9,17 +9,16 @@ package com.facebook.react.modules.appearance;
import android.content.Context;
import android.content.res.Configuration;
import com.facebook.fbreact.specs.NativeAppearanceSpec;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
/** Module that exposes the user's preferred color scheme. */
@ReactModule(name = AppearanceModule.NAME)
public class AppearanceModule extends ReactContextBaseJavaModule {
public class AppearanceModule extends NativeAppearanceSpec {
public static final String NAME = "Appearance";
@@ -51,18 +50,18 @@ public class AppearanceModule extends ReactContextBaseJavaModule {
return NAME;
}
@ReactMethod(isBlockingSynchronousMethod = true)
@Override
public String getColorScheme() {
mColorScheme = colorSchemeForCurrentConfiguration(getReactApplicationContext());
return mColorScheme;
}
/** Stub */
@ReactMethod
@Override
public void addListener(String eventName) {}
/** Stub */
@ReactMethod
@Override
public void removeListeners(double count) {}
/*
@@ -7,12 +7,11 @@
package com.facebook.react.modules.appstate;
import com.facebook.fbreact.specs.NativeAppStateSpec;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WindowFocusChangeListener;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.LifecycleState;
@@ -23,7 +22,7 @@ import java.util.Map;
import javax.annotation.Nullable;
@ReactModule(name = AppStateModule.NAME)
public class AppStateModule extends ReactContextBaseJavaModule
public class AppStateModule extends NativeAppStateSpec
implements LifecycleEventListener, WindowFocusChangeListener {
public static final String TAG = AppStateModule.class.getSimpleName();
@@ -52,13 +51,13 @@ public class AppStateModule extends ReactContextBaseJavaModule
}
@Override
public Map<String, Object> getConstants() {
public Map<String, Object> getTypedExportedConstants() {
HashMap<String, Object> constants = new HashMap<>();
constants.put(INITIAL_STATE, mAppState);
return constants;
}
@ReactMethod
@Override
public void getCurrentAppState(Callback success, Callback error) {
success.invoke(createAppStateEventMap());
}
@@ -103,4 +102,14 @@ public class AppStateModule extends ReactContextBaseJavaModule
private void sendAppStateChangeEvent() {
sendEvent("appStateDidChange", createAppStateEventMap());
}
@Override
public void addListener(String eventName) {
// iOS only
}
@Override
public void removeListeners(double count) {
// iOS only
}
}
@@ -13,11 +13,10 @@ import android.net.Uri;
import android.provider.MediaStore;
import android.webkit.MimeTypeMap;
import androidx.annotation.Nullable;
import com.facebook.fbreact.specs.NativeBlobModuleSpec;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
@@ -43,7 +42,7 @@ import okhttp3.ResponseBody;
import okio.ByteString;
@ReactModule(name = BlobModule.NAME)
public class BlobModule extends ReactContextBaseJavaModule {
public class BlobModule extends NativeBlobModuleSpec {
public static final String NAME = "BlobModule";
@@ -156,7 +155,7 @@ public class BlobModule extends ReactContextBaseJavaModule {
}
@Override
public @Nullable Map<String, Object> getConstants() {
public @Nullable Map<String, Object> getTypedExportedConstants() {
// The application can register BlobProvider as a ContentProvider so that blobs are resolvable.
// If it does, it needs to tell us what authority was used via this string resource.
Resources resources = getReactApplicationContext().getResources();
@@ -296,7 +295,7 @@ public class BlobModule extends ReactContextBaseJavaModule {
return null;
}
@ReactMethod
@Override
public void addNetworkingHandler() {
ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn();
@@ -309,8 +308,10 @@ public class BlobModule extends ReactContextBaseJavaModule {
}
}
@ReactMethod
public void addWebSocketHandler(final int id) {
@Override
public void addWebSocketHandler(final double idDouble) {
final int id = (int) idDouble;
WebSocketModule webSocketModule = getWebSocketModule("addWebSocketHandler");
if (webSocketModule != null) {
@@ -318,8 +319,10 @@ public class BlobModule extends ReactContextBaseJavaModule {
}
}
@ReactMethod
public void removeWebSocketHandler(final int id) {
@Override
public void removeWebSocketHandler(final double idDouble) {
final int id = (int) idDouble;
WebSocketModule webSocketModule = getWebSocketModule("removeWebSocketHandler");
if (webSocketModule != null) {
@@ -327,8 +330,10 @@ public class BlobModule extends ReactContextBaseJavaModule {
}
}
@ReactMethod
public void sendOverSocket(ReadableMap blob, int id) {
@Override
public void sendOverSocket(ReadableMap blob, double idDouble) {
int id = (int) idDouble;
WebSocketModule webSocketModule = getWebSocketModule("sendOverSocket");
if (webSocketModule != null) {
@@ -342,7 +347,7 @@ public class BlobModule extends ReactContextBaseJavaModule {
}
}
@ReactMethod
@Override
public void createFromParts(ReadableArray parts, String blobId) {
int totalBlobSize = 0;
ArrayList<byte[]> partList = new ArrayList<>(parts.size());
@@ -370,7 +375,7 @@ public class BlobModule extends ReactContextBaseJavaModule {
store(buffer.array(), blobId);
}
@ReactMethod
@Override
public void release(String blobId) {
remove(blobId);
}
@@ -8,15 +8,14 @@
package com.facebook.react.modules.blob;
import android.util.Base64;
import com.facebook.fbreact.specs.NativeFileReaderModuleSpec;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.module.annotations.ReactModule;
@ReactModule(name = FileReaderModule.NAME)
public class FileReaderModule extends ReactContextBaseJavaModule {
public class FileReaderModule extends NativeFileReaderModuleSpec {
public static final String NAME = "FileReaderModule";
private static final String ERROR_INVALID_BLOB = "ERROR_INVALID_BLOB";
@@ -40,7 +39,7 @@ public class FileReaderModule extends ReactContextBaseJavaModule {
return null;
}
@ReactMethod
@Override
public void readAsText(ReadableMap blob, String encoding, Promise promise) {
BlobModule blobModule = getBlobModule("readAsText");
@@ -65,7 +64,7 @@ public class FileReaderModule extends ReactContextBaseJavaModule {
}
}
@ReactMethod
@Override
public void readAsDataURL(ReadableMap blob, Promise promise) {
BlobModule blobModule = getBlobModule("readAsDataURL");
@@ -22,14 +22,13 @@ import android.provider.MediaStore.Images;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import com.facebook.common.logging.FLog;
import com.facebook.fbreact.specs.NativeCameraRollManagerSpec;
import com.facebook.react.bridge.GuardedAsyncTask;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableArray;
@@ -56,7 +55,7 @@ import java.util.List;
* {@link MediaStore.Images}).
*/
@ReactModule(name = CameraRollManager.NAME)
public class CameraRollManager extends ReactContextBaseJavaModule {
public class CameraRollManager extends NativeCameraRollManagerSpec {
public static final String NAME = "CameraRollManager";
@@ -102,7 +101,7 @@ public class CameraRollManager extends ReactContextBaseJavaModule {
* @param uri the file://, http:// or https:// URI of the image to save
* @param promise to be resolved or rejected
*/
@ReactMethod
@Override
public void saveToCameraRoll(String uri, String type, Promise promise) {
new SaveToCameraRoll(getReactApplicationContext(), Uri.parse(uri), promise)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@@ -223,7 +222,7 @@ public class CameraRollManager extends ReactContextBaseJavaModule {
* @param promise the Promise to be resolved when the photos are loaded; for a format of the
* parameters passed to this callback, see {@code getPhotosReturnChecker} in CameraRoll.js
*/
@ReactMethod
@Override
public void getPhotos(final ReadableMap params, final Promise promise) {
int first = params.getInt("first");
String after = params.hasKey("after") ? params.getString("after") : null;
@@ -523,4 +522,9 @@ public class CameraRollManager extends ReactContextBaseJavaModule {
node.putMap("location", location);
}
}
@Override
public void deletePhotos(ReadableArray assets, Promise promise) {
// iOS only
}
}
@@ -22,14 +22,13 @@ import android.provider.MediaStore;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import com.facebook.common.logging.FLog;
import com.facebook.fbreact.specs.NativeImageEditorSpec;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.GuardedAsyncTask;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.module.annotations.ReactModule;
@@ -46,7 +45,7 @@ import java.util.List;
/** Native module that provides image cropping functionality. */
@ReactModule(name = ImageEditingManager.NAME)
public class ImageEditingManager extends ReactContextBaseJavaModule {
public class ImageEditingManager extends NativeImageEditorSpec {
public static final String NAME = "ImageEditingManager";
@@ -154,7 +153,7 @@ public class ImageEditingManager extends ReactContextBaseJavaModule {
* is passed to this callback is the file:// URI of the new image
* @param error callback to be invoked when an error occurs (e.g. can't create file etc.)
*/
@ReactMethod
@Override
public void cropImage(
String uri, ReadableMap options, final Callback success, final Callback error) {
ReadableMap offset = options.hasKey("offset") ? options.getMap("offset") : null;
@@ -12,12 +12,11 @@ import android.net.Uri;
import android.os.AsyncTask;
import android.util.Base64;
import android.util.Base64OutputStream;
import com.facebook.fbreact.specs.NativeImageStoreSpec;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.GuardedAsyncTask;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
@@ -26,7 +25,7 @@ import java.io.IOException;
import java.io.InputStream;
@ReactModule(name = ImageStoreManager.NAME)
public class ImageStoreManager extends ReactContextBaseJavaModule {
public class ImageStoreManager extends NativeImageStoreSpec {
public static final String NAME = "ImageStoreManager";
private static final int BUFFER_SIZE = 8192;
@@ -47,7 +46,7 @@ public class ImageStoreManager extends ReactContextBaseJavaModule {
* @param success callback to be invoked with the base64 string as the only argument
* @param error callback to be invoked on error (e.g. file not found, not readable etc.)
*/
@ReactMethod
@Override
public void getBase64ForTag(String uri, Callback success, Callback error) {
new GetBase64Task(getReactApplicationContext(), uri, success, error)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@@ -106,4 +105,20 @@ public class ImageStoreManager extends ReactContextBaseJavaModule {
// shhh
}
}
@Override
public void hasImageForTag(String uri, Callback callback) {
// iOS only
}
@Override
public void removeImageForTag(String uri) {
// iOS only
}
@Override
public void addImageFromBase64(
String base64ImageData, Callback successCallback, Callback errorCallback) {
// iOS only
}
}
@@ -10,19 +10,18 @@ package com.facebook.react.modules.core;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.facebook.fbreact.specs.NativeDeviceEventManagerSpec;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.module.annotations.ReactModule;
/** Native module that handles device hardware events like hardware back presses. */
@ReactModule(name = DeviceEventManagerModule.NAME)
public class DeviceEventManagerModule extends ReactContextBaseJavaModule {
public class DeviceEventManagerModule extends NativeDeviceEventManagerSpec {
public static final String NAME = "DeviceEventManager";
@DoNotStrip
@@ -71,7 +70,7 @@ public class DeviceEventManagerModule extends ReactContextBaseJavaModule {
* Invokes the default back handler for the host of this catalyst instance. This should be invoked
* if JS does not want to handle the back press itself.
*/
@ReactMethod
@Override
public void invokeDefaultBackPressHandler() {
// There should be no need to check if the catalyst instance is alive. After initialization
// the thread instances cannot be null, and scheduling on a thread after ReactApplicationContext
@@ -8,10 +8,9 @@
package com.facebook.react.modules.core;
import com.facebook.common.logging.FLog;
import com.facebook.fbreact.specs.NativeExceptionsManagerSpec;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.JavaOnlyMap;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.JavascriptException;
@@ -22,13 +21,14 @@ import com.facebook.react.util.ExceptionDataHelper;
import com.facebook.react.util.JSStackTrace;
@ReactModule(name = ExceptionsManagerModule.NAME)
public class ExceptionsManagerModule extends ReactContextBaseJavaModule {
public class ExceptionsManagerModule extends NativeExceptionsManagerSpec {
public static final String NAME = "ExceptionsManager";
private final DevSupportManager mDevSupportManager;
public ExceptionsManagerModule(DevSupportManager devSupportManager) {
super(null);
mDevSupportManager = devSupportManager;
}
@@ -37,8 +37,10 @@ public class ExceptionsManagerModule extends ReactContextBaseJavaModule {
return NAME;
}
@ReactMethod
public void reportFatalException(String message, ReadableArray stack, int id) {
@Override
public void reportFatalException(String message, ReadableArray stack, double idDouble) {
int id = (int) idDouble;
JavaOnlyMap data = new JavaOnlyMap();
data.putString("message", message);
data.putArray("stack", stack);
@@ -47,8 +49,10 @@ public class ExceptionsManagerModule extends ReactContextBaseJavaModule {
reportException(data);
}
@ReactMethod
public void reportSoftException(String message, ReadableArray stack, int id) {
@Override
public void reportSoftException(String message, ReadableArray stack, double idDouble) {
int id = (int) idDouble;
JavaOnlyMap data = new JavaOnlyMap();
data.putString("message", message);
data.putArray("stack", stack);
@@ -57,7 +61,7 @@ public class ExceptionsManagerModule extends ReactContextBaseJavaModule {
reportException(data);
}
@ReactMethod
@Override
public void reportException(ReadableMap data) {
String message = data.hasKey("message") ? data.getString("message") : "";
ReadableArray stack = data.hasKey("stack") ? data.getArray("stack") : Arguments.createArray();
@@ -87,14 +91,17 @@ public class ExceptionsManagerModule extends ReactContextBaseJavaModule {
}
}
@ReactMethod
public void updateExceptionMessage(String title, ReadableArray details, int exceptionId) {
@Override
public void updateExceptionMessage(
String title, ReadableArray details, double exceptionIdDouble) {
int exceptionId = (int) exceptionIdDouble;
if (mDevSupportManager.getDevSupportEnabled()) {
mDevSupportManager.updateJSError(title, details, exceptionId);
}
}
@ReactMethod
@Override
public void dismissRedbox() {
if (mDevSupportManager.getDevSupportEnabled()) {
mDevSupportManager.hideRedboxDialog();
@@ -8,10 +8,9 @@
package com.facebook.react.modules.core;
import com.facebook.common.logging.FLog;
import com.facebook.fbreact.specs.NativeHeadlessJsTaskSupportSpec;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.jstasks.HeadlessJsTaskContext;
import com.facebook.react.module.annotations.ReactModule;
@@ -20,7 +19,7 @@ import com.facebook.react.module.annotations.ReactModule;
* it can e.g. release any resources, stop timers etc.
*/
@ReactModule(name = HeadlessJsTaskSupportModule.NAME)
public class HeadlessJsTaskSupportModule extends ReactContextBaseJavaModule {
public class HeadlessJsTaskSupportModule extends NativeHeadlessJsTaskSupportSpec {
public static final String NAME = "HeadlessJsTaskSupport";
@@ -33,8 +32,10 @@ public class HeadlessJsTaskSupportModule extends ReactContextBaseJavaModule {
return NAME;
}
@ReactMethod
public void notifyTaskRetry(int taskId, Promise promise) {
@Override
public void notifyTaskRetry(double taskIdDouble, Promise promise) {
int taskId = (int) taskIdDouble;
HeadlessJsTaskContext headlessJsTaskContext =
HeadlessJsTaskContext.getInstance(getReactApplicationContext());
if (headlessJsTaskContext.isTaskRunning(taskId)) {
@@ -49,8 +50,10 @@ public class HeadlessJsTaskSupportModule extends ReactContextBaseJavaModule {
}
}
@ReactMethod
public void notifyTaskFinished(int taskId) {
@Override
public void notifyTaskFinished(double taskIdDouble) {
int taskId = (int) taskIdDouble;
HeadlessJsTaskContext headlessJsTaskContext =
HeadlessJsTaskContext.getInstance(getReactApplicationContext());
if (headlessJsTaskContext.isTaskRunning(taskId)) {
@@ -7,10 +7,9 @@
package com.facebook.react.modules.core;
import com.facebook.fbreact.specs.NativeTimingSpec;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.devsupport.interfaces.DevSupportManager;
import com.facebook.react.jstasks.HeadlessJsTaskContext;
@@ -19,7 +18,7 @@ import com.facebook.react.module.annotations.ReactModule;
/** Native module for JS timer execution. Timers fire on frame boundaries. */
@ReactModule(name = TimingModule.NAME)
public final class TimingModule extends ReactContextBaseJavaModule
public final class TimingModule extends NativeTimingSpec
implements LifecycleEventListener, HeadlessJsTaskEventListener {
public class BridgeTimerManager implements JavaScriptTimerManager {
@@ -79,21 +78,26 @@ public final class TimingModule extends ReactContextBaseJavaModule
return NAME;
}
@ReactMethod
@Override
public void createTimer(
final int callbackID,
final int duration,
final double callbackIDDouble,
final double durationDouble,
final double jsSchedulingTime,
final boolean repeat) {
final int callbackID = (int) callbackIDDouble;
final int duration = (int) durationDouble;
mJavaTimerManager.createAndMaybeCallTimer(callbackID, duration, jsSchedulingTime, repeat);
}
@ReactMethod
public void deleteTimer(int timerId) {
@Override
public void deleteTimer(double timerIdDouble) {
int timerId = (int) timerIdDouble;
mJavaTimerManager.deleteTimer(timerId);
}
@ReactMethod
@Override
public void setSendIdleEvents(final boolean sendIdleEvents) {
mJavaTimerManager.setSendIdleEvents(sendIdleEvents);
}
@@ -18,6 +18,7 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import com.facebook.fbreact.specs.NativeDatePickerAndroidSpec;
import com.facebook.react.bridge.*;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.module.annotations.ReactModule;
@@ -27,7 +28,7 @@ import com.facebook.react.module.annotations.ReactModule;
* the user selects a date.
*/
@ReactModule(name = DatePickerDialogModule.FRAGMENT_TAG)
public class DatePickerDialogModule extends ReactContextBaseJavaModule {
public class DatePickerDialogModule extends NativeDatePickerAndroidSpec {
@VisibleForTesting public static final String FRAGMENT_TAG = "DatePickerAndroid";
@@ -45,7 +46,6 @@ public class DatePickerDialogModule extends ReactContextBaseJavaModule {
super(reactContext);
}
@Override
public @NonNull String getName() {
return DatePickerDialogModule.FRAGMENT_TAG;
}
@@ -100,7 +100,7 @@ public class DatePickerDialogModule extends ReactContextBaseJavaModule {
* action is {@code dateSetAction} or {@code dismissedAction}, depending on what the user did.
* If the action is dismiss, year, month and date are undefined.
*/
@ReactMethod
@Override
public void open(@Nullable final ReadableMap options, Promise promise) {
Activity raw_activity = getCurrentActivity();
if (raw_activity == null || !(raw_activity instanceof FragmentActivity)) {
@@ -10,10 +10,9 @@ package com.facebook.react.modules.debug;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.facebook.common.logging.FLog;
import com.facebook.fbreact.specs.NativeAnimationsDebugModuleSpec;
import com.facebook.react.bridge.JSApplicationCausedNativeException;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.debug.interfaces.DeveloperSettings;
@@ -24,7 +23,7 @@ import java.util.Locale;
* going from one screen to another).
*/
@ReactModule(name = AnimationsDebugModule.NAME)
public class AnimationsDebugModule extends ReactContextBaseJavaModule {
public class AnimationsDebugModule extends NativeAnimationsDebugModuleSpec {
protected static final String NAME = "AnimationsDebugModule";
@@ -42,7 +41,7 @@ public class AnimationsDebugModule extends ReactContextBaseJavaModule {
return NAME;
}
@ReactMethod
@Override
public void startRecordingFps() {
if (mCatalystSettings == null || !mCatalystSettings.isAnimationFpsDebugEnabled()) {
return;
@@ -61,7 +60,7 @@ public class AnimationsDebugModule extends ReactContextBaseJavaModule {
* (unix time) so that we know when the animation stopped from the JS perspective and we don't
* count time after as being part of the animation.
*/
@ReactMethod
@Override
public void stopRecordingFps(double animationStopTimeMs) {
if (mFrameCallback == null) {
return;
@@ -7,10 +7,9 @@
package com.facebook.react.modules.debug;
import com.facebook.fbreact.specs.NativeDevSettingsSpec;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.devsupport.interfaces.DevOptionHandler;
@@ -22,7 +21,7 @@ import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEm
* Module that exposes the URL to the source code map (used for exception stack trace parsing) to JS
*/
@ReactModule(name = DevSettingsModule.NAME)
public class DevSettingsModule extends ReactContextBaseJavaModule {
public class DevSettingsModule extends NativeDevSettingsSpec {
public static final String NAME = "DevSettings";
@@ -40,7 +39,7 @@ public class DevSettingsModule extends ReactContextBaseJavaModule {
return NAME;
}
@ReactMethod
@Override
public void reload() {
if (mDevSupportManager.getDevSupportEnabled()) {
UiThreadUtil.runOnUiThread(
@@ -53,37 +52,37 @@ public class DevSettingsModule extends ReactContextBaseJavaModule {
}
}
@ReactMethod
@Override
public void reloadWithReason(String reason) {
this.reload();
}
@ReactMethod
@Override
public void onFastRefresh() {
// noop
}
@ReactMethod
@Override
public void setHotLoadingEnabled(boolean isHotLoadingEnabled) {
mDevSupportManager.setHotModuleReplacementEnabled(isHotLoadingEnabled);
}
@ReactMethod
@Override
public void setIsDebuggingRemotely(boolean isDebugginRemotelyEnabled) {
mDevSupportManager.setRemoteJSDebugEnabled(isDebugginRemotelyEnabled);
}
@ReactMethod
@Override
public void setProfilingEnabled(boolean isProfilingEnabled) {
mDevSupportManager.setFpsDebugEnabled(isProfilingEnabled);
}
@ReactMethod
@Override
public void toggleElementInspector() {
mDevSupportManager.toggleElementInspector();
}
@ReactMethod
@Override
public void addMenuItem(final String title) {
mDevSupportManager.addCustomDevOption(
title,
@@ -104,4 +103,9 @@ public class DevSettingsModule extends ReactContextBaseJavaModule {
}
});
}
@Override
public void setIsShakeToShowDevMenuEnabled(boolean enabled) {
// iOS only
}
}
@@ -17,11 +17,10 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import com.facebook.common.logging.FLog;
import com.facebook.fbreact.specs.NativeDialogManagerAndroidSpec;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.SoftAssertions;
@@ -31,7 +30,7 @@ import com.facebook.react.module.annotations.ReactModule;
import java.util.Map;
@ReactModule(name = DialogModule.NAME)
public class DialogModule extends ReactContextBaseJavaModule implements LifecycleEventListener {
public class DialogModule extends NativeDialogManagerAndroidSpec implements LifecycleEventListener {
/* package */ static final String FRAGMENT_TAG =
"com.facebook.catalyst.react.dialog.DialogModule";
@@ -149,7 +148,7 @@ public class DialogModule extends ReactContextBaseJavaModule implements Lifecycl
}
@Override
public Map<String, Object> getConstants() {
public Map<String, Object> getTypedExportedConstants() {
return CONSTANTS;
}
@@ -179,7 +178,7 @@ public class DialogModule extends ReactContextBaseJavaModule implements Lifecycl
}
}
@ReactMethod
@Override
public void showAlert(
ReadableMap options, Callback errorCallback, final Callback actionCallback) {
final FragmentManagerHelper fragmentManagerHelper = getFragmentManagerHelper();
@@ -15,11 +15,10 @@ import android.net.Uri;
import android.nfc.NfcAdapter;
import android.provider.Settings;
import androidx.annotation.Nullable;
import com.facebook.fbreact.specs.NativeLinkingSpec;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
@@ -27,7 +26,7 @@ import com.facebook.react.module.annotations.ReactModule;
/** Intent module. Launch other activities or open URLs. */
@ReactModule(name = IntentModule.NAME)
public class IntentModule extends ReactContextBaseJavaModule {
public class IntentModule extends NativeLinkingSpec {
public static final String NAME = "IntentAndroid";
@@ -45,7 +44,7 @@ public class IntentModule extends ReactContextBaseJavaModule {
*
* @param promise a promise which is resolved with the initial URL
*/
@ReactMethod
@Override
public void getInitialURL(Promise promise) {
try {
Activity currentActivity = getCurrentActivity();
@@ -79,7 +78,7 @@ public class IntentModule extends ReactContextBaseJavaModule {
*
* @param url the URL to open
*/
@ReactMethod
@Override
public void openURL(String url, Promise promise) {
if (url == null || url.isEmpty()) {
promise.reject(new JSApplicationIllegalArgumentException("Invalid URL: " + url));
@@ -121,7 +120,7 @@ public class IntentModule extends ReactContextBaseJavaModule {
* @param url the URL to open
* @param promise a promise that is always resolved with a boolean argument
*/
@ReactMethod
@Override
public void canOpenURL(String url, Promise promise) {
if (url == null || url.isEmpty()) {
promise.reject(new JSApplicationIllegalArgumentException("Invalid URL: " + url));
@@ -148,7 +147,7 @@ public class IntentModule extends ReactContextBaseJavaModule {
*
* @param promise a promise which is resolved when the Settings is opened
*/
@ReactMethod
@Override
public void openSettings(Promise promise) {
try {
Intent intent = new Intent();
@@ -182,7 +181,7 @@ public class IntentModule extends ReactContextBaseJavaModule {
* @param action The general action to be performed
* @param extras An array of extras [{ String, String | Number | Boolean }]
*/
@ReactMethod
@Override
public void sendIntent(String action, @Nullable ReadableArray extras, Promise promise) {
if (action == null || action.isEmpty()) {
promise.reject(new JSApplicationIllegalArgumentException("Invalid Action: " + action + "."));
@@ -238,4 +237,14 @@ public class IntentModule extends ReactContextBaseJavaModule {
getReactApplicationContext().startActivity(intent);
}
@Override
public void addListener(String eventName) {
// iOS only
}
@Override
public void removeListeners(double count) {
// iOS only
}
}
@@ -13,11 +13,10 @@ import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Process;
import android.util.SparseArray;
import com.facebook.fbreact.specs.NativePermissionsAndroidSpec;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;
@@ -28,7 +27,7 @@ import java.util.ArrayList;
/** Module that exposes the Android M Permission system to JS. */
@ReactModule(name = PermissionsModule.NAME)
public class PermissionsModule extends ReactContextBaseJavaModule implements PermissionListener {
public class PermissionsModule extends NativePermissionsAndroidSpec implements PermissionListener {
private static final String ERROR_INVALID_ACTIVITY = "E_INVALID_ACTIVITY";
public static final String NAME = "PermissionsAndroid";
@@ -52,7 +51,7 @@ public class PermissionsModule extends ReactContextBaseJavaModule implements Per
* Check if the app has the permission given. successCallback is called with true if the
* permission had been granted, false otherwise. See {@link Activity#checkSelfPermission}.
*/
@ReactMethod
@Override
public void checkPermission(final String permission, final Promise promise) {
Context context = getReactApplicationContext().getBaseContext();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
@@ -72,7 +71,7 @@ public class PermissionsModule extends ReactContextBaseJavaModule implements Per
* again). For devices before Android M, this always returns false. See {@link
* Activity#shouldShowRequestPermissionRationale}.
*/
@ReactMethod
@Override
public void shouldShowRequestPermissionRationale(final String permission, final Promise promise) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
promise.resolve(false);
@@ -92,7 +91,7 @@ public class PermissionsModule extends ReactContextBaseJavaModule implements Per
* user has the permission given or not and resolves with GRANTED or DENIED. See {@link
* Activity#checkSelfPermission}.
*/
@ReactMethod
@Override
public void requestPermission(final String permission, final Promise promise) {
Context context = getReactApplicationContext().getBaseContext();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
@@ -137,7 +136,7 @@ public class PermissionsModule extends ReactContextBaseJavaModule implements Per
}
}
@ReactMethod
@Override
public void requestMultiplePermissions(final ReadableArray permissions, final Promise promise) {
final WritableMap grantedPermissions = new WritableNativeMap();
final ArrayList<String> permissionsToCheck = new ArrayList<String>();
@@ -9,18 +9,17 @@ package com.facebook.react.modules.share;
import android.app.Activity;
import android.content.Intent;
import com.facebook.fbreact.specs.NativeShareModuleSpec;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.module.annotations.ReactModule;
/** Intent module. Launch other activities or open URLs. */
@ReactModule(name = ShareModule.NAME)
public class ShareModule extends ReactContextBaseJavaModule {
public class ShareModule extends NativeShareModuleSpec {
public static final String NAME = "ShareModule";
/* package */ static final String ACTION_SHARED = "sharedAction";
@@ -44,7 +43,7 @@ public class ShareModule extends ReactContextBaseJavaModule {
* @param content the data to send
* @param dialogTitle the title of the chooser dialog
*/
@ReactMethod
@Override
public void share(ReadableMap content, String dialogTitle, Promise promise) {
if (content == null) {
promise.reject(ERROR_INVALID_CONTENT, "Content cannot be null");
@@ -9,15 +9,14 @@ package com.facebook.react.modules.sound;
import android.content.Context;
import android.media.AudioManager;
import com.facebook.fbreact.specs.NativeSoundManagerSpec;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;
/** {@link NativeModule} that allows Playing device sounds from JS. */
@ReactModule(name = SoundManagerModule.NAME)
public class SoundManagerModule extends ReactContextBaseJavaModule {
public class SoundManagerModule extends NativeSoundManagerSpec {
public static final String NAME = "SoundManager";
@@ -30,7 +29,7 @@ public class SoundManagerModule extends ReactContextBaseJavaModule {
return NAME;
}
@ReactMethod
@Override
public void playTouchSound() {
AudioManager audioManager =
(AudioManager) getReactApplicationContext().getSystemService(Context.AUDIO_SERVICE);
@@ -19,11 +19,10 @@ import android.view.WindowManager;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import com.facebook.common.logging.FLog;
import com.facebook.fbreact.specs.NativeStatusBarManagerAndroidSpec;
import com.facebook.react.bridge.GuardedRunnable;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.common.ReactConstants;
@@ -33,7 +32,7 @@ import java.util.Map;
/** {@link NativeModule} that allows changing the appearance of the status bar. */
@ReactModule(name = StatusBarModule.NAME)
public class StatusBarModule extends ReactContextBaseJavaModule {
public class StatusBarModule extends NativeStatusBarManagerAndroidSpec {
private static final String HEIGHT_KEY = "HEIGHT";
private static final String DEFAULT_BACKGROUND_COLOR_KEY = "DEFAULT_BACKGROUND_COLOR";
@@ -49,7 +48,7 @@ public class StatusBarModule extends ReactContextBaseJavaModule {
}
@Override
public @Nullable Map<String, Object> getConstants() {
public @Nullable Map<String, Object> getTypedExportedConstants() {
final Context context = getReactApplicationContext();
final Activity activity = getCurrentActivity();
@@ -70,8 +69,10 @@ public class StatusBarModule extends ReactContextBaseJavaModule {
HEIGHT_KEY, height, DEFAULT_BACKGROUND_COLOR_KEY, statusBarColorString);
}
@ReactMethod
public void setColor(final int color, final boolean animated) {
@Override
public void setColor(final double colorDouble, final boolean animated) {
final int color = (int) colorDouble;
final Activity activity = getCurrentActivity();
if (activity == null) {
FLog.w(
@@ -114,7 +115,7 @@ public class StatusBarModule extends ReactContextBaseJavaModule {
}
}
@ReactMethod
@Override
public void setTranslucent(final boolean translucent) {
final Activity activity = getCurrentActivity();
if (activity == null) {
@@ -156,7 +157,7 @@ public class StatusBarModule extends ReactContextBaseJavaModule {
}
}
@ReactMethod
@Override
public void setHidden(final boolean hidden) {
final Activity activity = getCurrentActivity();
if (activity == null) {
@@ -180,7 +181,7 @@ public class StatusBarModule extends ReactContextBaseJavaModule {
});
}
@ReactMethod
@Override
public void setStyle(@Nullable final String style) {
final Activity activity = getCurrentActivity();
if (activity == null) {
@@ -15,12 +15,11 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteStatement;
import android.os.AsyncTask;
import com.facebook.common.logging.FLog;
import com.facebook.fbreact.specs.NativeAsyncStorageSpec;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.GuardedAsyncTask;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
@@ -33,7 +32,7 @@ import java.util.HashSet;
import java.util.concurrent.Executor;
@ReactModule(name = AsyncStorageModule.NAME)
public final class AsyncStorageModule extends ReactContextBaseJavaModule
public final class AsyncStorageModule extends NativeAsyncStorageSpec
implements ModuleDataCleaner.Cleanable {
public static final String NAME = "AsyncSQLiteDBStorage";
@@ -120,7 +119,7 @@ public final class AsyncStorageModule extends ReactContextBaseJavaModule
* Given an array of keys, this returns a map of (key, value) pairs for the keys found, and (key,
* null) for the keys that haven't been found.
*/
@ReactMethod
@Override
public void multiGet(final ReadableArray keys, final Callback callback) {
if (keys == null) {
callback.invoke(AsyncStorageErrorUtil.getInvalidKeyError(null), null);
@@ -196,7 +195,7 @@ public final class AsyncStorageModule extends ReactContextBaseJavaModule
* return AsyncLocalStorageFailure, but all other pairs will have been inserted. The insertion
* will replace conflicting (key, value) pairs.
*/
@ReactMethod
@Override
public void multiSet(final ReadableArray keyValueArray, final Callback callback) {
if (keyValueArray.size() == 0) {
callback.invoke(AsyncStorageErrorUtil.getInvalidKeyError(null));
@@ -259,7 +258,7 @@ public final class AsyncStorageModule extends ReactContextBaseJavaModule
}
/** Removes all rows of the keys given. */
@ReactMethod
@Override
public void multiRemove(final ReadableArray keys, final Callback callback) {
if (keys.size() == 0) {
callback.invoke(AsyncStorageErrorUtil.getInvalidKeyError(null));
@@ -313,7 +312,7 @@ public final class AsyncStorageModule extends ReactContextBaseJavaModule
* Given an array of (key, value) pairs, this will merge the given values with the stored values
* of the given keys, if they exist.
*/
@ReactMethod
@Override
public void multiMerge(final ReadableArray keyValueArray, final Callback callback) {
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
@Override
@@ -373,7 +372,7 @@ public final class AsyncStorageModule extends ReactContextBaseJavaModule
}
/** Clears the database. */
@ReactMethod
@Override
public void clear(final Callback callback) {
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
@Override
@@ -394,7 +393,7 @@ public final class AsyncStorageModule extends ReactContextBaseJavaModule
}
/** Returns an array with all keys from the database. */
@ReactMethod
@Override
public void getAllKeys(final Callback callback) {
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
@Override
@@ -16,10 +16,9 @@ import android.content.res.Resources;
import android.os.Build;
import android.provider.Settings.Secure;
import androidx.annotation.Nullable;
import com.facebook.fbreact.specs.NativePlatformConstantsAndroidSpec;
import com.facebook.react.R;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
@@ -29,7 +28,7 @@ import java.util.Map;
/** Module that exposes Android Constants to JS. */
@ReactModule(name = AndroidInfoModule.NAME)
@SuppressLint("HardwareIds")
public class AndroidInfoModule extends ReactContextBaseJavaModule implements TurboModule {
public class AndroidInfoModule extends NativePlatformConstantsAndroidSpec implements TurboModule {
public static final String NAME = "PlatformConstants";
private static final String IS_TESTING = "IS_TESTING";
@@ -66,7 +65,7 @@ public class AndroidInfoModule extends ReactContextBaseJavaModule implements Tur
}
@Override
public @Nullable Map<String, Object> getConstants() {
public @Nullable Map<String, Object> getTypedExportedConstants() {
HashMap<String, Object> constants = new HashMap<>();
constants.put("Version", Build.VERSION.SDK_INT);
constants.put("Release", Build.VERSION.RELEASE);
@@ -83,7 +82,7 @@ public class AndroidInfoModule extends ReactContextBaseJavaModule implements Tur
return constants;
}
@ReactMethod(isBlockingSynchronousMethod = true)
@Override
public String getAndroidID() {
return Secure.getString(getReactApplicationContext().getContentResolver(), Secure.ANDROID_ID);
}
@@ -17,11 +17,10 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import com.facebook.fbreact.specs.NativeTimePickerAndroidSpec;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;
@@ -33,7 +32,7 @@ import com.facebook.react.module.annotations.ReactModule;
* the user selects a time.
*/
@ReactModule(name = TimePickerDialogModule.FRAGMENT_TAG)
public class TimePickerDialogModule extends ReactContextBaseJavaModule {
public class TimePickerDialogModule extends NativeTimePickerAndroidSpec {
@VisibleForTesting public static final String FRAGMENT_TAG = "TimePickerAndroid";
@@ -87,14 +86,14 @@ public class TimePickerDialogModule extends ReactContextBaseJavaModule {
}
}
@ReactMethod
@Override
public void open(@Nullable final ReadableMap options, Promise promise) {
Activity raw_activity = getCurrentActivity();
if (raw_activity == null || !(raw_activity instanceof FragmentActivity)) {
promise.reject(
ERROR_NO_ACTIVITY,
"Tried to open a DatePicker dialog while not attached to a FragmentActivity");
ERROR_NO_ACTIVITY,
"Tried to open a DatePicker dialog while not attached to a FragmentActivity");
return;
}
@@ -9,10 +9,9 @@ package com.facebook.react.modules.toast;
import android.view.Gravity;
import android.widget.Toast;
import com.facebook.fbreact.specs.NativeToastAndroidSpec;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.module.annotations.ReactModule;
@@ -20,7 +19,7 @@ import java.util.Map;
/** {@link NativeModule} that allows JS to show an Android Toast. */
@ReactModule(name = ToastModule.NAME)
public class ToastModule extends ReactContextBaseJavaModule {
public class ToastModule extends NativeToastAndroidSpec {
private static final String DURATION_SHORT_KEY = "SHORT";
private static final String DURATION_LONG_KEY = "LONG";
@@ -40,7 +39,7 @@ public class ToastModule extends ReactContextBaseJavaModule {
}
@Override
public Map<String, Object> getConstants() {
public Map<String, Object> getTypedExportedConstants() {
final Map<String, Object> constants = MapBuilder.newHashMap();
constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
@@ -50,8 +49,10 @@ public class ToastModule extends ReactContextBaseJavaModule {
return constants;
}
@ReactMethod
public void show(final String message, final int duration) {
@Override
public void show(final String message, final double durationDouble) {
final int duration = (int) durationDouble;
UiThreadUtil.runOnUiThread(
new Runnable() {
@Override
@@ -61,8 +62,12 @@ public class ToastModule extends ReactContextBaseJavaModule {
});
}
@ReactMethod
public void showWithGravity(final String message, final int duration, final int gravity) {
@Override
public void showWithGravity(
final String message, final double durationDouble, final double gravityDouble) {
final int duration = (int) durationDouble;
final int gravity = (int) gravityDouble;
UiThreadUtil.runOnUiThread(
new Runnable() {
@Override
@@ -74,13 +79,18 @@ public class ToastModule extends ReactContextBaseJavaModule {
});
}
@ReactMethod
@Override
public void showWithGravityAndOffset(
final String message,
final int duration,
final int gravity,
final int xOffset,
final int yOffset) {
final double durationDouble,
final double gravityDouble,
final double xOffsetDouble,
final double yOffsetDouble) {
final int duration = (int) durationDouble;
final int gravity = (int) gravityDouble;
final int xOffset = (int) xOffsetDouble;
final int yOffset = (int) yOffsetDouble;
UiThreadUtil.runOnUiThread(
new Runnable() {
@Override
@@ -10,15 +10,14 @@ package com.facebook.react.modules.vibration;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Vibrator;
import com.facebook.fbreact.specs.NativeVibrationSpec;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.module.annotations.ReactModule;
@SuppressLint("MissingPermission")
@ReactModule(name = VibrationModule.NAME)
public class VibrationModule extends ReactContextBaseJavaModule {
public class VibrationModule extends NativeVibrationSpec {
public static final String NAME = "Vibration";
@@ -31,16 +30,20 @@ public class VibrationModule extends ReactContextBaseJavaModule {
return NAME;
}
@ReactMethod
public void vibrate(int duration) {
@Override
public void vibrate(Double durationDouble) {
int duration = (int) durationDouble.doubleValue();
Vibrator v = (Vibrator) getReactApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
if (v != null) {
v.vibrate(duration);
}
}
@ReactMethod
public void vibrateByPattern(ReadableArray pattern, int repeat) {
@Override
public void vibrateByPattern(ReadableArray pattern, double repeatDouble) {
int repeat = (int) repeatDouble;
Vibrator v = (Vibrator) getReactApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
if (v != null) {
long[] patternLong = new long[pattern.size()];
@@ -51,7 +54,7 @@ public class VibrationModule extends ReactContextBaseJavaModule {
}
}
@ReactMethod
@Override
public void cancel() {
Vibrator v = (Vibrator) getReactApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
if (v != null) {