diff --git a/package.json b/package.json index 12ad5324..7ec7b009 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "workspaces": [ "packages/*" ], + "version": "0.6.6", "packageManager": "yarn@1.22.22", "scripts": { "lint": "eslint .", diff --git a/packages/react-native-external-display/android/.project b/packages/react-native-external-display/android/.project new file mode 100644 index 00000000..c55ce2f6 --- /dev/null +++ b/packages/react-native-external-display/android/.project @@ -0,0 +1,28 @@ + + + react-native-external-display + Project react-native-external-display created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + + + 1733156198568 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + + diff --git a/packages/react-native-external-display/android/src/main/java/com/externaldisplay/ExternalDisplayHelper.java b/packages/react-native-external-display/android/src/main/java/com/externaldisplay/ExternalDisplayHelper.java index 6ec288af..6943d4e1 100644 --- a/packages/react-native-external-display/android/src/main/java/com/externaldisplay/ExternalDisplayHelper.java +++ b/packages/react-native-external-display/android/src/main/java/com/externaldisplay/ExternalDisplayHelper.java @@ -18,81 +18,126 @@ import java.util.Map; import java.util.HashMap; +import android.util.Log; + import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.ReactApplicationContext; @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) class ExternalDisplayScreen extends Presentation { - ExternalDisplayScreen(Context ctx, Display display) { - super(ctx, display); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } + ExternalDisplayScreen(Context ctx, Display display) { + super(ctx, display); + Log.d("RNExternalDisplayEvent", "ExternalDisplayScreen init"); + + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + Log.d("RNExternalDisplayEvent", "ExternalDisplayScreen onCreate"); + + super.onCreate(savedInstanceState); + } } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) class ExternalDisplayHelper implements DisplayManager.DisplayListener { - public static Map getScreenInfo(Display[] displays) { - HashMap info = new HashMap(); - for (Display display : displays) { - int displayId = display.getDisplayId(); - if ( - display.getDisplayId() == Display.DEFAULT_DISPLAY || - (display.getFlags() & Display.FLAG_PRESENTATION) == 0 - ) { - continue; - } - HashMap data = new HashMap(); - DisplayMetrics displayMetrics = new DisplayMetrics(); - display.getMetrics(displayMetrics); - data.put("id", displayId); - data.put("width", displayMetrics.widthPixels); - data.put("height", displayMetrics.heightPixels); - info.put(String.valueOf(display.getDisplayId()), data); + private static final String TAG = "RNExternalDisplayEvent"; + private static ExternalDisplayHelper instance = null; + private DisplayManager dm = null; + private Listener listener = null; + private Display displays = null; + + // Private constructor to prevent direct instantiation + private ExternalDisplayHelper(Context context, Listener listener) { + this.listener = listener; + dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); + if (dm != null) { + dm.registerDisplayListener(this, null); + } else { + } + } + + // Method to initialize the singleton instance + public static synchronized void initialize(Context context, Listener listener) { + if (instance == null) { + instance = new ExternalDisplayHelper(context.getApplicationContext(), listener); + } + } + + // Method to get the singleton instance + public static synchronized ExternalDisplayHelper getInstance() { + if (instance == null) { + throw new IllegalStateException("ExternalDisplayHelper is not initialized. Call initialize() first."); + } + return instance; + } + + // Method to clean up the singleton instance + public static synchronized void destroy() { + if (instance != null && instance.dm != null) { + instance.dm.unregisterDisplayListener(instance); + instance = null; + } + } + public static Map getScreenInfo(Display[] displays) { + HashMap info = new HashMap<>(); + for (Display display : displays) { + int displayId = display.getDisplayId(); + if ( + display.getDisplayId() == Display.DEFAULT_DISPLAY || + (display.getFlags() & Display.FLAG_PRESENTATION) == 0 + ) { + continue; + } + HashMap data = new HashMap<>(); + DisplayMetrics displayMetrics = new DisplayMetrics(); + display.getMetrics(displayMetrics); + data.put("id", displayId); + data.put("width", displayMetrics.widthPixels); + data.put("height", displayMetrics.heightPixels); + info.put(String.valueOf(display.getDisplayId()), data); + } + return info; + } + + @Override + public void onDisplayAdded(int displayId) { + if (listener != null) { + listener.onDisplayAdded(getDisplays(), displayId); + } + } + + @Override + public void onDisplayChanged(int displayId) { + if (listener != null) { + listener.onDisplayChanged(getDisplays(), displayId); + } + } + + @Override + public void onDisplayRemoved(int displayId) { + if (listener != null) { + listener.onDisplayRemoved(getDisplays(), displayId); + } + } + + public Display getDisplay(int displayId) { + if (dm != null) { + return dm.getDisplay(displayId); + } + return null; + } + + public Display[] getDisplays() { + if (dm != null) { + return dm.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION); + } + return new Display[0]; + } + + public interface Listener { + void onDisplayAdded(Display[] displays, int displayId); + void onDisplayChanged(Display[] displays, int displayId); + void onDisplayRemoved(Display[] displays, int displayId); } - return info; - } - - public interface Listener { - void onDisplayAdded(Display[] displays, int displayId); - void onDisplayChanged(Display[] displays, int displayId); - void onDisplayRemoved(Display[] displays, int displayId); - } - - private Listener listener = null; - private DisplayManager dm = null; - private Display displays = null; - - public ExternalDisplayHelper(Context context, Listener listener) { - this.listener = listener; - - dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); - dm.registerDisplayListener(this, null); - } - - public Display getDisplay(int displayId) { - return dm.getDisplay(displayId); - } - - public Display[] getDisplays() { - return dm.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION); - } - - @Override - public void onDisplayAdded(int displayId) { - listener.onDisplayAdded(getDisplays(), displayId); - } - - @Override - public void onDisplayChanged(int displayId) { - listener.onDisplayChanged(getDisplays(), displayId); - } - - @Override - public void onDisplayRemoved(int displayId) { - listener.onDisplayRemoved(getDisplays(), displayId); - } } diff --git a/packages/react-native-external-display/android/src/main/java/com/externaldisplay/RNExternalDisplayPackage.java b/packages/react-native-external-display/android/src/main/java/com/externaldisplay/RNExternalDisplayPackage.java index 93a92e7f..32589536 100644 --- a/packages/react-native-external-display/android/src/main/java/com/externaldisplay/RNExternalDisplayPackage.java +++ b/packages/react-native-external-display/android/src/main/java/com/externaldisplay/RNExternalDisplayPackage.java @@ -1,6 +1,7 @@ package com.externaldisplay; import androidx.annotation.Nullable; + import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.module.model.ReactModuleInfo; @@ -8,6 +9,8 @@ import com.facebook.react.TurboReactPackage; import com.facebook.react.uimanager.ViewManager; +import android.util.Log; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -16,55 +19,60 @@ import android.util.Log; +import com.externaldisplay.RNExternalDisplayManager; +import com.externaldisplay.RNExternalDisplayModule; + public class RNExternalDisplayPackage extends TurboReactPackage { + private static final String TAG = "RNExternalDisplayEvent"; - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - List viewManagers = new ArrayList<>(); - viewManagers.add(new RNExternalDisplayManager(reactContext)); - return viewManagers; - } - @Nullable - @Override - public NativeModule getModule(String name, ReactApplicationContext reactContext) { - if (name.equals(RNExternalDisplayModule.REACT_CLASS)) { - return new com.externaldisplay.RNExternalDisplayModule(reactContext); - } else { - return null; + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + List viewManagers = new ArrayList<>(); + viewManagers.add(new RNExternalDisplayManager(reactContext)); + return viewManagers; } - } - @Override - public ReactModuleInfoProvider getReactModuleInfoProvider() { - return () -> { - final Map moduleInfos = new HashMap<>(); - boolean isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; - moduleInfos.put( - RNExternalDisplayModule.REACT_CLASS, - new ReactModuleInfo( - RNExternalDisplayModule.REACT_CLASS, - RNExternalDisplayModule.REACT_CLASS, - false, // canOverrideExistingModule - false, // needsEagerInit - true, // hasConstants - false, // isCxxModule - isTurboModule // isTurboModule - ) - ); - moduleInfos.put( - RNExternalDisplayManager.REACT_CLASS, - new ReactModuleInfo( - RNExternalDisplayManager.REACT_CLASS, - RNExternalDisplayManager.REACT_CLASS, - false, // canOverrideExistingModule - false, // needsEagerInit - true, // hasConstants - false, // isCxxModule - isTurboModule // isTurboModule - ) - ); - return moduleInfos; - }; - } + @Nullable + @Override + public NativeModule getModule(String name, ReactApplicationContext reactContext) { + if (name.equals(RNExternalDisplayModule.REACT_CLASS)) { + return new RNExternalDisplayModule(reactContext); + } else { + return null; + } + } + + @Override + public ReactModuleInfoProvider getReactModuleInfoProvider() { + return () -> { + final Map moduleInfos = new HashMap<>(); + boolean isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; + moduleInfos.put( + RNExternalDisplayModule.REACT_CLASS, + new ReactModuleInfo( + RNExternalDisplayModule.REACT_CLASS, + RNExternalDisplayModule.REACT_CLASS, + false, // canOverrideExistingModule + false, // needsEagerInit + true, // hasConstants + false, // isCxxModule + isTurboModule // isTurboModule + ) + ); + moduleInfos.put( + RNExternalDisplayManager.REACT_CLASS, + new ReactModuleInfo( + RNExternalDisplayManager.REACT_CLASS, + RNExternalDisplayManager.REACT_CLASS, + false, // canOverrideExistingModule + false, // needsEagerInit + true, // hasConstants + false, // isCxxModule + isTurboModule // isTurboModule + ) + ); + return moduleInfos; + }; + } } diff --git a/packages/react-native-external-display/android/src/main/java/com/externaldisplay/RNExternalDisplayView.java b/packages/react-native-external-display/android/src/main/java/com/externaldisplay/RNExternalDisplayView.java index f2ae98fc..107e85e7 100644 --- a/packages/react-native-external-display/android/src/main/java/com/externaldisplay/RNExternalDisplayView.java +++ b/packages/react-native-external-display/android/src/main/java/com/externaldisplay/RNExternalDisplayView.java @@ -3,198 +3,232 @@ import android.content.Context; import android.view.View; import android.view.ViewGroup; + import com.facebook.react.ReactRootView; import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.ReactContext; + import android.widget.LinearLayout; + import com.facebook.common.logging.FLog; import com.facebook.react.common.ReactConstants; +import android.util.Log; + import android.view.Display; import android.util.DisplayMetrics; import java.util.ArrayList; public class RNExternalDisplayView extends ReactRootView implements LifecycleEventListener { - Context context; - private boolean fallbackInMainScreen = false; - private ExternalDisplayHelper helper; - private ExternalDisplayScreen displayScreen; - private int screen = -1; - private ArrayList subviews = new ArrayList(); - private ReactRootView wrap; - private boolean pausedWithDisplayScreen = false; - - public RNExternalDisplayView(Context context, ExternalDisplayHelper helper) { - super(context); - ((ReactContext) context).addLifecycleEventListener(this); - this.context = context; - this.helper = helper; - } - - @Override - public void addView(View child, int index) { - subviews.add(index, child); - updateScreen(); - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - } - - @Override - public int getChildCount() { - return subviews.size(); - } - - @Override - public View getChildAt(int index) { - return subviews.get(index); - } - - @Override - public void removeView(View view) { - super.removeView(view); - } - - @Override - public void removeViewAt(int index) { - View child = getChildAt(index); - super.removeView(child); - subviews.remove(index); - if (wrap != null) { - for (int i = 0; i < wrap.getChildCount(); i++) { - if (i == index) { - wrap.removeViewAt(i); + private static final String TAG = "RNExternalDisplayEvent"; + private boolean fallbackInMainScreen = false; + private ExternalDisplayHelper helper; + private ExternalDisplayScreen displayScreen; + private int screen = -1; + private ArrayList subviews = new ArrayList(); + private ReactRootView wrap; + private boolean pausedWithDisplayScreen = false; + Context context; + + + public RNExternalDisplayView(Context context, ExternalDisplayHelper helper) { + super(context); + ((ReactContext) context).addLifecycleEventListener(this); + if (helper != null) { + this.helper = helper; + } else { + this.helper = null; } - } - } - } - - public void onDropInstance() { - ((ReactContext) getContext()).removeLifecycleEventListener(this); - if (wrap != null && wrap.getChildCount() > 0) { - for (int i = 0; i < wrap.getChildCount(); i++) { - wrap.removeViewAt(i); - } - } - destroyScreen(); - } - - @Override - public void addChildrenForAccessibility(ArrayList outChildren) { - // This solves an accessibility bug originally addressed in RN - // Reference: https://github.com/mybigday/react-native-external-display/issues/211 - } - - @Override - public void onHostResume() { - if (displayScreen == null && !pausedWithDisplayScreen) { - return; - } - pausedWithDisplayScreen = false; - updateScreen(); - } - - @Override - public void onHostPause() { - if (displayScreen == null) { - return; - } - pausedWithDisplayScreen = true; - if (wrap != null) { - for (int i = 0; i < wrap.getChildCount(); i++) { - wrap.removeViewAt(i); - } - } - destroyScreen(); - } - - @Override - public void onHostDestroy() { - onDropInstance(); - } - - public void updateScreen() { - if (getChildCount() == 0) return; - if (screen > 0) { - Display display = helper.getDisplay(screen); - if (display != null) { - if (displayScreen == null) { - displayScreen = new ExternalDisplayScreen(context, display); - wrap = new ReactRootView(context); - } else if (wrap.getChildCount() > 0) { - for (int i = 0; i < wrap.getChildCount(); i++) { - wrap.removeViewAt(i); - } + } + /** + * Retrieves the singleton ExternalDisplayHelper instance. + * If not available, returns null. + * + * @param context The context. + * @return ExternalDisplayHelper instance or null. + */ + private ExternalDisplayHelper getDefaultHelper(Context context) { + try { + return ExternalDisplayHelper.getInstance(); + } catch (IllegalStateException e) { + return null; } - for (int i = 0; i < subviews.size(); i++) { - View subview = subviews.get(i); - if (subview.getParent() != null) { - // Make sure removed from parent - ((ViewGroup) subview.getParent()).removeView(subview); - } - wrap.addView(subview, i); + } + + @Override + public void addView(View child, int index) { + subviews.add(index, child); + updateScreen(); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + } + + @Override + public int getChildCount() { + return subviews.size(); + } + + @Override + public View getChildAt(int index) { + return subviews.get(index); + } + + @Override + public void removeView(View view) { + super.removeView(view); + } + + @Override + public void removeViewAt(int index) { + View child = getChildAt(index); + super.removeView(child); + subviews.remove(index); + if (wrap != null) { + for (int i = 0; i < wrap.getChildCount(); i++) { + if (i == index) { + wrap.removeViewAt(i); + } + } } - displayScreen.setContentView(wrap); - displayScreen.show(); - return; - } - } - if (fallbackInMainScreen == true) { - if (wrap != null) { - for (int i = 0; i < wrap.getChildCount(); i++) { - wrap.removeViewAt(i); + } + + public void onDropInstance() { + ((ReactContext) getContext()).removeLifecycleEventListener(this); + if (wrap != null && wrap.getChildCount() > 0) { + for (int i = 0; i < wrap.getChildCount(); i++) { + wrap.removeViewAt(i); + } } - } - for (int i = 0; i < subviews.size(); i++) { - View subview = subviews.get(i); - if (subview.getParent() != null) { - // Make sure removed from parent - ((ViewGroup) subview.getParent()).removeView(subview); + destroyScreen(); + } + + @Override + public void addChildrenForAccessibility(ArrayList outChildren) { + // This solves an accessibility bug originally addressed in RN + // Reference: https://github.com/mybigday/react-native-external-display/issues/211 + } + + @Override + public void onHostResume() { + if (displayScreen == null && !pausedWithDisplayScreen) { + return; + } + pausedWithDisplayScreen = false; + updateScreen(); + } + + @Override + public void onHostPause() { + if (displayScreen == null) { + return; + } + pausedWithDisplayScreen = true; + if (wrap != null) { + for (int i = 0; i < wrap.getChildCount(); i++) { + wrap.removeViewAt(i); + } } - super.addView(subview, i); - } - } - } - - private void destroyScreen() { - if (displayScreen != null) { - displayScreen.hide(); - displayScreen.dismiss(); - displayScreen = null; - wrap = null; - } - } - - public void setScreen(String screen) { - if (getChildCount() > 0 && wrap != null && wrap.getChildCount() > 0) { - for (int i = 0; i < wrap.getChildCount(); i++) { - wrap.removeViewAt(i); - } - } else { - for (View subview : subviews) { - removeView(subview); - } - } - try { - int nextScreen = Integer.parseInt(screen); - if (nextScreen != this.screen) { destroyScreen(); - } - this.screen = nextScreen; - } catch (NumberFormatException e) { - destroyScreen(); - this.screen = -1; - } - updateScreen(); - } - - public int getScreen() { - return this.screen; - } - - public void setFallbackInMainScreen(boolean value) { - this.fallbackInMainScreen = value; - } + } + + @Override + public void onHostDestroy() { + onDropInstance(); + } + + public void updateScreen() { + if (getChildCount() == 0) return; + + if (screen > 0 && helper != null) { + Display display = helper.getDisplay(screen); + if (display != null) { + if (displayScreen == null) { + displayScreen = new ExternalDisplayScreen(getContext(), display); + wrap = new ReactRootView(getContext()); + } else if (wrap.getChildCount() > 0) { + for (int i = 0; i < wrap.getChildCount(); i++) { + wrap.removeViewAt(i); + } + } + for (int i = 0; i < subviews.size(); i++) { + View subview = subviews.get(i); + if (subview.getParent() != null) { + // Make sure removed from parent + ((ViewGroup) subview.getParent()).removeView(subview); + } + wrap.addView(subview, i); + } + try { + displayScreen.setContentView(wrap); + displayScreen.show(); + } catch (Exception e) { + } + return; + }else { + Log.e(TAG, "Display with ID " + screen + " not found."); + } + } + + if (fallbackInMainScreen) { + if (wrap != null) { + for (int i = 0; i < wrap.getChildCount(); i++) { + wrap.removeViewAt(i); + } + } + for (int i = 0; i < subviews.size(); i++) { + View subview = subviews.get(i); + if (subview.getParent() != null) { + // Make sure removed from parent + ((ViewGroup) subview.getParent()).removeView(subview); + } + super.addView(subview, i); + } + } + } + + private void destroyScreen() { + if (displayScreen != null) { + try { + displayScreen.hide(); + displayScreen.dismiss(); + } catch (Exception e) { + } + displayScreen = null; + wrap = null; + } + } + + public void setScreen(String screen) { + if (getChildCount() > 0 && wrap != null && wrap.getChildCount() > 0) { + for (int i = 0; i < wrap.getChildCount(); i++) { + wrap.removeViewAt(i); + } + } else { + for (View subview : subviews) { + removeView(subview); + } + } + try { + int nextScreen = Integer.parseInt(screen); + if (nextScreen != this.screen) { + destroyScreen(); + } + this.screen = nextScreen; + } catch (NumberFormatException e) { + destroyScreen(); + this.screen = -1; + } + updateScreen(); + } + + public int getScreen() { + return this.screen; + } + + public void setFallbackInMainScreen(boolean value) { + this.fallbackInMainScreen = value; + } } diff --git a/packages/react-native-external-display/android/src/oldarch/java/com/externaldisplay/RNExternalDisplayManager.java b/packages/react-native-external-display/android/src/oldarch/java/com/externaldisplay/RNExternalDisplayManager.java index 787a5447..98149dd0 100644 --- a/packages/react-native-external-display/android/src/oldarch/java/com/externaldisplay/RNExternalDisplayManager.java +++ b/packages/react-native-external-display/android/src/oldarch/java/com/externaldisplay/RNExternalDisplayManager.java @@ -15,97 +15,76 @@ import android.util.DisplayMetrics; import android.view.Display; import android.graphics.Rect; - +import android.util.Log; +import com.externaldisplay.RNExternalDisplayModule; import javax.annotation.Nullable; + import java.util.Map; import java.util.HashMap; -public class RNExternalDisplayManager extends ViewGroupManager implements ExternalDisplayHelper.Listener { - public static final String REACT_CLASS = "RNExternalDisplay"; - private ExternalDisplayHelper helper; - private ReactApplicationContext reactContext; - private Map views = new HashMap(); - - public RNExternalDisplayManager(ReactApplicationContext reactContext) { - super(); - this.reactContext = reactContext; - } +public class RNExternalDisplayManager extends ViewGroupManager { + public static final String REACT_CLASS = "RNExternalDisplay"; + private static final String TAG = "RNExternalDisplayEvent"; + private ReactApplicationContext reactContext; + //private Map views = new HashMap(); - @Override - public String getName() { - return REACT_CLASS; - } + public RNExternalDisplayManager(ReactApplicationContext reactContext) { + super(); + this.reactContext = reactContext; + } - @Override - public RNExternalDisplayView createViewInstance(ThemedReactContext context) { - if (this.helper == null) { - this.helper = new ExternalDisplayHelper(reactContext, this); + @Override + public String getName() { + return REACT_CLASS; } - RNExternalDisplayView view = new RNExternalDisplayView(context, this.helper); - views.put(view, view); - return view; - } - @Override - public void onDropViewInstance(RNExternalDisplayView view) { - views.remove(view); - super.onDropViewInstance(view); - view.onDropInstance(); - } + @Override + public RNExternalDisplayView createViewInstance(ThemedReactContext context) { + // Retrieve the module to access the helper + RNExternalDisplayModule module = context.getNativeModule(RNExternalDisplayModule.class); + ExternalDisplayHelper helper = null; + if (module != null) { + helper = module.getExternalDisplayHelper(); + } else { + } - private void checkScreen() { - int screenId = -1; - for (RNExternalDisplayView view : views.values()) { - int viewScreenId = view.getScreen(); - if (viewScreenId > 0 && screenId == viewScreenId) { - // TODO: Log to console - FLog.e(ReactConstants.TAG, "Detected two or more RNExternalDisplayView to register the same screen id: " + screenId); - } - if (viewScreenId > 0) { - screenId = viewScreenId; - } + RNExternalDisplayView view = new RNExternalDisplayView(context, helper); + return view; } - } - @ReactProp(name = "screen") - public void setScreen(RNExternalDisplayView view, @Nullable String screen) { - view.setScreen(screen); - checkScreen(); - } + @Override + public void onDropViewInstance(RNExternalDisplayView view) { + //views.remove(view); + super.onDropViewInstance(view); + view.onDropInstance(); + } +/* + private void checkScreen() { + Log.d("RNExternalDisplayEvent", "RNExternalDisplayManager checkScreen"); - @ReactProp(name = "fallbackInMainScreen", defaultBoolean = false) - public void setFallbackInMainScreen(RNExternalDisplayView view, boolean fallbackInMainScreen) { - view.setFallbackInMainScreen(fallbackInMainScreen); - } + int screenId = -1; + for (RNExternalDisplayView view : views.values()) { + int viewScreenId = view.getScreen(); + if (viewScreenId > 0 && screenId == viewScreenId) { + // TODO: Log to console + FLog.e(ReactConstants.TAG, "Detected two or more RNExternalDisplayView to register the same screen id: " + screenId); + } + if (viewScreenId > 0) { + screenId = viewScreenId; + } + } + } + + */ - private void sendEvent(String eventName, @Nullable WritableMap params) { - reactContext - .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) - .emit(eventName, params); - } + @ReactProp(name = "screen") + public void setScreen(RNExternalDisplayView view, String screen) { + view.setScreen(screen); + //checkScreen(); + } - public void onDisplayAdded(Display[] displays, int displayId) { - sendEvent( - "@RNExternalDisplay_screenDidConnect", - Arguments.makeNativeMap( - ExternalDisplayHelper.getScreenInfo(displays) - ) - ); - } - public void onDisplayChanged(Display[] displays, int displayId) { - sendEvent( - "@RNExternalDisplay_screenDidChange", - Arguments.makeNativeMap( - ExternalDisplayHelper.getScreenInfo(displays) - ) - ); - } - public void onDisplayRemoved(Display[] displays, int displayId) { - sendEvent( - "@RNExternalDisplay_screenDidDisconnect", - Arguments.makeNativeMap( - ExternalDisplayHelper.getScreenInfo(displays) - ) - ); - } + @ReactProp(name = "fallbackInMainScreen", defaultBoolean = false) + public void setFallbackInMainScreen(RNExternalDisplayView view, boolean fallbackInMainScreen) { + view.setFallbackInMainScreen(fallbackInMainScreen); + } } diff --git a/packages/react-native-external-display/android/src/oldarch/java/com/externaldisplay/RNExternalDisplayModule.java b/packages/react-native-external-display/android/src/oldarch/java/com/externaldisplay/RNExternalDisplayModule.java index 8272f4f8..2029f7d0 100644 --- a/packages/react-native-external-display/android/src/oldarch/java/com/externaldisplay/RNExternalDisplayModule.java +++ b/packages/react-native-external-display/android/src/oldarch/java/com/externaldisplay/RNExternalDisplayModule.java @@ -1,36 +1,96 @@ package com.externaldisplay; import android.content.Context; + import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import android.view.Display; import android.hardware.display.DisplayManager; +import android.util.Log; import java.util.Map; import java.util.HashMap; -public class RNExternalDisplayModule extends ReactContextBaseJavaModule { - public static final String REACT_CLASS = "RNExternalDisplayEvent"; - private ReactApplicationContext reactContext = null; - private DisplayManager dm = null; - - public RNExternalDisplayModule(ReactApplicationContext context) { - super(context); - reactContext = context; - dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); - } - - @Override - public String getName() { - return REACT_CLASS; - } - - @Override - public Map getConstants() { - HashMap map = new HashMap(); - map.put("SCREEN_INFO", ExternalDisplayHelper.getScreenInfo(dm.getDisplays())); - return map; - } -} \ No newline at end of file +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.module.annotations.ReactModule; +import com.facebook.react.modules.core.DeviceEventManagerModule; +import com.facebook.react.bridge.Arguments; + +@ReactModule(name = RNExternalDisplayModule.REACT_CLASS) // Added Annotation +public class RNExternalDisplayModule extends ReactContextBaseJavaModule implements ExternalDisplayHelper.Listener { + public static final String REACT_CLASS = "RNExternalDisplayEvent"; + private static final String TAG = "RNExternalDisplayEvent"; + + private ReactApplicationContext reactContext = null; + + public RNExternalDisplayModule(ReactApplicationContext context) { + super(context); + this.reactContext = context; + // Initialize ExternalDisplayHelper singleton + ExternalDisplayHelper.initialize(context, this); + } + + @Override + public String getName() { + return REACT_CLASS; + } + + @Override + public Map getConstants() { + HashMap map = new HashMap<>(); + try { + map.put("SCREEN_INFO", ExternalDisplayHelper.getScreenInfo(ExternalDisplayHelper.getInstance().getDisplays())); + } catch (IllegalStateException e) { + map.put("SCREEN_INFO", new HashMap()); + } + return map; + } + + private void sendEvent(String eventName, WritableMap params) { + reactContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit(eventName, params); + } + + @Override + public void onDisplayAdded(Display[] displays, int displayId) { + sendEvent( + "@RNExternalDisplay_screenDidConnect", + Arguments.makeNativeMap(ExternalDisplayHelper.getScreenInfo(displays)) + ); + } + + @Override + public void onDisplayChanged(Display[] displays, int displayId) { + sendEvent( + "@RNExternalDisplay_screenDidChange", + Arguments.makeNativeMap(ExternalDisplayHelper.getScreenInfo(displays)) + ); + } + + @Override + public void onDisplayRemoved(Display[] displays, int displayId) { + sendEvent( + "@RNExternalDisplay_screenDidDisconnect", + Arguments.makeNativeMap(ExternalDisplayHelper.getScreenInfo(displays)) + ); + } + + @Override + public void onCatalystInstanceDestroy() { + super.onCatalystInstanceDestroy(); + // Clean up the ExternalDisplayHelper singleton + ExternalDisplayHelper.destroy(); + } + + // Optional: Provide a getter for ExternalDisplayHelper + public ExternalDisplayHelper getExternalDisplayHelper() { + try { + return ExternalDisplayHelper.getInstance(); + } catch (IllegalStateException e) { + return null; + } + } +}