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