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 call session event.
    139      *
    140      * @param event The call session event.
    141      */
    142     public void callSessionEvent(int event) {
    143         for (VideoEventListener listener : mVideoEventListeners) {
    144             listener.onCallSessionEvent(event);
    145         }
    146     }
    147 
    148     /**
    149      * Inform listeners of a downgrade to audio.
    150      *
    151      * @param call The call.
    152      * @param paused The paused state.
    153      */
    154     public void peerPausedStateChanged(Call call, boolean paused) {
    155         for (VideoEventListener listener : mVideoEventListeners) {
    156             listener.onPeerPauseStateChanged(call, paused);
    157         }
    158     }
    159 
    160     /**
    161      * Inform listeners of any change in the video quality of the call
    162      *
    163      * @param call The call.
    164      * @param videoQuality The updated video quality of the call.
    165      */
    166     public void videoQualityChanged(Call call, int videoQuality) {
    167         for (VideoEventListener listener : mVideoEventListeners) {
    168             listener.onVideoQualityChanged(call, videoQuality);
    169         }
    170     }
    171 
    172     /**
    173      * Inform listeners of a change to peer dimensions.
    174      *
    175      * @param call The call.
    176      * @param width New peer width.
    177      * @param height New peer height.
    178      */
    179     public void peerDimensionsChanged(Call call, int width, int height) {
    180         for (SurfaceChangeListener listener : mSurfaceChangeListeners) {
    181             listener.onUpdatePeerDimensions(call, width, height);
    182         }
    183     }
    184 
    185     /**
    186      * Inform listeners of a change to camera dimensions.
    187      *
    188      * @param call The call.
    189      * @param width The new camera video width.
    190      * @param height The new camera video height.
    191      */
    192     public void cameraDimensionsChanged(Call call, int width, int height) {
    193         for (SurfaceChangeListener listener : mSurfaceChangeListeners) {
    194             listener.onCameraDimensionsChange(call, width, height);
    195         }
    196     }
    197 
    198     /**
    199      * Inform listeners of a change to call data usage.
    200      *
    201      * @param dataUsage data usage value
    202      */
    203     public void callDataUsageChanged(long dataUsage) {
    204         for (VideoEventListener listener : mVideoEventListeners) {
    205             listener.onCallDataUsageChange(dataUsage);
    206         }
    207     }
    208 
    209     /**
    210      * Listener interface for any class that wants to be notified of upgrade to video request.
    211      */
    212     public interface SessionModificationListener {
    213         /**
    214          * Called when a peer request is received to upgrade an audio-only call to a video call.
    215          *
    216          * @param call The call the request was received for.
    217          * @param videoState The requested video state.
    218          */
    219         public void onUpgradeToVideoRequest(Call call, int videoState);
    220     }
    221 
    222     /**
    223      * Listener interface for any class that wants to be notified of video events, including pause
    224      * and un-pause of peer video, video quality changes.
    225      */
    226     public interface VideoEventListener {
    227         /**
    228          * Called when the peer pauses or un-pauses video transmission.
    229          *
    230          * @param call   The call which paused or un-paused video transmission.
    231          * @param paused {@code True} when the video transmission is paused, {@code false}
    232          *               otherwise.
    233          */
    234         public void onPeerPauseStateChanged(Call call, boolean paused);
    235 
    236         /**
    237          * Called when the video quality changes.
    238          *
    239          * @param call   The call whose video quality changes.
    240          * @param videoCallQuality - values are QUALITY_HIGH, MEDIUM, LOW and UNKNOWN.
    241          */
    242         public void onVideoQualityChanged(Call call, int videoCallQuality);
    243 
    244         /*
    245          * Called when call data usage value is requested or when call data usage value is updated
    246          * because of a call state change
    247          *
    248          * @param dataUsage call data usage value
    249          */
    250         public void onCallDataUsageChange(long dataUsage);
    251 
    252         /**
    253          * Called when call session event is raised.
    254          *
    255          * @param event The call session event.
    256          */
    257         public void onCallSessionEvent(int event);
    258     }
    259 
    260     /**
    261      * Listener interface for any class that wants to be notified of changes to the video surfaces.
    262      */
    263     public interface SurfaceChangeListener {
    264         /**
    265          * Called when the peer video feed changes dimensions. This can occur when the peer rotates
    266          * their device, changing the aspect ratio of the video signal.
    267          *
    268          * @param call The call which experienced a peer video
    269          * @param width
    270          * @param height
    271          */
    272         public void onUpdatePeerDimensions(Call call, int width, int height);
    273 
    274         /**
    275          * Called when the local camera changes dimensions.  This occurs when a change in camera
    276          * occurs.
    277          *
    278          * @param call The call which experienced the camera dimension change.
    279          * @param width The new camera video width.
    280          * @param height The new camera video height.
    281          */
    282         public void onCameraDimensionsChange(Call call, int width, int height);
    283     }
    284 }
    285