Loading packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java +11 −243 Original line number Diff line number Diff line Loading @@ -16,23 +16,16 @@ package com.android.systemui.recents.events; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; import android.os.UserHandle; import android.util.Log; import android.util.MutableBoolean; import com.android.systemui.recents.misc.ReferenceCountedTrigger; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; Loading Loading @@ -117,11 +110,7 @@ class EventHandlerMethod { * <p> * Currently, there is a single EventBus that handles {@link EventBus.Event}s for each subscriber * on the main application thread. Publishers can send() events to synchronously call subscribers * of that event, or post() events to be processed in the next run of the {@link Looper}. In * addition, the EventBus supports sending and handling {@link EventBus.InterprocessEvent}s * (within the same package) implemented using standard {@link BroadcastReceiver} mechanism. * Interprocess events must be posted using postInterprocess() to ensure that it is dispatched * correctly across processes. * of that event, or post() events to be processed in the next run of the {@link Looper}. * * <p> * Subscribers must be registered with a particular EventBus before they will receive events, and Loading @@ -135,26 +124,12 @@ class EventHandlerMethod { * <li>Methods must take one parameter, of class type deriving from {@link EventBus.Event} * </ul> * * <p> * Interprocess-Event method signature:<ul> * <li>Methods must be public final * <li>Methods must return void * <li>Methods must be called "onInterprocessBusEvent" * <li>Methods must take one parameter, of class type deriving from {@link EventBus.InterprocessEvent} * </ul> * </p> * * </p> * Each subscriber can be registered with a given priority (default 1), and events will be dispatch * in decreasing order of priority. For subscribers with the same priority, events will be * dispatched by latest registration time to earliest. * * <p> * Interprocess events must extend {@link EventBus.InterprocessEvent}, have a constructor which * takes a {@link Bundle} and implement toBundle(). This allows us to serialize events to be sent * across processes. * * <p> * Caveats:<ul> * <li>The EventBus keeps a {@link WeakReference} to the publisher to prevent memory leaks, so * there must be another strong reference to the publisher for it to not get garbage-collected and Loading Loading @@ -201,7 +176,7 @@ class EventHandlerMethod { * result? * </p> */ public class EventBus extends BroadcastReceiver { public class EventBus { private static final String TAG = "EventBus"; private static final boolean DEBUG_TRACE_ALL = false; Loading Loading @@ -313,35 +288,6 @@ public class EventBus extends BroadcastReceiver { } } /** * An inter-process event super class that allows us to track user state across subscriber * invocations. */ public static class InterprocessEvent extends Event { private static final String EXTRA_USER = "_user"; // The user which this event originated from public final int user; // Only accessible from derived events protected InterprocessEvent(int user) { this.user = user; } /** * Called from the event bus */ protected InterprocessEvent(Bundle b) { user = b.getInt(EXTRA_USER); } protected Bundle toBundle() { Bundle b = new Bundle(); b.putInt(EXTRA_USER, user); return b; } } /** * Proguard must also know, and keep, all methods matching this signature. * Loading @@ -351,13 +297,6 @@ public class EventBus extends BroadcastReceiver { * } */ private static final String METHOD_PREFIX = "onBusEvent"; private static final String INTERPROCESS_METHOD_PREFIX = "onInterprocessBusEvent"; // Ensures that interprocess events can only be sent from a process holding this permission. */ private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF"; // Used for passing event data across process boundaries private static final String EXTRA_INTERPROCESS_EVENT_BUNDLE = "interprocess_event_bundle"; // The default priority of all subscribers private static final int DEFAULT_SUBSCRIBER_PRIORITY = 1; Loading @@ -383,10 +322,6 @@ public class EventBus extends BroadcastReceiver { // The handler to post all events private Handler mHandler; // Keep track of whether we have registered a broadcast receiver already, so that we can // unregister ourselves before re-registering again with a new IntentFilter. private boolean mHasRegisteredReceiver; /** * Map from event class -> event handler list. Keeps track of the actual mapping from event * to subscriber method. Loading @@ -400,13 +335,6 @@ public class EventBus extends BroadcastReceiver { */ private HashMap<Class<? extends Object>, ArrayList<EventHandlerMethod>> mSubscriberTypeMap = new HashMap<>(); /** * Map from interprocess event name -> interprocess event class. Used for mapping the event * name after receiving the broadcast, to the event type. After which a new instance is created * and posted in the local process. */ private HashMap<String, Class<? extends InterprocessEvent>> mInterprocessEventNameMap = new HashMap<>(); /** * Set of all currently registered subscribers */ Loading Loading @@ -447,7 +375,7 @@ public class EventBus extends BroadcastReceiver { * be scanned for appropriate event handler methods. */ public void register(Object subscriber) { registerSubscriber(subscriber, DEFAULT_SUBSCRIBER_PRIORITY, null); registerSubscriber(subscriber, DEFAULT_SUBSCRIBER_PRIORITY); } /** Loading @@ -460,44 +388,7 @@ public class EventBus extends BroadcastReceiver { * subscribers */ public void register(Object subscriber, int priority) { registerSubscriber(subscriber, priority, null); } /** * Explicitly registers a subscriber to receive interprocess events with the default priority. * * @param subscriber the subscriber to handle events. If this is the first instance of the * subscriber's class type that has been registered, the class's methods will * be scanned for appropriate event handler methods. */ public void registerInterprocessAsCurrentUser(Context context, Object subscriber) { registerInterprocessAsCurrentUser(context, subscriber, DEFAULT_SUBSCRIBER_PRIORITY); } /** * Registers a subscriber to receive interprocess events with the given priority. * * @param subscriber the subscriber to handle events. If this is the first instance of the * subscriber's class type that has been registered, the class's methods will * be scanned for appropriate event handler methods. * @param priority the priority that this subscriber will receive events relative to other * subscribers */ public void registerInterprocessAsCurrentUser(Context context, Object subscriber, int priority) { if (DEBUG_TRACE_ALL) { logWithPid("registerInterprocessAsCurrentUser(" + subscriber.getClass().getSimpleName() + ")"); } // Register the subscriber normally, and update the broadcast receiver filter if this is // a new subscriber type with interprocess events MutableBoolean hasInterprocessEventsChanged = new MutableBoolean(false); registerSubscriber(subscriber, priority, hasInterprocessEventsChanged); if (DEBUG_TRACE_ALL) { logWithPid("hasInterprocessEventsChanged: " + hasInterprocessEventsChanged.value); } if (hasInterprocessEventsChanged.value) { registerReceiverForInterprocessEvents(context); } registerSubscriber(subscriber, priority); } /** Loading Loading @@ -537,18 +428,6 @@ public class EventBus extends BroadcastReceiver { } } /** * Explicit unregistration for interprocess event subscribers. This actually behaves exactly * the same as unregister() since we also do not want to stop listening for specific * inter-process messages in case new instances of that subscriber is registered. */ public void unregisterInterprocess(Context context, Object subscriber) { if (DEBUG_TRACE_ALL) { logWithPid("unregisterInterprocess()"); } unregister(subscriber); } /** * Sends an event to the subscribers of the given event type immediately. This can only be * called from the same thread as the EventBus's looper thread (for the default EventBus, this Loading Loading @@ -599,57 +478,6 @@ public class EventBus extends BroadcastReceiver { } } /** Prevent post()ing an InterprocessEvent */ @Deprecated public void post(InterprocessEvent event) { throw new RuntimeException("Not supported, use postInterprocess"); } /** Prevent send()ing an InterprocessEvent */ @Deprecated public void send(InterprocessEvent event) { throw new RuntimeException("Not supported, use postInterprocess"); } /** * Posts an interprocess event. */ public void postInterprocess(Context context, final InterprocessEvent event) { if (DEBUG_TRACE_ALL) { logWithPid("postInterprocess(" + event.getClass().getSimpleName() + ")"); } String eventType = event.getClass().getName(); Bundle eventBundle = event.toBundle(); Intent intent = new Intent(eventType); intent.setPackage(context.getPackageName()); intent.putExtra(EXTRA_INTERPROCESS_EVENT_BUNDLE, eventBundle); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | Intent.FLAG_RECEIVER_FOREGROUND); context.sendBroadcastAsUser(intent, UserHandle.ALL); } /** * Receiver for interprocess events. */ @Override public void onReceive(Context context, Intent intent) { if (DEBUG_TRACE_ALL) { logWithPid("onReceive(" + intent.getAction() + ", user " + UserHandle.myUserId() + ")"); } Bundle eventBundle = intent.getBundleExtra(EXTRA_INTERPROCESS_EVENT_BUNDLE); Class<? extends InterprocessEvent> eventType = mInterprocessEventNameMap.get(intent.getAction()); try { Constructor<? extends InterprocessEvent> ctor = eventType.getConstructor(Bundle.class); send((Event) ctor.newInstance(eventBundle)); } catch (NoSuchMethodException| InvocationTargetException| InstantiationException| IllegalAccessException e) { Log.e(TAG, "Failed to create InterprocessEvent", e.getCause()); } } /** * @return a dump of the current state of the EventBus */ Loading Loading @@ -711,8 +539,7 @@ public class EventBus extends BroadcastReceiver { /** * Registers a new subscriber. */ private void registerSubscriber(Object subscriber, int priority, MutableBoolean hasInterprocessEventsChangedOut) { private void registerSubscriber(Object subscriber, int priority) { // Fail immediately if we are being called from the non-main thread long callingThreadId = Thread.currentThread().getId(); if (callingThreadId != mHandler.getLooper().getThread().getId()) { Loading Loading @@ -759,32 +586,16 @@ public class EventBus extends BroadcastReceiver { } // Find all the valid event bus handler methods of the subscriber MutableBoolean isInterprocessEvent = new MutableBoolean(false); Method[] methods = subscriberType.getDeclaredMethods(); for (Method m : methods) { Class<?>[] parameterTypes = m.getParameterTypes(); isInterprocessEvent.value = false; if (isValidEventBusHandlerMethod(m, parameterTypes, isInterprocessEvent)) { if (isValidEventBusHandlerMethod(m, parameterTypes)) { Class<? extends Event> eventType = (Class<? extends Event>) parameterTypes[0]; ArrayList<EventHandler> eventTypeHandlers = mEventTypeMap.get(eventType); if (eventTypeHandlers == null) { eventTypeHandlers = new ArrayList<>(); mEventTypeMap.put(eventType, eventTypeHandlers); } if (isInterprocessEvent.value) { try { // Enforce that the event must have a Bundle constructor eventType.getConstructor(Bundle.class); mInterprocessEventNameMap.put(eventType.getName(), (Class<? extends InterprocessEvent>) eventType); if (hasInterprocessEventsChangedOut != null) { hasInterprocessEventsChangedOut.value = true; } } catch (NoSuchMethodException e) { throw new RuntimeException("Expected InterprocessEvent to have a Bundle constructor"); } } EventHandlerMethod method = new EventHandlerMethod(m, eventType); EventHandler handler = new EventHandler(sub, method, priority); eventTypeHandlers.add(handler); Loading @@ -793,8 +604,7 @@ public class EventBus extends BroadcastReceiver { if (DEBUG_TRACE_ALL) { logWithPid(" * Method: " + m.getName() + " event: " + parameterTypes[0].getSimpleName() + " interprocess? " + isInterprocessEvent.value); " event: " + parameterTypes[0].getSimpleName()); } } } Loading Loading @@ -830,12 +640,7 @@ public class EventBus extends BroadcastReceiver { final EventHandler eventHandler = eventHandlers.get(i); if (eventHandler.subscriber.getReference() != null) { if (event.requiresPost) { mHandler.post(new Runnable() { @Override public void run() { processEvent(eventHandler, event); } }); mHandler.post(() -> processEvent(eventHandler, event)); hasPostedEvent = true; } else { processEvent(eventHandler, event); Loading @@ -845,12 +650,7 @@ public class EventBus extends BroadcastReceiver { // Clean up after this event, deferring until all subscribers have been called if (hasPostedEvent) { mHandler.post(new Runnable() { @Override public void run() { event.onPostDispatch(); } }); mHandler.post(event::onPostDispatch); } else { event.onPostDispatch(); } Loading Loading @@ -897,29 +697,6 @@ public class EventBus extends BroadcastReceiver { } } /** * Re-registers the broadcast receiver for any new messages that we want to listen for. */ private void registerReceiverForInterprocessEvents(Context context) { if (DEBUG_TRACE_ALL) { logWithPid("registerReceiverForInterprocessEvents()"); } // Rebuild the receiver filter with the new interprocess events IntentFilter filter = new IntentFilter(); for (String eventName : mInterprocessEventNameMap.keySet()) { filter.addAction(eventName); if (DEBUG_TRACE_ALL) { logWithPid(" filter: " + eventName); } } // Re-register the receiver with the new filter if (mHasRegisteredReceiver) { context.unregisterReceiver(this); } context.registerReceiverAsUser(this, UserHandle.ALL, filter, PERMISSION_SELF, mHandler); mHasRegisteredReceiver = true; } /** * Returns whether this subscriber is currently registered. If {@param removeFoundSubscriber} * is true, then remove the subscriber before returning. Loading @@ -940,28 +717,19 @@ public class EventBus extends BroadcastReceiver { /** * @return whether {@param method} is a valid (normal or interprocess) event bus handler method */ private boolean isValidEventBusHandlerMethod(Method method, Class<?>[] parameterTypes, MutableBoolean isInterprocessEventOut) { private boolean isValidEventBusHandlerMethod(Method method, Class<?>[] parameterTypes) { int modifiers = method.getModifiers(); if (Modifier.isPublic(modifiers) && Modifier.isFinal(modifiers) && method.getReturnType().equals(Void.TYPE) && parameterTypes.length == 1) { if (EventBus.InterprocessEvent.class.isAssignableFrom(parameterTypes[0]) && method.getName().startsWith(INTERPROCESS_METHOD_PREFIX)) { isInterprocessEventOut.value = true; return true; } else if (EventBus.Event.class.isAssignableFrom(parameterTypes[0]) && if (EventBus.Event.class.isAssignableFrom(parameterTypes[0]) && method.getName().startsWith(METHOD_PREFIX)) { isInterprocessEventOut.value = false; return true; } else { if (DEBUG_TRACE_ALL) { if (!EventBus.Event.class.isAssignableFrom(parameterTypes[0])) { logWithPid(" Expected method take an Event-based parameter: " + method.getName()); } else if (!method.getName().startsWith(INTERPROCESS_METHOD_PREFIX) && !method.getName().startsWith(METHOD_PREFIX)) { logWithPid(" Expected method start with method prefix: " + method.getName()); } } } Loading Loading
packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java +11 −243 Original line number Diff line number Diff line Loading @@ -16,23 +16,16 @@ package com.android.systemui.recents.events; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; import android.os.UserHandle; import android.util.Log; import android.util.MutableBoolean; import com.android.systemui.recents.misc.ReferenceCountedTrigger; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; Loading Loading @@ -117,11 +110,7 @@ class EventHandlerMethod { * <p> * Currently, there is a single EventBus that handles {@link EventBus.Event}s for each subscriber * on the main application thread. Publishers can send() events to synchronously call subscribers * of that event, or post() events to be processed in the next run of the {@link Looper}. In * addition, the EventBus supports sending and handling {@link EventBus.InterprocessEvent}s * (within the same package) implemented using standard {@link BroadcastReceiver} mechanism. * Interprocess events must be posted using postInterprocess() to ensure that it is dispatched * correctly across processes. * of that event, or post() events to be processed in the next run of the {@link Looper}. * * <p> * Subscribers must be registered with a particular EventBus before they will receive events, and Loading @@ -135,26 +124,12 @@ class EventHandlerMethod { * <li>Methods must take one parameter, of class type deriving from {@link EventBus.Event} * </ul> * * <p> * Interprocess-Event method signature:<ul> * <li>Methods must be public final * <li>Methods must return void * <li>Methods must be called "onInterprocessBusEvent" * <li>Methods must take one parameter, of class type deriving from {@link EventBus.InterprocessEvent} * </ul> * </p> * * </p> * Each subscriber can be registered with a given priority (default 1), and events will be dispatch * in decreasing order of priority. For subscribers with the same priority, events will be * dispatched by latest registration time to earliest. * * <p> * Interprocess events must extend {@link EventBus.InterprocessEvent}, have a constructor which * takes a {@link Bundle} and implement toBundle(). This allows us to serialize events to be sent * across processes. * * <p> * Caveats:<ul> * <li>The EventBus keeps a {@link WeakReference} to the publisher to prevent memory leaks, so * there must be another strong reference to the publisher for it to not get garbage-collected and Loading Loading @@ -201,7 +176,7 @@ class EventHandlerMethod { * result? * </p> */ public class EventBus extends BroadcastReceiver { public class EventBus { private static final String TAG = "EventBus"; private static final boolean DEBUG_TRACE_ALL = false; Loading Loading @@ -313,35 +288,6 @@ public class EventBus extends BroadcastReceiver { } } /** * An inter-process event super class that allows us to track user state across subscriber * invocations. */ public static class InterprocessEvent extends Event { private static final String EXTRA_USER = "_user"; // The user which this event originated from public final int user; // Only accessible from derived events protected InterprocessEvent(int user) { this.user = user; } /** * Called from the event bus */ protected InterprocessEvent(Bundle b) { user = b.getInt(EXTRA_USER); } protected Bundle toBundle() { Bundle b = new Bundle(); b.putInt(EXTRA_USER, user); return b; } } /** * Proguard must also know, and keep, all methods matching this signature. * Loading @@ -351,13 +297,6 @@ public class EventBus extends BroadcastReceiver { * } */ private static final String METHOD_PREFIX = "onBusEvent"; private static final String INTERPROCESS_METHOD_PREFIX = "onInterprocessBusEvent"; // Ensures that interprocess events can only be sent from a process holding this permission. */ private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF"; // Used for passing event data across process boundaries private static final String EXTRA_INTERPROCESS_EVENT_BUNDLE = "interprocess_event_bundle"; // The default priority of all subscribers private static final int DEFAULT_SUBSCRIBER_PRIORITY = 1; Loading @@ -383,10 +322,6 @@ public class EventBus extends BroadcastReceiver { // The handler to post all events private Handler mHandler; // Keep track of whether we have registered a broadcast receiver already, so that we can // unregister ourselves before re-registering again with a new IntentFilter. private boolean mHasRegisteredReceiver; /** * Map from event class -> event handler list. Keeps track of the actual mapping from event * to subscriber method. Loading @@ -400,13 +335,6 @@ public class EventBus extends BroadcastReceiver { */ private HashMap<Class<? extends Object>, ArrayList<EventHandlerMethod>> mSubscriberTypeMap = new HashMap<>(); /** * Map from interprocess event name -> interprocess event class. Used for mapping the event * name after receiving the broadcast, to the event type. After which a new instance is created * and posted in the local process. */ private HashMap<String, Class<? extends InterprocessEvent>> mInterprocessEventNameMap = new HashMap<>(); /** * Set of all currently registered subscribers */ Loading Loading @@ -447,7 +375,7 @@ public class EventBus extends BroadcastReceiver { * be scanned for appropriate event handler methods. */ public void register(Object subscriber) { registerSubscriber(subscriber, DEFAULT_SUBSCRIBER_PRIORITY, null); registerSubscriber(subscriber, DEFAULT_SUBSCRIBER_PRIORITY); } /** Loading @@ -460,44 +388,7 @@ public class EventBus extends BroadcastReceiver { * subscribers */ public void register(Object subscriber, int priority) { registerSubscriber(subscriber, priority, null); } /** * Explicitly registers a subscriber to receive interprocess events with the default priority. * * @param subscriber the subscriber to handle events. If this is the first instance of the * subscriber's class type that has been registered, the class's methods will * be scanned for appropriate event handler methods. */ public void registerInterprocessAsCurrentUser(Context context, Object subscriber) { registerInterprocessAsCurrentUser(context, subscriber, DEFAULT_SUBSCRIBER_PRIORITY); } /** * Registers a subscriber to receive interprocess events with the given priority. * * @param subscriber the subscriber to handle events. If this is the first instance of the * subscriber's class type that has been registered, the class's methods will * be scanned for appropriate event handler methods. * @param priority the priority that this subscriber will receive events relative to other * subscribers */ public void registerInterprocessAsCurrentUser(Context context, Object subscriber, int priority) { if (DEBUG_TRACE_ALL) { logWithPid("registerInterprocessAsCurrentUser(" + subscriber.getClass().getSimpleName() + ")"); } // Register the subscriber normally, and update the broadcast receiver filter if this is // a new subscriber type with interprocess events MutableBoolean hasInterprocessEventsChanged = new MutableBoolean(false); registerSubscriber(subscriber, priority, hasInterprocessEventsChanged); if (DEBUG_TRACE_ALL) { logWithPid("hasInterprocessEventsChanged: " + hasInterprocessEventsChanged.value); } if (hasInterprocessEventsChanged.value) { registerReceiverForInterprocessEvents(context); } registerSubscriber(subscriber, priority); } /** Loading Loading @@ -537,18 +428,6 @@ public class EventBus extends BroadcastReceiver { } } /** * Explicit unregistration for interprocess event subscribers. This actually behaves exactly * the same as unregister() since we also do not want to stop listening for specific * inter-process messages in case new instances of that subscriber is registered. */ public void unregisterInterprocess(Context context, Object subscriber) { if (DEBUG_TRACE_ALL) { logWithPid("unregisterInterprocess()"); } unregister(subscriber); } /** * Sends an event to the subscribers of the given event type immediately. This can only be * called from the same thread as the EventBus's looper thread (for the default EventBus, this Loading Loading @@ -599,57 +478,6 @@ public class EventBus extends BroadcastReceiver { } } /** Prevent post()ing an InterprocessEvent */ @Deprecated public void post(InterprocessEvent event) { throw new RuntimeException("Not supported, use postInterprocess"); } /** Prevent send()ing an InterprocessEvent */ @Deprecated public void send(InterprocessEvent event) { throw new RuntimeException("Not supported, use postInterprocess"); } /** * Posts an interprocess event. */ public void postInterprocess(Context context, final InterprocessEvent event) { if (DEBUG_TRACE_ALL) { logWithPid("postInterprocess(" + event.getClass().getSimpleName() + ")"); } String eventType = event.getClass().getName(); Bundle eventBundle = event.toBundle(); Intent intent = new Intent(eventType); intent.setPackage(context.getPackageName()); intent.putExtra(EXTRA_INTERPROCESS_EVENT_BUNDLE, eventBundle); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | Intent.FLAG_RECEIVER_FOREGROUND); context.sendBroadcastAsUser(intent, UserHandle.ALL); } /** * Receiver for interprocess events. */ @Override public void onReceive(Context context, Intent intent) { if (DEBUG_TRACE_ALL) { logWithPid("onReceive(" + intent.getAction() + ", user " + UserHandle.myUserId() + ")"); } Bundle eventBundle = intent.getBundleExtra(EXTRA_INTERPROCESS_EVENT_BUNDLE); Class<? extends InterprocessEvent> eventType = mInterprocessEventNameMap.get(intent.getAction()); try { Constructor<? extends InterprocessEvent> ctor = eventType.getConstructor(Bundle.class); send((Event) ctor.newInstance(eventBundle)); } catch (NoSuchMethodException| InvocationTargetException| InstantiationException| IllegalAccessException e) { Log.e(TAG, "Failed to create InterprocessEvent", e.getCause()); } } /** * @return a dump of the current state of the EventBus */ Loading Loading @@ -711,8 +539,7 @@ public class EventBus extends BroadcastReceiver { /** * Registers a new subscriber. */ private void registerSubscriber(Object subscriber, int priority, MutableBoolean hasInterprocessEventsChangedOut) { private void registerSubscriber(Object subscriber, int priority) { // Fail immediately if we are being called from the non-main thread long callingThreadId = Thread.currentThread().getId(); if (callingThreadId != mHandler.getLooper().getThread().getId()) { Loading Loading @@ -759,32 +586,16 @@ public class EventBus extends BroadcastReceiver { } // Find all the valid event bus handler methods of the subscriber MutableBoolean isInterprocessEvent = new MutableBoolean(false); Method[] methods = subscriberType.getDeclaredMethods(); for (Method m : methods) { Class<?>[] parameterTypes = m.getParameterTypes(); isInterprocessEvent.value = false; if (isValidEventBusHandlerMethod(m, parameterTypes, isInterprocessEvent)) { if (isValidEventBusHandlerMethod(m, parameterTypes)) { Class<? extends Event> eventType = (Class<? extends Event>) parameterTypes[0]; ArrayList<EventHandler> eventTypeHandlers = mEventTypeMap.get(eventType); if (eventTypeHandlers == null) { eventTypeHandlers = new ArrayList<>(); mEventTypeMap.put(eventType, eventTypeHandlers); } if (isInterprocessEvent.value) { try { // Enforce that the event must have a Bundle constructor eventType.getConstructor(Bundle.class); mInterprocessEventNameMap.put(eventType.getName(), (Class<? extends InterprocessEvent>) eventType); if (hasInterprocessEventsChangedOut != null) { hasInterprocessEventsChangedOut.value = true; } } catch (NoSuchMethodException e) { throw new RuntimeException("Expected InterprocessEvent to have a Bundle constructor"); } } EventHandlerMethod method = new EventHandlerMethod(m, eventType); EventHandler handler = new EventHandler(sub, method, priority); eventTypeHandlers.add(handler); Loading @@ -793,8 +604,7 @@ public class EventBus extends BroadcastReceiver { if (DEBUG_TRACE_ALL) { logWithPid(" * Method: " + m.getName() + " event: " + parameterTypes[0].getSimpleName() + " interprocess? " + isInterprocessEvent.value); " event: " + parameterTypes[0].getSimpleName()); } } } Loading Loading @@ -830,12 +640,7 @@ public class EventBus extends BroadcastReceiver { final EventHandler eventHandler = eventHandlers.get(i); if (eventHandler.subscriber.getReference() != null) { if (event.requiresPost) { mHandler.post(new Runnable() { @Override public void run() { processEvent(eventHandler, event); } }); mHandler.post(() -> processEvent(eventHandler, event)); hasPostedEvent = true; } else { processEvent(eventHandler, event); Loading @@ -845,12 +650,7 @@ public class EventBus extends BroadcastReceiver { // Clean up after this event, deferring until all subscribers have been called if (hasPostedEvent) { mHandler.post(new Runnable() { @Override public void run() { event.onPostDispatch(); } }); mHandler.post(event::onPostDispatch); } else { event.onPostDispatch(); } Loading Loading @@ -897,29 +697,6 @@ public class EventBus extends BroadcastReceiver { } } /** * Re-registers the broadcast receiver for any new messages that we want to listen for. */ private void registerReceiverForInterprocessEvents(Context context) { if (DEBUG_TRACE_ALL) { logWithPid("registerReceiverForInterprocessEvents()"); } // Rebuild the receiver filter with the new interprocess events IntentFilter filter = new IntentFilter(); for (String eventName : mInterprocessEventNameMap.keySet()) { filter.addAction(eventName); if (DEBUG_TRACE_ALL) { logWithPid(" filter: " + eventName); } } // Re-register the receiver with the new filter if (mHasRegisteredReceiver) { context.unregisterReceiver(this); } context.registerReceiverAsUser(this, UserHandle.ALL, filter, PERMISSION_SELF, mHandler); mHasRegisteredReceiver = true; } /** * Returns whether this subscriber is currently registered. If {@param removeFoundSubscriber} * is true, then remove the subscriber before returning. Loading @@ -940,28 +717,19 @@ public class EventBus extends BroadcastReceiver { /** * @return whether {@param method} is a valid (normal or interprocess) event bus handler method */ private boolean isValidEventBusHandlerMethod(Method method, Class<?>[] parameterTypes, MutableBoolean isInterprocessEventOut) { private boolean isValidEventBusHandlerMethod(Method method, Class<?>[] parameterTypes) { int modifiers = method.getModifiers(); if (Modifier.isPublic(modifiers) && Modifier.isFinal(modifiers) && method.getReturnType().equals(Void.TYPE) && parameterTypes.length == 1) { if (EventBus.InterprocessEvent.class.isAssignableFrom(parameterTypes[0]) && method.getName().startsWith(INTERPROCESS_METHOD_PREFIX)) { isInterprocessEventOut.value = true; return true; } else if (EventBus.Event.class.isAssignableFrom(parameterTypes[0]) && if (EventBus.Event.class.isAssignableFrom(parameterTypes[0]) && method.getName().startsWith(METHOD_PREFIX)) { isInterprocessEventOut.value = false; return true; } else { if (DEBUG_TRACE_ALL) { if (!EventBus.Event.class.isAssignableFrom(parameterTypes[0])) { logWithPid(" Expected method take an Event-based parameter: " + method.getName()); } else if (!method.getName().startsWith(INTERPROCESS_METHOD_PREFIX) && !method.getName().startsWith(METHOD_PREFIX)) { logWithPid(" Expected method start with method prefix: " + method.getName()); } } } Loading