Home | History | Annotate | Download | only in shadows
      1 package org.robolectric.shadows;
      2 
      3 import static android.os.Build.VERSION_CODES.LOLLIPOP;
      4 import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1;
      5 import static android.os.Build.VERSION_CODES.M;
      6 
      7 import android.content.ComponentName;
      8 import android.content.Context;
      9 import android.net.Uri;
     10 import android.os.Bundle;
     11 import android.telecom.PhoneAccount;
     12 import android.telecom.PhoneAccountHandle;
     13 import android.telecom.TelecomManager;
     14 import com.google.common.collect.ImmutableList;
     15 import java.util.ArrayList;
     16 import java.util.HashSet;
     17 import java.util.LinkedHashMap;
     18 import java.util.List;
     19 import java.util.Set;
     20 import org.robolectric.annotation.HiddenApi;
     21 import org.robolectric.annotation.Implementation;
     22 import org.robolectric.annotation.Implements;
     23 import org.robolectric.annotation.RealObject;
     24 import org.robolectric.util.ReflectionHelpers;
     25 
     26 @Implements(value = TelecomManager.class, minSdk = LOLLIPOP)
     27 public class ShadowTelecomManager {
     28 
     29   @RealObject
     30   private TelecomManager realObject;
     31 
     32   private PhoneAccountHandle simCallManager;
     33   private LinkedHashMap<PhoneAccountHandle, PhoneAccount> accounts = new LinkedHashMap();
     34   private List<CallRecord> incomingCalls = new ArrayList<>();
     35   private List<CallRecord> unknownCalls = new ArrayList<>();
     36   private String defaultDialerPackageName;
     37   private boolean isInCall;
     38 
     39   @Implementation
     40   protected PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme) {
     41     return null;
     42   }
     43 
     44   @Implementation
     45   @HiddenApi
     46   public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
     47     return null;
     48   }
     49 
     50   @Implementation
     51   @HiddenApi
     52   public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
     53   }
     54 
     55   @Implementation
     56   protected PhoneAccountHandle getSimCallManager() {
     57     return simCallManager;
     58   }
     59 
     60   @Implementation(minSdk = M)
     61   @HiddenApi
     62   public PhoneAccountHandle getSimCallManager(int userId) {
     63     return null;
     64   }
     65 
     66   @Implementation
     67   @HiddenApi
     68   public PhoneAccountHandle getConnectionManager() {
     69     return this.getSimCallManager();
     70   }
     71 
     72   @Implementation
     73   @HiddenApi
     74   public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme) {
     75     List<PhoneAccountHandle> result = new ArrayList<>();
     76 
     77     for (PhoneAccountHandle handle : accounts.keySet()) {
     78       PhoneAccount phoneAccount = accounts.get(handle);
     79       if(phoneAccount.getSupportedUriSchemes().contains(uriScheme)) {
     80         result.add(handle);
     81       }
     82     }
     83     return result;
     84   }
     85 
     86   @Implementation(minSdk = M)
     87   protected List<PhoneAccountHandle> getCallCapablePhoneAccounts() {
     88     return this.getCallCapablePhoneAccounts(false);
     89   }
     90 
     91   @Implementation(minSdk = M)
     92   @HiddenApi
     93   public List<PhoneAccountHandle> getCallCapablePhoneAccounts(boolean includeDisabledAccounts) {
     94     List<PhoneAccountHandle> result = new ArrayList<>();
     95 
     96     for (PhoneAccountHandle handle : accounts.keySet()) {
     97       PhoneAccount phoneAccount = accounts.get(handle);
     98       if(!phoneAccount.isEnabled() && !includeDisabledAccounts) {
     99         continue;
    100       }
    101       result.add(handle);
    102     }
    103     return result;
    104   }
    105 
    106   @Implementation
    107   @HiddenApi
    108   public List<PhoneAccountHandle> getPhoneAccountsForPackage() {
    109     Context context = ReflectionHelpers.getField(realObject, "mContext");
    110 
    111     List<PhoneAccountHandle> results = new ArrayList<>();
    112     for (PhoneAccountHandle handle : accounts.keySet()) {
    113       if (handle.getComponentName().getPackageName().equals(context.getPackageName())) {
    114         results.add(handle);
    115       }
    116     }
    117     return results;
    118   }
    119 
    120   @Implementation
    121   protected PhoneAccount getPhoneAccount(PhoneAccountHandle account) {
    122     return accounts.get(account);
    123   }
    124 
    125   @Implementation
    126   @HiddenApi
    127   public int getAllPhoneAccountsCount() {
    128     return accounts.size();
    129   }
    130 
    131   @Implementation
    132   @HiddenApi
    133   public List<PhoneAccount> getAllPhoneAccounts() {
    134     return ImmutableList.copyOf(accounts.values());
    135   }
    136 
    137   @Implementation
    138   @HiddenApi
    139   public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
    140     return ImmutableList.copyOf(accounts.keySet());
    141   }
    142 
    143   @Implementation
    144   protected void registerPhoneAccount(PhoneAccount account) {
    145     accounts.put(account.getAccountHandle(), account);
    146   }
    147 
    148   @Implementation
    149   protected void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
    150     accounts.remove(accountHandle);
    151   }
    152 
    153   /** @deprecated */
    154   @Deprecated
    155   @Implementation
    156   @HiddenApi
    157   public void clearAccounts() {
    158     accounts.clear();
    159   }
    160 
    161 
    162   @Implementation(minSdk = LOLLIPOP_MR1)
    163   @HiddenApi
    164   public void clearAccountsForPackage(String packageName) {
    165     Set<PhoneAccountHandle> phoneAccountHandlesInPackage = new HashSet<>();
    166 
    167     for (PhoneAccountHandle handle : accounts.keySet()) {
    168       if (handle.getComponentName().getPackageName().equals(packageName)) {
    169         phoneAccountHandlesInPackage.add(handle);
    170       }
    171     }
    172 
    173     for (PhoneAccountHandle handle : phoneAccountHandlesInPackage) {
    174       accounts.remove(handle);
    175     }
    176   }
    177 
    178   /** @deprecated */
    179   @Deprecated
    180   @Implementation
    181   @HiddenApi
    182   public ComponentName getDefaultPhoneApp() {
    183     return null;
    184   }
    185 
    186   @Implementation(minSdk = M)
    187   protected String getDefaultDialerPackage() {
    188     return defaultDialerPackageName;
    189   }
    190 
    191   @Implementation(minSdk = M)
    192   @HiddenApi
    193   public boolean setDefaultDialer(String packageName) {
    194     this.defaultDialerPackageName = packageName;
    195     return true;
    196   }
    197 
    198   @Implementation(minSdk = M)
    199   @HiddenApi
    200   public String getSystemDialerPackage() {
    201     return null;
    202   }
    203 
    204   @Implementation(minSdk = LOLLIPOP_MR1)
    205   protected boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number) {
    206     return false;
    207   }
    208 
    209   @Implementation(minSdk = M)
    210   protected String getVoiceMailNumber(PhoneAccountHandle accountHandle) {
    211     return null;
    212   }
    213 
    214   @Implementation(minSdk = LOLLIPOP_MR1)
    215   protected String getLine1Number(PhoneAccountHandle accountHandle) {
    216     return null;
    217   }
    218 
    219   /** Sets the return value for {@link TelecomManager#isInCall}. */
    220   public void setIsInCall(boolean isInCall) {
    221     this.isInCall = isInCall;
    222   }
    223 
    224   /**
    225    * Overrides behavior of {@link TelecomManager#isInCall} to return pre-set result.
    226    *
    227    * @return Value set by calling {@link ShadowTelecomManager#setIsInCall}. If setIsInCall has not
    228    *     previously been called, will return false.
    229    */
    230   @Implementation
    231   protected boolean isInCall() {
    232     return isInCall;
    233   }
    234 
    235   @Implementation
    236   @HiddenApi
    237   public int getCallState() {
    238     return 0;
    239   }
    240 
    241   @Implementation
    242   @HiddenApi
    243   public boolean isRinging() {
    244     for (CallRecord callRecord : incomingCalls) {
    245       if (callRecord.isRinging) {
    246         return true;
    247       }
    248     }
    249     for (CallRecord callRecord : unknownCalls) {
    250       if (callRecord.isRinging) {
    251         return true;
    252       }
    253     }
    254     return false;
    255   }
    256 
    257   @Implementation
    258   @HiddenApi
    259   public boolean endCall() {
    260     return false;
    261   }
    262 
    263   @Implementation
    264   protected void acceptRingingCall() {}
    265 
    266   @Implementation
    267   protected void silenceRinger() {
    268     for (CallRecord callRecord : incomingCalls) {
    269       callRecord.isRinging = false;
    270     }
    271     for (CallRecord callRecord : unknownCalls) {
    272       callRecord.isRinging = false;
    273     }
    274   }
    275 
    276   @Implementation
    277   protected boolean isTtySupported() {
    278     return false;
    279   }
    280 
    281   @Implementation
    282   @HiddenApi
    283   public int getCurrentTtyMode() {
    284     return 0;
    285   }
    286 
    287   @Implementation
    288   protected void addNewIncomingCall(PhoneAccountHandle phoneAccount, Bundle extras) {
    289     incomingCalls.add(new CallRecord(phoneAccount, extras));
    290   }
    291 
    292   public List<CallRecord> getAllIncomingCalls() {
    293     return incomingCalls;
    294   }
    295 
    296   @Implementation
    297   @HiddenApi
    298   public void addNewUnknownCall(PhoneAccountHandle phoneAccount, Bundle extras) {
    299     unknownCalls.add(new CallRecord(phoneAccount, extras));
    300   }
    301 
    302   public List<CallRecord> getAllUnknownCalls() {
    303     return unknownCalls;
    304   }
    305 
    306   @Implementation
    307   protected boolean handleMmi(String dialString) {
    308     return false;
    309   }
    310 
    311   @Implementation(minSdk = M)
    312   protected boolean handleMmi(String dialString, PhoneAccountHandle accountHandle) {
    313     return false;
    314   }
    315 
    316   @Implementation(minSdk = LOLLIPOP_MR1)
    317   protected Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle) {
    318     return Uri.parse("content://icc/adn");
    319   }
    320 
    321   @Implementation
    322   protected void cancelMissedCallsNotification() {}
    323 
    324   @Implementation
    325   protected void showInCallScreen(boolean showDialpad) {}
    326 
    327   @Implementation(minSdk = M)
    328   protected void placeCall(Uri address, Bundle extras) {}
    329 
    330   @Implementation(minSdk = M)
    331   @HiddenApi
    332   public void enablePhoneAccount(PhoneAccountHandle handle, boolean isEnabled) {
    333   }
    334 
    335   public void setSimCallManager(PhoneAccountHandle simCallManager) {
    336     this.simCallManager = simCallManager;
    337   }
    338 
    339   public static class CallRecord {
    340     public final PhoneAccountHandle phoneAccount;
    341     public final Bundle bundle;
    342     private boolean isRinging = true;
    343 
    344     public CallRecord(PhoneAccountHandle phoneAccount, Bundle extras) {
    345       this.phoneAccount = phoneAccount;
    346       this.bundle = extras;
    347     }
    348   }
    349 
    350 }
    351