1 /* 2 * Copyright (C) 2016 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.dialer.enrichedcall; 18 19 import android.support.annotation.IntDef; 20 import android.support.annotation.MainThread; 21 import android.support.annotation.NonNull; 22 import android.support.annotation.Nullable; 23 import com.android.dialer.calldetails.CallDetailsEntries; 24 import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; 25 import com.android.dialer.enrichedcall.historyquery.proto.HistoryResult; 26 import com.android.dialer.enrichedcall.videoshare.VideoShareListener; 27 import com.android.dialer.multimedia.MultimediaData; 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 import java.util.List; 31 import java.util.Map; 32 33 /** Performs all enriched calling logic. */ 34 public interface EnrichedCallManager { 35 36 int POST_CALL_NOTE_MAX_CHAR = 60; 37 38 /** Receives updates when enriched call capabilities are ready. */ 39 interface CapabilitiesListener { 40 41 /** Callback fired when the capabilities are updated. */ 42 @MainThread onCapabilitiesUpdated()43 void onCapabilitiesUpdated(); 44 } 45 46 /** 47 * Registers the given {@link CapabilitiesListener}. 48 * 49 * <p>As a result of this method, the listener will receive a call to {@link 50 * CapabilitiesListener#onCapabilitiesUpdated()} after a call to {@link 51 * #requestCapabilities(String)}. 52 */ 53 @MainThread registerCapabilitiesListener(@onNull CapabilitiesListener listener)54 void registerCapabilitiesListener(@NonNull CapabilitiesListener listener); 55 56 /** 57 * Starts an asynchronous process to get enriched call capabilities of the given number. 58 * 59 * <p>Registered listeners will receive a call to {@link 60 * CapabilitiesListener#onCapabilitiesUpdated()} on completion. 61 * 62 * @param number the remote number in any format 63 */ 64 @MainThread requestCapabilities(@onNull String number)65 void requestCapabilities(@NonNull String number); 66 67 /** 68 * Unregisters the given {@link CapabilitiesListener}. 69 * 70 * <p>As a result of this method, the listener will not receive capabilities of the given number. 71 */ 72 @MainThread unregisterCapabilitiesListener(@onNull CapabilitiesListener listener)73 void unregisterCapabilitiesListener(@NonNull CapabilitiesListener listener); 74 75 /** Gets the cached capabilities for the given number, else null */ 76 @MainThread 77 @Nullable getCapabilities(@onNull String number)78 EnrichedCallCapabilities getCapabilities(@NonNull String number); 79 80 /** Clears any cached data, such as capabilities. */ 81 @MainThread clearCachedData()82 void clearCachedData(); 83 84 /** Possible states for call composer sessions. */ 85 @Retention(RetentionPolicy.SOURCE) 86 @IntDef({ 87 STATE_NONE, 88 STATE_STARTING, 89 STATE_STARTED, 90 STATE_START_FAILED, 91 STATE_MESSAGE_SENT, 92 STATE_MESSAGE_FAILED, 93 STATE_CLOSED, 94 }) 95 @interface State {} 96 97 int STATE_NONE = 0; 98 int STATE_STARTING = STATE_NONE + 1; 99 int STATE_STARTED = STATE_STARTING + 1; 100 int STATE_START_FAILED = STATE_STARTED + 1; 101 int STATE_MESSAGE_SENT = STATE_START_FAILED + 1; 102 int STATE_MESSAGE_FAILED = STATE_MESSAGE_SENT + 1; 103 int STATE_CLOSED = STATE_MESSAGE_FAILED + 1; 104 105 /** 106 * Starts a call composer session with the given remote number. 107 * 108 * @param number the remote number in any format 109 * @return the id for the started session, or {@link Session#NO_SESSION_ID} if the session fails 110 */ 111 @MainThread startCallComposerSession(@onNull String number)112 long startCallComposerSession(@NonNull String number); 113 114 /** 115 * Sends the given information through an open enriched call session. As per the enriched calling 116 * spec, up to two messages are sent: the first is an enriched call data message that optionally 117 * includes the subject and the second is the optional image data message. 118 * 119 * @param sessionId the id for the session. See {@link #startCallComposerSession(String)} 120 * @param data the {@link MultimediaData} 121 * @throws IllegalArgumentException if there's no open session with the given number 122 * @throws IllegalStateException if the session isn't in the {@link #STATE_STARTED} state 123 */ 124 @MainThread sendCallComposerData(long sessionId, @NonNull MultimediaData data)125 void sendCallComposerData(long sessionId, @NonNull MultimediaData data); 126 127 /** 128 * Ends the given call composer session. Ending a session means that the call composer session 129 * will be closed. 130 * 131 * @param sessionId the id of the session to end 132 */ 133 @MainThread endCallComposerSession(long sessionId)134 void endCallComposerSession(long sessionId); 135 136 /** 137 * Sends a post call note to the given number. 138 * 139 * @throws IllegalArgumentException if message is longer than {@link #POST_CALL_NOTE_MAX_CHAR} 140 * characters 141 */ 142 @MainThread sendPostCallNote(@onNull String number, @NonNull String message)143 void sendPostCallNote(@NonNull String number, @NonNull String message); 144 145 /** 146 * Called once the capabilities are available for a corresponding call to {@link 147 * #requestCapabilities(String)}. 148 * 149 * @param number the remote number in any format 150 * @param capabilities the supported capabilities 151 */ 152 @MainThread onCapabilitiesReceived( @onNull String number, @NonNull EnrichedCallCapabilities capabilities)153 void onCapabilitiesReceived( 154 @NonNull String number, @NonNull EnrichedCallCapabilities capabilities); 155 156 /** Receives updates when the state of an enriched call changes. */ 157 interface StateChangedListener { 158 159 /** 160 * Callback fired when state changes. Listeners should call {@link #getSession(long)} or {@link 161 * #getSession(String, String, Filter)} to retrieve the new state. 162 */ onEnrichedCallStateChanged()163 void onEnrichedCallStateChanged(); 164 } 165 166 /** 167 * Registers the given {@link StateChangedListener}. 168 * 169 * <p>As a result of this method, the listener will receive updates when the state of any enriched 170 * call changes. 171 */ 172 @MainThread registerStateChangedListener(@onNull StateChangedListener listener)173 void registerStateChangedListener(@NonNull StateChangedListener listener); 174 175 /** 176 * Returns the {@link Session} for the given unique call id, falling back to the number. If a 177 * filter is provided, it will be applied to both the uniqueCalId and number lookups. 178 */ 179 @MainThread 180 @Nullable getSession(@onNull String uniqueCallId, @NonNull String number, @Nullable Filter filter)181 Session getSession(@NonNull String uniqueCallId, @NonNull String number, @Nullable Filter filter); 182 183 /** Returns the {@link Session} for the given sessionId, or {@code null} if no session exists. */ 184 @MainThread 185 @Nullable getSession(long sessionId)186 Session getSession(long sessionId); 187 188 @NonNull createIncomingCallComposerFilter()189 Filter createIncomingCallComposerFilter(); 190 191 @NonNull createOutgoingCallComposerFilter()192 Filter createOutgoingCallComposerFilter(); 193 194 /** 195 * Starts an asynchronous process to get all historical data for the given number and set of 196 * {@link CallDetailsEntries}. 197 */ 198 @MainThread requestAllHistoricalData(@onNull String number, @NonNull CallDetailsEntries entries)199 void requestAllHistoricalData(@NonNull String number, @NonNull CallDetailsEntries entries); 200 201 /** 202 * Returns a mapping of enriched call data for all of the given {@link CallDetailsEntries}, which 203 * should not be modified. A {@code null} return indicates that clients should call {@link 204 * #requestAllHistoricalData(String, CallDetailsEntries)}. 205 * 206 * <p>The mapping is created by finding the HistoryResults whose timestamps occurred during or 207 * close after a CallDetailsEntry. A CallDetailsEntry can have multiple HistoryResults in the 208 * event that both a CallComposer message and PostCall message were sent for the same call. 209 */ 210 @Nullable 211 @MainThread getAllHistoricalData( @onNull String number, @NonNull CallDetailsEntries entries)212 Map<CallDetailsEntry, List<HistoryResult>> getAllHistoricalData( 213 @NonNull String number, @NonNull CallDetailsEntries entries); 214 215 /** 216 * Unregisters the given {@link StateChangedListener}. 217 * 218 * <p>As a result of this method, the listener will not receive updates when the state of enriched 219 * calls changes. 220 */ 221 @MainThread unregisterStateChangedListener(@onNull StateChangedListener listener)222 void unregisterStateChangedListener(@NonNull StateChangedListener listener); 223 224 /** 225 * Called when the status of an enriched call session changes. 226 * 227 * 228 * @throws IllegalArgumentException if the state is invalid 229 */ 230 @MainThread onSessionStatusUpdate(long sessionId, @NonNull String number, int state)231 void onSessionStatusUpdate(long sessionId, @NonNull String number, int state); 232 233 /** 234 * Called when the status of an enriched call message updates. 235 * 236 * 237 * @throws IllegalArgumentException if the state is invalid 238 * @throws IllegalStateException if there's no session for the given id 239 */ 240 @MainThread onMessageUpdate(long sessionId, @NonNull String messageId, int state)241 void onMessageUpdate(long sessionId, @NonNull String messageId, int state); 242 243 /** 244 * Called when call composer data arrives for the given session. 245 * 246 * @throws IllegalStateException if there's no session for the given id 247 */ 248 @MainThread onIncomingCallComposerData(long sessionId, @NonNull MultimediaData multimediaData)249 void onIncomingCallComposerData(long sessionId, @NonNull MultimediaData multimediaData); 250 251 /** 252 * Called when post call data arrives for the given session. 253 * 254 * @throws IllegalStateException if there's no session for the given id 255 */ 256 @MainThread onIncomingPostCallData(long sessionId, @NonNull MultimediaData multimediaData)257 void onIncomingPostCallData(long sessionId, @NonNull MultimediaData multimediaData); 258 259 /** 260 * Registers the given {@link VideoShareListener}. 261 * 262 * <p>As a result of this method, the listener will receive updates when any video share state 263 * changes. 264 */ 265 @MainThread registerVideoShareListener(@onNull VideoShareListener listener)266 void registerVideoShareListener(@NonNull VideoShareListener listener); 267 268 /** 269 * Unregisters the given {@link VideoShareListener}. 270 * 271 * <p>As a result of this method, the listener will not receive updates when any video share state 272 * changes. 273 */ 274 @MainThread unregisterVideoShareListener(@onNull VideoShareListener listener)275 void unregisterVideoShareListener(@NonNull VideoShareListener listener); 276 277 /** 278 * Called when an incoming video share invite is received. 279 * 280 * @return whether or not the invite was accepted by the manager (rejected when disabled) 281 */ 282 @MainThread onIncomingVideoShareInvite(long sessionId, @NonNull String number)283 boolean onIncomingVideoShareInvite(long sessionId, @NonNull String number); 284 285 /** 286 * Starts a video share session with the given remote number. 287 * 288 * @param number the remote number in any format 289 * @return the id for the started session, or {@link Session#NO_SESSION_ID} if the session fails 290 */ 291 @MainThread startVideoShareSession(@onNull String number)292 long startVideoShareSession(@NonNull String number); 293 294 /** 295 * Accepts a video share session invite. 296 * 297 * @param sessionId the session to accept 298 * @return whether or not accepting the session succeeded 299 */ 300 @MainThread acceptVideoShareSession(long sessionId)301 boolean acceptVideoShareSession(long sessionId); 302 303 /** 304 * Retrieve the session id for an incoming video share invite. 305 * 306 * @param number the remote number in any format 307 * @return the id for the session invite, or {@link Session#NO_SESSION_ID} if there is no invite 308 */ 309 @MainThread getVideoShareInviteSessionId(@onNull String number)310 long getVideoShareInviteSessionId(@NonNull String number); 311 312 /** 313 * Ends the given video share session. 314 * 315 * @param sessionId the id of the session to end 316 */ 317 @MainThread endVideoShareSession(long sessionId)318 void endVideoShareSession(long sessionId); 319 320 /** Interface for filtering sessions (compatible with Predicate from Java 8) */ 321 interface Filter { test(Session session)322 boolean test(Session session); 323 } 324 } 325