Skip to content

Fix android DisplayListener Events #964

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"workspaces": [
"packages/*"
],
"version": "0.6.6",
"packageManager": "yarn@1.22.22",
"scripts": {
"lint": "eslint .",
Expand Down
28 changes: 28 additions & 0 deletions packages/react-native-external-display/android/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>react-native-external-display</name>
<comment>Project react-native-external-display created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>1733156198568</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, Object> getScreenInfo(Display[] displays) {
HashMap<String, Object> info = new HashMap<String, Object>();
for (Display display : displays) {
int displayId = display.getDisplayId();
if (
display.getDisplayId() == Display.DEFAULT_DISPLAY ||
(display.getFlags() & Display.FLAG_PRESENTATION) == 0
) {
continue;
}
HashMap<String, Object> data = new HashMap<String, Object>();
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<String, Object> getScreenInfo(Display[] displays) {
HashMap<String, Object> 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<String, Object> 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);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
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;
import com.facebook.react.module.model.ReactModuleInfoProvider;
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;
Expand All @@ -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<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
List<ViewManager> 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<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
List<ViewManager> viewManagers = new ArrayList<>();
viewManagers.add(new RNExternalDisplayManager(reactContext));
return viewManagers;
}
}

@Override
public ReactModuleInfoProvider getReactModuleInfoProvider() {
return () -> {
final Map<String, ReactModuleInfo> 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<String, ReactModuleInfo> 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;
};
}
}
Loading