Skip to content
Merged
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
25 changes: 21 additions & 4 deletions android/src/main/java/com/oney/WebRTCModule/GetUserMediaImpl.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.oney.WebRTCModule;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.media.projection.MediaProjectionManager;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.util.Log;
import androidx.core.util.Consumer;
Expand Down Expand Up @@ -59,6 +62,22 @@ class GetUserMediaImpl {
private Promise displayMediaPromise;
private Intent mediaProjectionPermissionResultData;

private final ServiceConnection mediaProjectionServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// Service is now bound, you can call createScreenStream()
Log.d(TAG, "MediaProjectionService bound, creating screen stream.");
ThreadUtils.runOnExecutor(() -> {
createScreenStream();
});
}

@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "MediaProjectionService disconnected.");
}
};

GetUserMediaImpl(WebRTCModule webRTCModule, ReactApplicationContext reactContext) {
this.webRTCModule = webRTCModule;
this.reactContext = reactContext;
Expand All @@ -76,10 +95,8 @@ public void onActivityResult(Activity activity, int requestCode, int resultCode,

mediaProjectionPermissionResultData = data;

ThreadUtils.runOnExecutor(() -> {
MediaProjectionService.launch(activity);
createScreenStream();
});
MediaProjectionService.launch(activity, mediaProjectionServiceConnection);

}
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,12 @@ static Notification buildMediaProjectionNotification(Context context) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, ONGOING_CONFERENCE_CHANNEL_ID);

builder
.setCategory(NotificationCompat.CATEGORY_CALL)
.setContentTitle(context.getString(R.string.media_projection_notification_title))
.setContentText(context.getString(R.string.media_projection_notification_text))
.setPriority(NotificationCompat.PRIORITY_LOW)
.setOngoing(false)
.setUsesChronometer(false)
.setAutoCancel(true)
.setOngoing(true)
.setSilent(true)
.setWhen(System.currentTimeMillis())
.setAutoCancel(false)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setOnlyAlertOnce(true)
.setSmallIcon(context.getResources().getIdentifier("ic_notification", "drawable", context.getPackageName()))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.oney.WebRTCModule;

import android.app.Activity;
import android.app.Notification;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.ServiceInfo;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
Expand All @@ -23,22 +26,30 @@
public class MediaProjectionService extends Service {
private static final String TAG = MediaProjectionService.class.getSimpleName();

static final int NOTIFICATION_ID = new Random().nextInt(99999) + 10000;
private final IBinder binder = new LocalBinder();

public static void launch(Context context) {
public class LocalBinder extends Binder {
public MediaProjectionService getService() {
// Return this instance of MediaProjectionService so clients can call public methods
return MediaProjectionService.this;
}
}

public static void launch(Activity activity, ServiceConnection serviceConnection) {
if (!WebRTCModuleOptions.getInstance().enableMediaProjectionService) {
return;
}

MediaProjectionNotification.createNotificationChannel(context);
Intent intent = new Intent(context, MediaProjectionService.class);
MediaProjectionNotification.createNotificationChannel(activity);
Intent intent = new Intent(activity, MediaProjectionService.class);
activity.bindService(intent, serviceConnection, Context.BIND_IMPORTANT);
ComponentName componentName;

try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
componentName = context.startForegroundService(intent);
componentName = activity.startForegroundService(intent);
} else {
componentName = context.startService(intent);
componentName = activity.startService(intent);
}
} catch (RuntimeException e) {
// Avoid crashing due to ForegroundServiceStartNotAllowedException (API level 31).
Expand All @@ -65,18 +76,21 @@ public static void abort(Context context) {

@Override
public IBinder onBind(Intent intent) {
return null;
return binder;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

Notification notification = MediaProjectionNotification.buildMediaProjectionNotification(this);

final Random random = new Random();
final int id = random.nextInt(Integer.MAX_VALUE);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION);
startForeground(id, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION);
} else {
startForeground(NOTIFICATION_ID, notification);
startForeground(id, notification);
}

return START_NOT_STICKY;
Expand Down
Loading