• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static android.os.Build.VERSION_CODES.P;
4 import static android.os.Build.VERSION_CODES.Q;
5 import static android.os.Build.VERSION_CODES.R;
6 import static org.robolectric.util.reflector.Reflector.reflector;
7 
8 import android.os.Build.VERSION;
9 import android.telephony.NetworkRegistrationInfo;
10 import android.telephony.ServiceState;
11 import androidx.annotation.RequiresApi;
12 import java.util.List;
13 import org.robolectric.RuntimeEnvironment;
14 import org.robolectric.util.reflector.Accessor;
15 import org.robolectric.util.reflector.ForType;
16 
17 /** Builder class to create instance of {@link ServiceState}. */
18 public class ServiceStateBuilder {
19   private ServiceState serviceState = new ServiceState();
20 
newBuilder()21   public static ServiceStateBuilder newBuilder() {
22     return new ServiceStateBuilder();
23   }
24 
newBuilder(ServiceState serviceState)25   public static ServiceStateBuilder newBuilder(ServiceState serviceState) {
26     ServiceStateBuilder builder = new ServiceStateBuilder();
27     builder.serviceState = serviceState;
28     return builder;
29   }
30 
build()31   public ServiceState build() {
32     return serviceState;
33   }
34 
setVoiceRegState(int value)35   public ServiceStateBuilder setVoiceRegState(int value) {
36     serviceState.setVoiceRegState(value);
37     return this;
38   }
39 
setDataRegState(int value)40   public ServiceStateBuilder setDataRegState(int value) {
41     serviceState.setDataRegState(value);
42     return this;
43   }
44 
setNrFrequencyRange(int value)45   public ServiceStateBuilder setNrFrequencyRange(int value) {
46     assertIsAtLeast(Q);
47     serviceState.setNrFrequencyRange(value);
48     return this;
49   }
50 
setIsManualSelection(boolean value)51   public ServiceStateBuilder setIsManualSelection(boolean value) {
52     serviceState.setIsManualSelection(value);
53     return this;
54   }
55 
setOperatorName(String longName, String shortName, String numeric)56   public ServiceStateBuilder setOperatorName(String longName, String shortName, String numeric) {
57     assertIsAtLeast(R);
58     serviceState.setOperatorName(longName, shortName, numeric);
59     return this;
60   }
61 
setIwlanPreferred(boolean value)62   public ServiceStateBuilder setIwlanPreferred(boolean value) {
63     assertIsAtLeast(R);
64     serviceState.setIwlanPreferred(value);
65     return this;
66   }
67 
setEmergencyOnly(boolean value)68   public ServiceStateBuilder setEmergencyOnly(boolean value) {
69     serviceState.setEmergencyOnly(value);
70     return this;
71   }
72 
setDataRoamingFromRegistration(boolean value)73   public ServiceStateBuilder setDataRoamingFromRegistration(boolean value) {
74     assertIsAtLeast(R);
75     serviceState.setDataRoamingFromRegistration(value);
76     return this;
77   }
78 
79   /**
80    * Use this method to control return value of {@link ServiceState#isUsingCarrierAggregation()} (up
81    * to P). On APIs > P, use {@link ServiceStateBuilder#setNetworkRegistrationInfoList()}.
82    */
setIsUsingCarrierAggregation(boolean value)83   public ServiceStateBuilder setIsUsingCarrierAggregation(boolean value) {
84     assertIsAtLeast(P);
85     // {@link NetworkRegistrationInfo} was first made a @SystemApi in Q then finally exposed as
86     // public in R. For SDK later than Q, call
87     // {@link ServiceStateBuilder#setNetworkRegistrationInfoList} to set this value. Downstream test
88     // code will have to specify NRIs in the builder to set this value. But the "actual"
89     // implementation code under test would still be looking at the non-NRI getters
90     // on {@link ServiceState}, assuming it's restricted to only public APIs.
91     if (VERSION.SDK_INT >= Q) {
92       throw new UnsupportedOperationException(
93           "Newer SDKs must specify carrier aggregation by constructing an appropriate "
94               + "NetworkRegistrationInfo and calling #setNetworkRegistrationInfoList instead");
95     } else {
96       reflector(ServiceStateReflector.class, serviceState).setIsUsingCarrierAggregation(value);
97     }
98     return this;
99   }
100 
101   @RequiresApi(Q)
setNetworkRegistrationInfoList(List<NetworkRegistrationInfo> value)102   public ServiceStateBuilder setNetworkRegistrationInfoList(List<NetworkRegistrationInfo> value) {
103     assertIsAtLeast(Q);
104     reflector(ServiceStateReflector.class, serviceState).setNetworkRegistrationInfos(value);
105     return this;
106   }
107 
setRoaming(boolean value)108   public ServiceStateBuilder setRoaming(boolean value) {
109     serviceState.setRoaming(value);
110     return this;
111   }
112 
setChannelNumber(int value)113   public ServiceStateBuilder setChannelNumber(int value) {
114     serviceState.setChannelNumber(value);
115     return this;
116   }
117 
setCellBandwidths(int[] value)118   public ServiceStateBuilder setCellBandwidths(int[] value) {
119     serviceState.setCellBandwidths(value);
120     return this;
121   }
122 
123   // TODO Find a proper way to set radio tech values.
124 
assertIsAtLeast(int sdk)125   private void assertIsAtLeast(int sdk) {
126     if (VERSION.SDK_INT < sdk) {
127       throw new IllegalStateException(
128           "This method is not available on SDK : " + RuntimeEnvironment.getApiLevel());
129     }
130   }
131 
132   @ForType(ServiceState.class)
133   private interface ServiceStateReflector {
134 
135     @Accessor("mIsUsingCarrierAggregation")
setIsUsingCarrierAggregation(boolean value)136     public void setIsUsingCarrierAggregation(boolean value);
137 
138     @Accessor("mNetworkRegistrationInfos")
setNetworkRegistrationInfos(List<NetworkRegistrationInfo> value)139     public void setNetworkRegistrationInfos(List<NetworkRegistrationInfo> value);
140   }
141 }
142