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.VideoCallListener} to notify interested parties of incoming
     27  * events.
     28  */
     29 public class InCallVideoCallListenerNotifier {
     30     /**
     31      * Singleton instance of this class.
     32      */
     33     private static InCallVideoCallListenerNotifier sInstance = new InCallVideoCallListenerNotifier();
     34 
     35     /**
     36      * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
     37      * load factor before resizing, 1 means we only expect a single thread to
     38      * access the map so make only a single shard
     39      */
     40     private final Set<SessionModificationListener> mSessionModificationListeners =
     41             Collections.newSetFromMap(new ConcurrentHashMap<SessionModificationListener, Boolean>
     42                     (8, 0.9f, 1));
     43     private final Set<VideoEventListener> mVideoEventListeners = Collections.newSetFromMap(
     44             new ConcurrentHashMap<VideoEventListener, Boolean>(8, 0.9f, 1));
     45     private final Set<SurfaceChangeListener> mSurfaceChangeListeners = Collections.newSetFromMap(
     46             new ConcurrentHashMap<SurfaceChangeListener, Boolean>(8, 0.9f, 1));
     47 
     48     /**
     49      * Static singleton accessor method.
     50      */
     51     public static InCallVideoCallListenerNotifier getInstance() {
     52         return sInstance;
     53     }
     54 
     55     /**
     56      * Private constructor.  Instance should only be acquired through getInstance().
     57      */
     58     private InCallVideoCallListenerNotifier() {
     59     }
     60 
     61     /**
     62      * Adds a new {@link SessionModificationListener}.
     63      *
     64      * @param listener The listener.
     65      */
     66     public void addSessionModificationListener(SessionModificationListener listener) {
     67         Preconditions.checkNotNull(listener);
     68         mSessionModificationListeners.add(listener);
     69     }
     70 
     71     /**
     72      * Remove a {@link SessionModificationListener}.
     73      *
     74      * @param listener The listener.
     75      */
     76     public void removeSessionModificationListener(SessionModificationListener listener) {
     77         if (listener != null) {
     78             mSessionModificationListeners.remove(listener);
     79         }
     80     }
     81 
     82     /**
     83      * Adds a new {@link VideoEventListener}.
     84      *
     85      * @param listener The listener.
     86      */
     87     public void addVideoEventListener(VideoEventListener listener) {
     88         Preconditions.checkNotNull(listener);
     89         mVideoEventListeners.add(listener);
     90     }
     91 
     92     /**
     93      * Remove a {@link VideoEventListener}.
     94      *
     95      * @param listener The listener.
     96      */
     97     public void removeVideoEventListener(VideoEventListener listener) {
     98         if (listener != null) {
     99             mVideoEventListeners.remove(listener);
    100         }
    101     }
    102 
    103     /**
    104      * Adds a new {@link SurfaceChangeListener}.
    105      *
    106      * @param listener The listener.
    107      */
    108     public void addSurfaceChangeListener(SurfaceChangeListener listener) {
    109         Preconditions.checkNotNull(listener);
    110         mSurfaceChangeListeners.add(listener);
    111     }
    112 
    113     /**
    114      * Remove a {@link SurfaceChangeListener}.
    115      *
    116      * @param listener The listener.
    117      */
    118     public void removeSurfaceChangeListener(SurfaceChangeListener listener) {
    119         if (listener != null) {
    120             mSurfaceChangeListeners.remove(listener);
    121         }
    122     }
    123 
    124     /**
    125      * Inform listeners of an upgrade to video request for a call.
    126      *
    127      * @param call The call.
    128      */
    129     public void upgradeToVideoRequest(Call call) {
    130         for (SessionModificationListener listener : mSessionModificationListeners) {
    131             listener.onUpgradeToVideoRequest(call);
    132         }
    133     }
    134 
    135     /**
    136      * Inform listeners of a successful response to a video request for a call.
    137      *
    138      * @param call The call.
    139      */
    140     public void upgradeToVideoSuccess(Call call) {
    141         for (SessionModificationListener listener : mSessionModificationListeners) {
    142             listener.onUpgradeToVideoSuccess(call);
    143         }
    144     }
    145 
    146     /**
    147      * Inform listeners of an unsuccessful response to a video request for a call.
    148      *
    149      * @param call The call.
    150      */
    151     public void upgradeToVideoFail(Call call) {
    152         for (SessionModificationListener listener : mSessionModificationListeners) {
    153             listener.onUpgradeToVideoFail(call);
    154         }
    155     }
    156 
    157     /**
    158      * Inform listeners of a downgrade to audio.
    159      *
    160      * @param call The call.
    161      */
    162     public void downgradeToAudio(Call call) {
    163         for (SessionModificationListener listener : mSessionModificationListeners) {
    164             listener.onDowngradeToAudio(call);
    165         }
    166     }
    167 
    168     /**
    169      * Inform listeners of a downgrade to audio.
    170      *
    171      * @param call The call.
    172      * @param paused The paused state.
    173      */
    174     public void peerPausedStateChanged(Call call, boolean paused) {
    175         for (VideoEventListener listener : mVideoEventListeners) {
    176             listener.onPeerPauseStateChanged(call, paused);
    177         }
    178     }
    179 
    180     /**
    181      * Inform listeners of a change to peer dimensions.
    182      *
    183      * @param call The call.
    184      * @param width New peer width.
    185      * @param height New peer height.
    186      */
    187     public void peerDimensionsChanged(Call call, int width, int height) {
    188         for (SurfaceChangeListener listener : mSurfaceChangeListeners) {
    189             listener.onUpdatePeerDimensions(call, width, height);
    190         }
    191     }
    192 
    193     /**
    194      * Inform listeners of a change to camera dimensions.
    195      *
    196      * @param call The call.
    197      * @param width The new camera video width.
    198      * @param height The new camera video height.
    199      */
    200     public void cameraDimensionsChanged(Call call, int width, int height) {
    201         for (SurfaceChangeListener listener : mSurfaceChangeListeners) {
    202             listener.onCameraDimensionsChange(call, width, height);
    203         }
    204     }
    205 
    206     /**
    207      * Listener interface for any class that wants to be notified of upgrade to video and downgrade
    208      * to audio session modification requests.
    209      */
    210     public interface SessionModificationListener {
    211         /**
    212          * Called when a peer request is received to upgrade an audio-only call to a video call.
    213          *
    214          * @param call The call the request was received for.
    215          */
    216         public void onUpgradeToVideoRequest(Call call);
    217 
    218         /**
    219          * Called when a request to a peer to upgrade an audio-only call to a video call is
    220          * successful.
    221          *
    222          * @param call The call the request was successful for.
    223          */
    224         public void onUpgradeToVideoSuccess(Call call);
    225 
    226         /**
    227          * Called when a request to a peer to upgrade an audio-only call to a video call is
    228          * NOT successful. This can be if the peer chooses rejects the the video call, or if the
    229          * peer does not support video calling, or if there is some error in sending the request.
    230          *
    231          * @param call The call the request was successful for.
    232          */
    233         public void onUpgradeToVideoFail(Call call);
    234 
    235         /**
    236          * Called when a call has been downgraded to audio-only.
    237          *
    238          * @param call The call which was downgraded to audio-only.
    239          */
    240         public void onDowngradeToAudio(Call call);
    241     }
    242 
    243     /**
    244      * Listener interface for any class that wants to be notified of video events, including pause
    245      * and un-pause of peer video.
    246      */
    247     public interface VideoEventListener {
    248         /**
    249          * Called when the peer pauses or un-pauses video transmission.
    250          *
    251          * @param call   The call which paused or un-paused video transmission.
    252          * @param paused {@code True} when the video transmission is paused, {@code false}
    253          *               otherwise.
    254          */
    255         public void onPeerPauseStateChanged(Call call, boolean paused);
    256     }
    257 
    258     /**
    259      * Listener interface for any class that wants to be notified of changes to the video surfaces.
    260      */
    261     public interface SurfaceChangeListener {
    262         /**
    263          * Called when the peer video feed changes dimensions. This can occur when the peer rotates
    264          * their device, changing the aspect ratio of the video signal.
    265          *
    266          * @param call The call which experienced a peer video
    267          * @param width
    268          * @param height
    269          */
    270         public void onUpdatePeerDimensions(Call call, int width, int height);
    271 
    272         /**
    273          * Called when the local camera changes dimensions.  This occurs when a change in camera
    274          * occurs.
    275          *
    276          * @param call The call which experienced the camera dimension change.
    277          * @param width The new camera video width.
    278          * @param height The new camera video height.
    279          */
    280         public void onCameraDimensionsChange(Call call, int width, int height);
    281     }
    282 }
    283