1 package expo.modules.taskManager; 2 3 import android.content.Context; 4 import android.os.Bundle; 5 import android.util.Log; 6 7 import java.lang.ref.WeakReference; 8 import java.util.ArrayList; 9 import java.util.Arrays; 10 import java.util.List; 11 import java.util.Map; 12 13 import expo.core.ModuleRegistry; 14 import expo.core.interfaces.InternalModule; 15 import expo.core.interfaces.ModuleRegistryConsumer; 16 import expo.core.interfaces.services.EventEmitter; 17 import expo.interfaces.constants.ConstantsInterface; 18 import expo.interfaces.taskManager.TaskConsumerInterface; 19 import expo.interfaces.taskManager.TaskServiceInterface; 20 import expo.interfaces.taskManager.TaskManagerInterface; 21 22 public class TaskManagerInternalModule implements InternalModule, ModuleRegistryConsumer, TaskManagerInterface { 23 private EventEmitter mEventEmitter; 24 private ConstantsInterface mConstants; 25 private TaskServiceInterface mTaskService; 26 private WeakReference<Context> mContextRef; 27 private List<Bundle> mEventsQueue = new ArrayList<>(); 28 29 public TaskManagerInternalModule(Context context) { 30 mContextRef = new WeakReference<>(context); 31 } 32 33 //region InternalModule 34 35 @Override 36 public List<Class> getExportedInterfaces() { 37 return Arrays.<Class>asList(TaskManagerInterface.class); 38 } 39 40 //endregion 41 //region ModuleRegistryConsumer 42 43 @Override 44 public void setModuleRegistry(ModuleRegistry moduleRegistry) { 45 mEventEmitter = moduleRegistry.getModule(EventEmitter.class); 46 mConstants = moduleRegistry.getModule(ConstantsInterface.class); 47 mTaskService = moduleRegistry.getSingletonModule("TaskService", TaskServiceInterface.class); 48 49 // Register in TaskService. 50 mTaskService.setTaskManager(this, getAppId(), getAppUrl()); 51 } 52 53 //endregion 54 //region TaskManagerInterface 55 56 @Override 57 public void registerTask(String taskName, Class consumerClass, Map<String, Object> options) throws Exception { 58 checkTaskService(); 59 mTaskService.registerTask(taskName, getAppId(), getAppUrl(), consumerClass, options); 60 } 61 62 @Override 63 public void unregisterTask(String taskName, Class consumerClass) throws Exception { 64 checkTaskService(); 65 mTaskService.unregisterTask(taskName, getAppId(), consumerClass); 66 } 67 68 @Override 69 public void executeTaskWithBody(Bundle body) { 70 if (mEventsQueue != null) { 71 // `startObserving` on TaskManagerModule wasn't called yet - add event body to the queue. 72 mEventsQueue.add(body); 73 } else { 74 // Manager is already being observed by JS app, so we can execute the event immediately. 75 mEventEmitter.emit(TaskManagerModule.EVENT_NAME, body); 76 } 77 } 78 79 @Override 80 public boolean taskHasConsumerOfClass(String taskName, Class consumerClass) { 81 if (mTaskService == null) { 82 return false; 83 } 84 return mTaskService.taskHasConsumerOfClass(taskName, getAppId(), consumerClass); 85 } 86 87 @Override 88 public void flushQueuedEvents() { 89 // Execute any events that came before this call. 90 if (mEventsQueue != null) { 91 for (Bundle body : mEventsQueue) { 92 mEventEmitter.emit(TaskManagerModule.EVENT_NAME, body); 93 } 94 mEventsQueue = null; 95 } 96 } 97 98 @Override 99 public String getAppId() { 100 if (mConstants != null) { 101 return mConstants.getAppId(); 102 } 103 return null; 104 } 105 106 @Override 107 public boolean isRunningInHeadlessMode() { 108 if (mConstants != null) { 109 return (boolean) mConstants.getConstants().get("isHeadless"); 110 } 111 return false; 112 } 113 114 //endregion 115 //region helpers 116 117 private String getAppUrl() { 118 // If Constants module is available and experienceUrl is provided, just return it. 119 if (mConstants != null) { 120 String experienceUrl = (String) mConstants.getConstants().get("experienceUrl"); 121 if (experienceUrl != null) { 122 return experienceUrl; 123 } 124 } 125 126 // Fallback to package name? It should work well for RN apps with just one JS app inside. 127 Context context = mContextRef.get(); 128 if (context != null) { 129 return context.getPackageName(); 130 } 131 132 return null; 133 } 134 135 private void checkTaskService() throws IllegalStateException { 136 if (mTaskService == null) { 137 throw new IllegalStateException("Unable to find TaskService singleton module in module registry."); 138 } 139 } 140 141 //endregion 142 } 143