Home | History | Annotate | Download | only in incallui
      1 /*
      2  * Copyright (C) 2014 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.incallui;
     18 
     19 import com.google.common.base.Preconditions;
     20 
     21 import java.util.Collections;
     22 import java.util.Set;
     23 import java.util.concurrent.ConcurrentHashMap;
     24 
     25 /**
     26  * Class used by {@link InCallService.VideoCallCallback} to notify interested parties of incoming
     27  * events.
     28  */
     29 public class InCallVideoCallCallbackNotifier {
     30     /**
     31      * Singleton instance of this class.
     32      */
     33     private static InCallVideoCallCallbackNotifier sInstance =
     34             new InCallVideoCallCallbackNotifier();
     35 
     36     /**
     37      * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
     38      * load factor before resizing, 1 means we only expect a single thread to
     39      * access the map so make only a single shard
     40      */
     41     private final Set<SessionModificationListener> mSessionModificationListeners =
     42             Collections.newSetFromMap(new ConcurrentHashMap<SessionModificationListener, Boolean>
     43                     (8, 0.9f, 1));
     44     private final Set<VideoEventListener> mVideoEventListeners = Collections.newSetFromMap(
     45             new ConcurrentHashMap<VideoEventListener, Boolean>(8, 0.9f, 1));
     46     private final Set<SurfaceChangeListener> mSurfaceChangeListeners = Collections.newSetFromMap(
     47             new ConcurrentHashMap<SurfaceChangeListener, Boolean>(8, 0.9f, 1));
     48 
     49     /**
     50      * Static singleton accessor method.
     51      */
     52     public static InCallVideoCallCallbackNotifier getInstance() {
     53         return sInstance;
     54     }
     55 
     56     /**
     57      * Private constructor.  Instance should only be acquired through getInstance().
     58      */
     59     private InCallVideoCallCallbackNotifier() {
     60     }
     61 
     62     /**
     63      * Adds a new {@link SessionModificationListener}.
     64      *
     65      * @param listener The listener.
     66      */
     67     public void addSessionModificationListener(SessionModificationListener listener) {
     68         Preconditions.checkNotNull(listener);
     69         mSessionModificationListeners.add(listener);
     70     }
     71 
     72     /**
     73      * Remove a {@link SessionModificationListener}.
     74      *
     75      * @param listener The listener.
     76      */
     77     public void removeSessionModificationListener(SessionModificationListener listener) {
     78         if (listener != null) {
     79             mSessionModificationListeners.remove(listener);
     80         }
     81     }
     82 
     83     /**
     84      * Adds a new {@link VideoEventListener}.
     85      *
     86      * @param listener The listener.
     87      */
     88     public void addVideoEventListener(VideoEventListener listener) {
     89         Preconditions.checkNotNull(listener);
     90         mVideoEventListeners.add(listener);
     91     }
     92 
     93     /**
     94      * Remove a {@link VideoEventListener}.
     95      *
     96      * @param listener The listener.
     97      */
     98     public void removeVideoEventListener(VideoEventListener listener) {
     99         if (listener != null) {
    100             mVideoEventListeners.remove(listener);
    101         }
    102     }
    103 
    104     /**
    105      * Adds a new {@link SurfaceChangeListener}.
    106      *
    107      * @param listener The listener.
    108      */
    109     public void addSurfaceChangeListener(SurfaceChangeListener listener) {
    110         Preconditions.checkNotNull(listener);
    111         mSurfaceChangeListeners.add(listener);
    112     }
    113 
    114     /**
    115      * Remove a {@link SurfaceChangeListener}.
    116      *
    117      * @param listener The listener.
    118      */
    119     public void removeSurfaceChangeListener(SurfaceChangeListener listener) {
    120         if (listener != null) {
    121             mSurfaceChangeListeners.remove(listener);
    122         }
    123     }
    124 
    125     /**
    126      * Inform listeners of an upgrade to video request for a call.
    127      * @param call The call.
    128      * @param videoState The video state we want to upgrade to.
    129      */
    130     public void upgradeToVideoRequest(Call call, int videoState) {
    131         Log.d(this, "upgradeToVideoRequest call = " + call + " new video state = " + videoState);
    132         for (SessionModificationListener listener : mSessionModificationListeners) {
    133             listener.onUpgradeToVideoRequest(call, videoState);
    134         }
    135     }
    136 
    137     /**
    138      * Inform listeners of a successful response to a video request for a call.
    139      *
    140      * @param call The call.
    141      */
    142     public void upgradeToVideoSuccess(Call call) {
    143         for (SessionModificationListener listener : mSessionModificationListeners) {
    144             listener.onUpgradeToVideoSuccess(call);
    145         }
    146     }
    147 
    148     /**
    149      * Inform listeners of an unsuccessful response to a video request for a call.
    150      *
    151      * @param call The call.
    152      */
    153     public void upgradeToVideoFail(int status, Call call) {
    154         for (SessionModificationListener listener : mSessionModificationListeners) {
    155             listener.onUpgradeToVideoFail(status, call);
    156         }
    157     }
    158 
    159     /**
    160      * Inform listeners of a downgrade to audio.
    161      *
    162      * @param call The call.
    163      */
    164     public void downgradeToAudio(Call call) {
    165         for (SessionModificationListener listener : mSessionModificationListeners) {
    166             listener.onDowngradeToAudio(call);
    167         }
    168     }
    169 
    170     /**
    171      * Inform listeners of a call session event.
    172      *
    173      * @param event The call session event.
    174      */
    175     public void callSessionEvent(int event) {
    176         for (VideoEventListener listener : mVideoEventListeners) {
    177             listener.onCallSessionEvent(event);
    178         }
    179     }
    180 
    181     /**
    182      * Inform listeners of a downgrade to audio.
    183      *
    184      * @param call The call.
    185      * @param paused The paused state.
    186      */
    187     public void peerPausedStateChanged(Call call, boolean paused) {
    188         for (VideoEventListener listener : mVideoEventListeners) {
    189             listener.onPeerPauseStateChanged(call, paused);
    190         }
    191     }
    192 
    193     /**
    194      * Inform listeners of any change in the video quality of the call
    195      *
    196      * @param call The call.
    197      * @param videoQuality The updated video quality of the call.
    198      */
    199     public void videoQualityChanged(Call call, int videoQuality) {
    200         for (VideoEventListener listener : mVideoEventListeners) {
    201             listener.onVideoQualityChanged(call, videoQuality);
    202         }
    203     }
    204 
    205     /**
    206      * Inform listeners of a change to peer dimensions.
    207      *
    208      * @param call The call.
    209      * @param width New peer width.
    210      * @param height New peer height.
    211      */
    212     public void peerDimensionsChanged(Call call, int width, int height) {
    213         for (SurfaceChangeListener listener : mSurfaceChangeListeners) {
    214             listener.onUpdatePeerDimensions(call, width, height);
    215         }
    216     }
    217 
    218     /**
    219      * Inform listeners of a change to camera dimensions.
    220      *
    221      * @param call The call.
    222      * @param width The new camera video width.
    223      * @param height The new camera video height.
    224      */
    225     public void cameraDimensionsChanged(Call call, int width, int height) {
    226         for (SurfaceChangeListener listener : mSurfaceChangeListeners) {
    227             listener.onCameraDimensionsChange(call, width, height);
    228         }
    229     }
    230 
    231     /**
    232      * Inform listeners of a change to call data usage.
    233      *
    234      * @param dataUsage data usage value
    235      */
    236     public void callDataUsageChanged(long dataUsage) {
    237         for (VideoEventListener listener : mVideoEventListeners) {
    238             listener.onCallDataUsageChange(dataUsage);
    239         }
    240     }
    241 
    242     /**
    243      * Listener interface for any class that wants to be notified of upgrade to video and downgrade
    244      * to audio session modification requests.
    245      */
    246     public interface SessionModificationListener {
    247         /**
    248          * Called when a peer request is received to upgrade an audio-only call to a video call.
    249          *
    250          * @param call The call the request was received for.
    251          * @param videoState The video state that the request wants to upgrade to.
    252          */
    253         public void onUpgradeToVideoRequest(Call call, int videoState);
    254 
    255         /**
    256          * Called when a request to a peer to upgrade an audio-only call to a video call is
    257          * successful.
    258          *
    259          * @param call The call the request was successful for.
    260          */
    261         public void onUpgradeToVideoSuccess(Call call);
    262 
    263         /**
    264          * Called when a request to a peer to upgrade an audio-only call to a video call is
    265          * NOT successful. This can be if the peer chooses rejects the the video call, or if the
    266          * peer does not support video calling, or if there is some error in sending the request.
    267          *
    268          * @param call The call the request was successful for.
    269          */
    270         public void onUpgradeToVideoFail(int status, Call call);
    271 
    272         /**
    273          * Called when a call has been downgraded to audio-only.
    274          *
    275          * @param call The call which was downgraded to audio-only.
    276          */
    277         public void onDowngradeToAudio(Call call);
    278     }
    279 
    280     /**
    281      * Listener interface for any class that wants to be notified of video events, including pause
    282      * and un-pause of peer video, video quality changes.
    283      */
    284     public interface VideoEventListener {
    285         /**
    286          * Called when the peer pauses or un-pauses video transmission.
    287          *
    288          * @param call   The call which paused or un-paused video transmission.
    289          * @param paused {@code True} when the video transmission is paused, {@code false}
    290          *               otherwise.
    291          */
    292         public void onPeerPauseStateChanged(Call call, boolean paused);
    293 
    294         /**
    295          * Called when the video quality changes.
    296          *
    297          * @param call   The call whose video quality changes.
    298          * @param videoCallQuality - values are QUALITY_HIGH, MEDIUM, LOW and UNKNOWN.
    299          */
    300         public void onVideoQualityChanged(Call call, int videoCallQuality);
    301 
    302         /*
    303          * Called when call data usage value is requested or when call data usage value is updated
    304          * because of a call state change
    305          *
    306          * @param dataUsage call data usage value
    307          */
    308         public void onCallDataUsageChange(long dataUsage);
    309 
    310         /**
    311          * Called when call session event is raised.
    312          *
    313          * @param event The call session event.
    314          */
    315         public void onCallSessionEvent(int event);
    316     }
    317 
    318     /**
    319      * Listener interface for any class that wants to be notified of changes to the video surfaces.
    320      */
    321     public interface SurfaceChangeListener {
    322         /**
    323          * Called when the peer video feed changes dimensions. This can occur when the peer rotates
    324          * their device, changing the aspect ratio of the video signal.
    325          *
    326          * @param call The call which experienced a peer video
    327          * @param width
    328          * @param height
    329          */
    330         public void onUpdatePeerDimensions(Call call, int width, int height);
    331 
    332         /**
    333          * Called when the local camera changes dimensions.  This occurs when a change in camera
    334          * occurs.
    335          *
    336          * @param call The call which experienced the camera dimension change.
    337          * @param width The new camera video width.
    338          * @param height The new camera video height.
    339          */
    340         public void onCameraDimensionsChange(Call call, int width, int height);
    341     }
    342 }
    343