mirror of https://github.com/jitsi/jitsi-meet
[WIP] adds BroadcastService (#8336)
feat(external_api) exposes more events from JS to native and adds the ability to send actions from native to JS.pull/8406/head jitsi-meet_5412
parent
1196ede961
commit
5ef60c3a7d
@ -0,0 +1,84 @@ |
||||
package org.jitsi.meet.sdk; |
||||
|
||||
import android.content.Intent; |
||||
import android.os.Bundle; |
||||
|
||||
import com.facebook.react.bridge.WritableNativeMap; |
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger; |
||||
|
||||
import java.util.HashMap; |
||||
|
||||
/** |
||||
* Wraps the name and extra data for events that were broadcasted locally. |
||||
*/ |
||||
public class BroadcastAction { |
||||
private static final String TAG = BroadcastAction.class.getSimpleName(); |
||||
|
||||
private final Type type; |
||||
private final HashMap<String, Object> data; |
||||
|
||||
public BroadcastAction(Intent intent) { |
||||
this.type = Type.buildTypeFromAction(intent.getAction()); |
||||
this.data = buildDataFromBundle(intent.getExtras()); |
||||
} |
||||
|
||||
public Type getType() { |
||||
return this.type; |
||||
} |
||||
|
||||
public HashMap<String, Object> getData() { |
||||
return this.data; |
||||
} |
||||
|
||||
public WritableNativeMap getDataAsWritableNativeMap() { |
||||
WritableNativeMap nativeMap = new WritableNativeMap(); |
||||
|
||||
for (String key : this.data.keySet()) { |
||||
try { |
||||
// TODO add support for different types of objects
|
||||
nativeMap.putString(key, this.data.get(key).toString()); |
||||
} catch (Exception e) { |
||||
JitsiMeetLogger.w(TAG + " invalid extra data in event", e); |
||||
} |
||||
} |
||||
|
||||
return nativeMap; |
||||
} |
||||
|
||||
private static HashMap<String, Object> buildDataFromBundle(Bundle bundle) { |
||||
HashMap<String, Object> map = new HashMap<>(); |
||||
|
||||
if (bundle != null) { |
||||
for (String key : bundle.keySet()) { |
||||
map.put(key, bundle.get(key)); |
||||
} |
||||
} |
||||
|
||||
return map; |
||||
} |
||||
|
||||
enum Type { |
||||
SET_AUDIO_MUTED("org.jitsi.meet.SET_AUDIO_MUTED"), |
||||
HANG_UP("org.jitsi.meet.HANG_UP"); |
||||
|
||||
private final String action; |
||||
|
||||
Type(String action) { |
||||
this.action = action; |
||||
} |
||||
|
||||
public String getAction() { |
||||
return action; |
||||
} |
||||
|
||||
private static Type buildTypeFromAction(String action) { |
||||
for (Type type : Type.values()) { |
||||
if (type.action.equalsIgnoreCase(action)) { |
||||
return type; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,30 @@ |
||||
package org.jitsi.meet.sdk; |
||||
|
||||
import android.content.Context; |
||||
import android.content.Intent; |
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager; |
||||
|
||||
import com.facebook.react.bridge.ReadableMap; |
||||
|
||||
/** |
||||
* Class used to emit events through the LocalBroadcastManager, called when events |
||||
* from JS occurred. Takes an action name from JS, builds and broadcasts the {@link BroadcastEvent} |
||||
*/ |
||||
public class BroadcastEmitter { |
||||
private final LocalBroadcastManager localBroadcastManager; |
||||
|
||||
public BroadcastEmitter(Context context) { |
||||
localBroadcastManager = LocalBroadcastManager.getInstance(context); |
||||
} |
||||
|
||||
public void sendBroadcast(String name, ReadableMap data) { |
||||
BroadcastEvent event = new BroadcastEvent(name, data); |
||||
|
||||
Intent intent = event.buildIntent(); |
||||
|
||||
if (intent != null) { |
||||
localBroadcastManager.sendBroadcast(intent); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,130 @@ |
||||
package org.jitsi.meet.sdk; |
||||
|
||||
import android.content.Intent; |
||||
import android.os.Bundle; |
||||
|
||||
import com.facebook.react.bridge.ReadableMap; |
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger; |
||||
|
||||
import java.util.HashMap; |
||||
|
||||
/** |
||||
* Wraps the name and extra data for the events that occur on the JS side and are |
||||
* to be broadcasted. |
||||
*/ |
||||
public class BroadcastEvent { |
||||
|
||||
private static final String TAG = BroadcastEvent.class.getSimpleName(); |
||||
|
||||
private final Type type; |
||||
private final HashMap<String, Object> data; |
||||
|
||||
public BroadcastEvent(String name, ReadableMap data) { |
||||
this.type = Type.buildTypeFromName(name); |
||||
this.data = data.toHashMap(); |
||||
} |
||||
|
||||
public BroadcastEvent(Intent intent) { |
||||
this.type = Type.buildTypeFromAction(intent.getAction()); |
||||
this.data = buildDataFromBundle(intent.getExtras()); |
||||
} |
||||
|
||||
public Type getType() { |
||||
return this.type; |
||||
} |
||||
|
||||
public HashMap<String, Object> getData() { |
||||
return this.data; |
||||
} |
||||
|
||||
public Intent buildIntent() { |
||||
if (type != null && type.action != null) { |
||||
Intent intent = new Intent(type.action); |
||||
|
||||
for (String key : this.data.keySet()) { |
||||
try { |
||||
intent.putExtra(key, this.data.get(key).toString()); |
||||
} catch (Exception e) { |
||||
JitsiMeetLogger.w(TAG + " invalid extra data in event", e); |
||||
} |
||||
} |
||||
|
||||
return intent; |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
private static HashMap<String, Object> buildDataFromBundle(Bundle bundle) { |
||||
if (bundle != null) { |
||||
try { |
||||
HashMap<String, Object> map = new HashMap<>(); |
||||
|
||||
for (String key : bundle.keySet()) { |
||||
map.put(key, bundle.get(key)); |
||||
} |
||||
|
||||
return map; |
||||
} catch (Exception e) { |
||||
JitsiMeetLogger.w(TAG + " invalid extra data", e); |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
public enum Type { |
||||
CONFERENCE_JOINED("org.jitsi.meet.CONFERENCE_JOINED"), |
||||
CONFERENCE_TERMINATED("org.jitsi.meet.CONFERENCE_TERMINATED"), |
||||
CONFERENCE_WILL_JOIN("org.jitsi.meet.CONFERENCE_WILL_JOIN"), |
||||
AUDIO_MUTED_CHANGED("org.jitsi.meet.AUDIO_MUTED_CHANGED"), |
||||
PARTICIPANT_JOINED("org.jitsi.meet.PARTICIPANT_JOINED"), |
||||
PARTICIPANT_LEFT("org.jitsi.meet.PARTICIPANT_LEFT"); |
||||
|
||||
private static final String CONFERENCE_WILL_JOIN_NAME = "CONFERENCE_WILL_JOIN"; |
||||
private static final String CONFERENCE_JOINED_NAME = "CONFERENCE_JOINED"; |
||||
private static final String CONFERENCE_TERMINATED_NAME = "CONFERENCE_TERMINATED"; |
||||
private static final String AUDIO_MUTED_CHANGED_NAME = "AUDIO_MUTED_CHANGED"; |
||||
private static final String PARTICIPANT_JOINED_NAME = "PARTICIPANT_JOINED"; |
||||
private static final String PARTICIPANT_LEFT_NAME = "PARTICIPANT_LEFT"; |
||||
|
||||
private final String action; |
||||
|
||||
Type(String action) { |
||||
this.action = action; |
||||
} |
||||
|
||||
public String getAction() { |
||||
return action; |
||||
} |
||||
|
||||
private static Type buildTypeFromAction(String action) { |
||||
for (Type type : Type.values()) { |
||||
if (type.action.equalsIgnoreCase(action)) { |
||||
return type; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
private static Type buildTypeFromName(String name) { |
||||
switch (name) { |
||||
case CONFERENCE_WILL_JOIN_NAME: |
||||
return CONFERENCE_WILL_JOIN; |
||||
case CONFERENCE_JOINED_NAME: |
||||
return CONFERENCE_JOINED; |
||||
case CONFERENCE_TERMINATED_NAME: |
||||
return CONFERENCE_TERMINATED; |
||||
case AUDIO_MUTED_CHANGED_NAME: |
||||
return AUDIO_MUTED_CHANGED; |
||||
case PARTICIPANT_JOINED_NAME: |
||||
return PARTICIPANT_JOINED; |
||||
case PARTICIPANT_LEFT_NAME: |
||||
return PARTICIPANT_LEFT; |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,15 @@ |
||||
package org.jitsi.meet.sdk; |
||||
|
||||
import android.content.Intent; |
||||
|
||||
public class BroadcastIntentHelper { |
||||
public static Intent buildSetAudioMutedIntent(boolean muted) { |
||||
Intent intent = new Intent(BroadcastAction.Type.SET_AUDIO_MUTED.getAction()); |
||||
intent.putExtra("muted", muted); |
||||
return intent; |
||||
} |
||||
|
||||
public static Intent buildHangUpIntent() { |
||||
return new Intent(BroadcastAction.Type.HANG_UP.getAction()); |
||||
} |
||||
} |
@ -0,0 +1,32 @@ |
||||
package org.jitsi.meet.sdk; |
||||
|
||||
import android.content.Context; |
||||
import android.content.Intent; |
||||
import android.content.IntentFilter; |
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager; |
||||
|
||||
/** |
||||
* Listens for {@link BroadcastAction}s on LocalBroadcastManager. When one occurs, |
||||
* it emits it to JS. |
||||
*/ |
||||
public class BroadcastReceiver extends android.content.BroadcastReceiver { |
||||
|
||||
public BroadcastReceiver(Context context) { |
||||
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context); |
||||
|
||||
IntentFilter intentFilter = new IntentFilter(); |
||||
intentFilter.addAction(BroadcastAction.Type.SET_AUDIO_MUTED.getAction()); |
||||
intentFilter.addAction(BroadcastAction.Type.HANG_UP.getAction()); |
||||
|
||||
localBroadcastManager.registerReceiver(this, intentFilter); |
||||
} |
||||
|
||||
@Override |
||||
public void onReceive(Context context, Intent intent) { |
||||
BroadcastAction action = new BroadcastAction(intent); |
||||
String actionName = action.getType().getAction(); |
||||
|
||||
ReactInstanceManagerHolder.emitEvent(actionName, action.getDataAsWritableNativeMap()); |
||||
} |
||||
} |
@ -0,0 +1,24 @@ |
||||
/* Copyright @ 2021-present 8x8, Inc.
|
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#import <React/RCTBridgeModule.h> |
||||
#import <React/RCTEventEmitter.h> |
||||
|
||||
@interface ExternalAPI : RCTEventEmitter<RCTBridgeModule> |
||||
|
||||
- (void)sendHangUp; |
||||
- (void)sendSetAudioMuted: (BOOL)muted; |
||||
|
||||
@end |
Loading…
Reference in new issue