• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static android.os.Build.VERSION_CODES.R;
4 import static android.os.Build.VERSION_CODES.S;
5 import static org.robolectric.util.reflector.Reflector.reflector;
6 
7 import android.net.Uri;
8 import android.telephony.ims.RcsContactUceCapability;
9 import android.telephony.ims.RcsUceAdapter;
10 import com.google.auto.value.AutoValue;
11 import com.google.common.collect.ImmutableList;
12 import java.util.Collection;
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.Map;
16 import java.util.Set;
17 import java.util.concurrent.Executor;
18 import org.robolectric.annotation.Implementation;
19 import org.robolectric.annotation.Implements;
20 import org.robolectric.annotation.RealObject;
21 import org.robolectric.annotation.Resetter;
22 import org.robolectric.util.reflector.Accessor;
23 import org.robolectric.util.reflector.ForType;
24 
25 /** A shadow for {@link RcsUceAdapter}. */
26 @Implements(
27     value = RcsUceAdapter.class,
28     // turn off shadowOf generation
29     isInAndroidSdk = false,
30     minSdk = R)
31 public class ShadowRcsUceAdapter {
32   private static final Set<Integer> subscriptionIdsWithUceSettingEnabled = new HashSet<>();
33   private static final Map<Uri, RcsContactUceCapability> capabilitiesMap = new HashMap<>();
34   private static final Map<Uri, CapabilityFailureInfo> capabilitiesFailureMap = new HashMap<>();
35 
36   @RealObject private RcsUceAdapter realRcsUceAdapter;
37 
38   /**
39    * Overrides the value returned by {@link RcsUceAdapter#isUceSettingEnabled()} for RcsUceAdapters
40    * associated with {@code subscriptionId}.
41    */
setUceSettingEnabledForSubscriptionId( int subscriptionId, boolean uceSettingEnabled)42   public static void setUceSettingEnabledForSubscriptionId(
43       int subscriptionId, boolean uceSettingEnabled) {
44     if (uceSettingEnabled) {
45       subscriptionIdsWithUceSettingEnabled.add(subscriptionId);
46     } else {
47       subscriptionIdsWithUceSettingEnabled.remove(subscriptionId);
48     }
49   }
50 
51   @Resetter
reset()52   public static void reset() {
53     subscriptionIdsWithUceSettingEnabled.clear();
54     capabilitiesMap.clear();
55     capabilitiesFailureMap.clear();
56   }
57 
58   /**
59    * Returns the value specified for the {@code subscriptionId} corresponding to the {@link
60    * RcsUceAdapter} by {@link ShadowRcsUceAdapter#setUceSettingEnabledForSubscriptionId(int,
61    * boolean)}. If no value has been specified, returns false.
62    */
63   @Implementation
isUceSettingEnabled()64   protected boolean isUceSettingEnabled() {
65     int subscriptionId = reflector(ReflectorRcsUceAdapter.class, realRcsUceAdapter).getSubId();
66     return subscriptionIdsWithUceSettingEnabled.contains(subscriptionId);
67   }
68 
setCapabilitiesForUri(Uri uri, RcsContactUceCapability capabilities)69   public static void setCapabilitiesForUri(Uri uri, RcsContactUceCapability capabilities) {
70     capabilitiesMap.put(uri, capabilities);
71   }
72 
setCapabilitiesFailureForUri(Uri uri, CapabilityFailureInfo failureInfo)73   public static void setCapabilitiesFailureForUri(Uri uri, CapabilityFailureInfo failureInfo) {
74     capabilitiesFailureMap.put(uri, failureInfo);
75   }
76 
77   @Implementation(minSdk = S)
requestCapabilities( Collection<Uri> contactNumbers, Executor executor, RcsUceAdapter.CapabilitiesCallback c)78   protected void requestCapabilities(
79       Collection<Uri> contactNumbers, Executor executor, RcsUceAdapter.CapabilitiesCallback c) {
80     boolean completedSuccessfully = true;
81     for (Uri contact : contactNumbers) {
82       if (capabilitiesFailureMap.containsKey(contact)) {
83         CapabilityFailureInfo failureInfo = capabilitiesFailureMap.get(contact);
84         executor.execute(() -> c.onError(failureInfo.errorCode(), failureInfo.retryMillis()));
85         completedSuccessfully = false;
86         break;
87       }
88       if (capabilitiesMap.containsKey(contact)) {
89         executor.execute(
90             () -> c.onCapabilitiesReceived(ImmutableList.of(capabilitiesMap.get(contact))));
91       } else {
92         executor.execute(
93             () ->
94                 c.onCapabilitiesReceived(
95                     ImmutableList.of(new RcsContactUceCapability.OptionsBuilder(contact).build())));
96       }
97     }
98     if (completedSuccessfully) {
99       executor.execute(c::onComplete);
100     }
101   }
102 
103   @Implementation(minSdk = S)
requestAvailability( Uri contactNumber, Executor executor, RcsUceAdapter.CapabilitiesCallback c)104   protected void requestAvailability(
105       Uri contactNumber, Executor executor, RcsUceAdapter.CapabilitiesCallback c) {
106     requestCapabilities(ImmutableList.of(contactNumber), executor, c);
107   }
108 
109   /** A data class holding the info for a failed capabilities exchange */
110   @AutoValue
111   public abstract static class CapabilityFailureInfo {
create(int errorCode, long retryMillis)112     public static CapabilityFailureInfo create(int errorCode, long retryMillis) {
113       return new AutoValue_ShadowRcsUceAdapter_CapabilityFailureInfo(errorCode, retryMillis);
114     }
115 
errorCode()116     public abstract int errorCode();
117 
retryMillis()118     public abstract long retryMillis();
119   }
120 
121   /** Accessor interface for {@link RcsUceAdapter}'s internals. */
122   @ForType(RcsUceAdapter.class)
123   private interface ReflectorRcsUceAdapter {
124     @Accessor("mSubId")
getSubId()125     int getSubId();
126   }
127 }
128