1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.util.concurrency; 18 19 /** 20 * Allows triggering methods based on a passed in id or message, generally on another thread. 21 * 22 * Messages sent on to this router must be processed in order. That is to say, if three 23 * messages are sent with no delay, they must be processed in the order they were sent. Moreover, 24 * if messages are sent with various delays, they must be processed in order of their delay. 25 * 26 * Messages can be passed by either a simple integer or an instance of a class. Unique integers are 27 * considered unique messages. Unique message classes (not instances) are considered unique 28 * messages. You can use message classes to pass extra data for processing to subscribers. 29 * 30 * <pre> 31 * // Three messages with three unique integer messages. 32 * // They can be subscribed to independently. 33 * router.sendMessage(0); 34 * router.sendMessage(1); 35 * router.sendMessage(2); 36 * 37 * // Three messages with two unique message classes. 38 * // The first and third messages will be delivered to the same subscribers. 39 * router.sendMessage(new Foo(0)); 40 * router.sendMessage(new Bar(1)); 41 * router.sendMessage(new Foo(2)); 42 * </pre> 43 * 44 * The number of unique ids and message types used should be relatively constrained. Construct 45 * a custom message-class and put unique, per-message data inside of it. 46 */ 47 public interface MessageRouter { 48 /** 49 * Alerts any listeners subscribed to the passed in id. 50 * 51 * The number of unique ids used should be relatively constrained - used to identify the type 52 * of message being sent. If unique information needs to be passed with each call, use 53 * {@link #sendMessage(Object)}. 54 * 55 * @param id An identifier for the message 56 */ sendMessage(int id)57 default void sendMessage(int id) { 58 sendMessageDelayed(id, 0); 59 } 60 61 /** 62 * Alerts any listeners subscribed to the passed in message. 63 * 64 * The number of message types used should be relatively constrained. If no unique information 65 * needs to be passed in, you can simply use {@link #sendMessage(int)}} which takes an integer 66 * instead of a unique class type. 67 * 68 * The class of the passed in object will be used to router the message. 69 * 70 * @param data A message containing extra data for processing. 71 */ sendMessage(Object data)72 default void sendMessage(Object data) { 73 sendMessageDelayed(data, 0); 74 } 75 76 /** 77 * Alerts any listeners subscribed to the passed in id in the future. 78 * 79 * The number of unique ids used should be relatively constrained - used to identify the type 80 * of message being sent. If unique information needs to be passed with each call, use 81 * {@link #sendMessageDelayed(Object, long)}. 82 * 83 * @param id An identifier for the message 84 * @param delayMs Number of milliseconds to wait before alerting. 85 */ sendMessageDelayed(int id, long delayMs)86 void sendMessageDelayed(int id, long delayMs); 87 88 89 /** 90 * Alerts any listeners subscribed to the passed in message in the future. 91 * 92 * The number of message types used should be relatively constrained. If no unique information 93 * needs to be passed in, you can simply use {@link #sendMessageDelayed(int, long)} which takes 94 * an integer instead of a unique class type. 95 * 96 * @param data A message containing extra data for processing. 97 * @param delayMs Number of milliseconds to wait before alerting. 98 */ sendMessageDelayed(Object data, long delayMs)99 void sendMessageDelayed(Object data, long delayMs); 100 101 /** 102 * Cancel all unprocessed messages for a given id. 103 * 104 * If a message has multiple listeners and one of those listeners has been alerted, the other 105 * listeners that follow it may also be alerted. This is only guaranteed to cancel messages 106 * that are still queued. 107 * 108 * @param id The message id to cancel. 109 */ cancelMessages(int id)110 void cancelMessages(int id); 111 112 /** 113 * Cancel all unprocessed messages for a given message type. 114 * 115 * If a message has multiple listeners and one of those listeners has been alerted, the other 116 * listeners that follow it may also be alerted. This is only guaranteed to cancel messages 117 * that are still queued. 118 * 119 * @param messageType The class of the message to cancel 120 */ cancelMessages(Class<T> messageType)121 <T> void cancelMessages(Class<T> messageType); 122 123 /** 124 * Add a listener for a message that does not handle any extra data. 125 * 126 * See also {@link #subscribeTo(Class, DataMessageListener)}. 127 * 128 * @param id The message id to listener for. 129 * @param listener 130 */ subscribeTo(int id, SimpleMessageListener listener)131 void subscribeTo(int id, SimpleMessageListener listener); 132 133 /** 134 * Add a listener for a message of a specific type. 135 * 136 * See also {@link #subscribeTo(Class, DataMessageListener)}. 137 * 138 * @param messageType The class of message to listen for. 139 * @param listener 140 */ subscribeTo(Class<T> messageType, DataMessageListener<T> listener)141 <T> void subscribeTo(Class<T> messageType, DataMessageListener<T> listener); 142 143 /** 144 * Remove a listener for a specific message. 145 * 146 * See also {@link #unsubscribeFrom(Class, DataMessageListener)} 147 * 148 * @param id The message id to stop listening for. 149 * @param listener The listener to remove. 150 */ unsubscribeFrom(int id, SimpleMessageListener listener)151 void unsubscribeFrom(int id, SimpleMessageListener listener); 152 153 /** 154 * Remove a listener for a specific message. 155 * 156 * See also {@link #unsubscribeFrom(int, SimpleMessageListener)}. 157 * 158 * @param messageType The class of message to stop listening for. 159 * @param listener The listener to remove. 160 */ unsubscribeFrom(Class<T> messageType, DataMessageListener<T> listener)161 <T> void unsubscribeFrom(Class<T> messageType, DataMessageListener<T> listener); 162 163 /** 164 * Remove a listener for all messages that it is subscribed to. 165 * 166 * See also {@link #unsubscribeFrom(DataMessageListener)}. 167 * 168 * @param listener The listener to remove. 169 */ unsubscribeFrom(SimpleMessageListener listener)170 void unsubscribeFrom(SimpleMessageListener listener); 171 172 /** 173 * Remove a listener for all messages that it is subscribed to. 174 * 175 * See also {@link #unsubscribeFrom(SimpleMessageListener)}. 176 * 177 * @param listener The listener to remove. 178 */ unsubscribeFrom(DataMessageListener<T> listener)179 <T> void unsubscribeFrom(DataMessageListener<T> listener); 180 181 /** 182 * A Listener interface for when no extra data is expected or desired. 183 */ 184 interface SimpleMessageListener { 185 /** */ onMessage(int id)186 void onMessage(int id); 187 } 188 189 /** 190 * A Listener interface for when extra data is expected or desired. 191 * 192 * @param <T> 193 */ 194 interface DataMessageListener<T> { 195 /** */ onMessage(T data)196 void onMessage(T data); 197 } 198 } 199