blob: 15227af29b8f6867a959509dc8c403eb9e27bf3d [file] [log] [blame]
package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1;
import static android.os.Build.VERSION_CODES.N;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.Resetter;
import org.robolectric.util.ReflectionHelpers;
@Implements(value = SubscriptionManager.class, minSdk = LOLLIPOP_MR1)
public class ShadowSubscriptionManager {
private static int defaultSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private static int defaultDataSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private static int defaultSmsSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private static int defaultVoiceSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
/** Returns value set with {@link #setDefaultSubscriptionId(int)}. */
@Implementation(minSdk = N)
protected static int getDefaultSubscriptionId() {
return defaultSubscriptionId;
}
/** Returns value set with {@link #setDefaultDataSubscriptionId(int)}. */
@Implementation(minSdk = N)
protected static int getDefaultDataSubscriptionId() {
return defaultDataSubscriptionId;
}
/** Returns value set with {@link #setDefaultSmsSubscriptionId(int)}. */
@Implementation(minSdk = N)
protected static int getDefaultSmsSubscriptionId() {
return defaultSmsSubscriptionId;
}
/** Returns value set with {@link #setDefaultVoiceSubscriptionId(int)}. */
@Implementation(minSdk = N)
protected static int getDefaultVoiceSubscriptionId() {
return defaultVoiceSubscriptionId;
}
/** Sets the value that will be returned by {@link #getDefaultSubscriptionId()}. */
public static void setDefaultSubscriptionId(int defaultSubscriptionId) {
ShadowSubscriptionManager.defaultSubscriptionId = defaultSubscriptionId;
}
public static void setDefaultDataSubscriptionId(int defaultDataSubscriptionId) {
ShadowSubscriptionManager.defaultDataSubscriptionId = defaultDataSubscriptionId;
}
public static void setDefaultSmsSubscriptionId(int defaultSmsSubscriptionId) {
ShadowSubscriptionManager.defaultSmsSubscriptionId = defaultSmsSubscriptionId;
}
public static void setDefaultVoiceSubscriptionId(int defaultVoiceSubscriptionId) {
ShadowSubscriptionManager.defaultVoiceSubscriptionId = defaultVoiceSubscriptionId;
}
/**
* Cache of {@link SubscriptionInfo} used by {@link #getActiveSubscriptionInfoList}.
* Managed by {@link #setActiveSubscriptionInfoList}.
*/
private List<SubscriptionInfo> subscriptionList = new ArrayList<>();
/**
* List of listeners to be notified if the list of {@link SubscriptionInfo} changes. Managed by
* {@link #addOnSubscriptionsChangedListener} and {@link removeOnSubscriptionsChangedListener}.
*/
private List<OnSubscriptionsChangedListener> listeners = new ArrayList<>();
/**
* Cache of subscription ids used by {@link #isNetworkRoaming}. Managed by {@link
* #setNetworkRoamingStatus} and {@link #clearNetworkRoamingStatus}.
*/
private Set<Integer> roamingSimSubscriptionIds = new HashSet<>();
/**
* Returns the active list of {@link SubscriptionInfo} that were set via {@link
* #setActiveSubscriptionInfoList}.
*/
@Implementation(minSdk = LOLLIPOP_MR1)
protected List<SubscriptionInfo> getActiveSubscriptionInfoList() {
return subscriptionList;
}
/**
* Returns the size of the list of {@link SubscriptionInfo} that were set via {@link
* #setActiveSubscriptionInfoList}. If no list was set, returns 0.
*/
@Implementation(minSdk = LOLLIPOP_MR1)
protected int getActiveSubscriptionInfoCount() {
return subscriptionList == null ? 0 : subscriptionList.size();
}
/**
* Returns subscription that were set via {@link #setActiveSubscriptionInfoList} if it can find
* one with the specified id or null if none found.
*/
@Implementation(minSdk = LOLLIPOP_MR1)
protected SubscriptionInfo getActiveSubscriptionInfo(int subId) {
if (subscriptionList == null) {
return null;
}
for (SubscriptionInfo info : subscriptionList) {
if (info.getSubscriptionId() == subId) {
return info;
}
}
return null;
}
/**
* Returns subscription that were set via {@link #setActiveSubscriptionInfoList} if it can find
* one with the specified slot index or null if none found.
*/
@Implementation(minSdk = N)
protected SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex) {
if (subscriptionList == null) {
return null;
}
for (SubscriptionInfo info : subscriptionList) {
if (info.getSimSlotIndex() == slotIndex) {
return info;
}
}
return null;
}
/**
* Sets the active list of {@link SubscriptionInfo}. This call internally triggers {@link
* OnSubscriptionsChangedListener#onSubscriptionsChanged()} to all the listeners.
* @param list - The subscription info list, can be null.
*/
public void setActiveSubscriptionInfoList(List<SubscriptionInfo> list) {
subscriptionList = list;
dispatchOnSubscriptionsChanged();
}
/**
* Sets the active list of {@link SubscriptionInfo}. This call internally triggers {@link
* OnSubscriptionsChangedListener#onSubscriptionsChanged()} to all the listeners.
*/
public void setActiveSubscriptionInfos(SubscriptionInfo... infos) {
if (infos == null) {
setActiveSubscriptionInfoList(Collections.emptyList());
} else {
setActiveSubscriptionInfoList(Arrays.asList(infos));
}
}
/**
* Adds a listener to a local list of listeners. Will be triggered by {@link
* #setActiveSubscriptionInfoList} when the local list of {@link SubscriptionInfo} is updated.
*/
@Implementation(minSdk = LOLLIPOP_MR1)
protected void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
listeners.add(listener);
}
/**
* Removes a listener from a local list of listeners. Will be triggered by {@link
* #setActiveSubscriptionInfoList} when the local list of {@link SubscriptionInfo} is updated.
*/
@Implementation(minSdk = LOLLIPOP_MR1)
protected void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
listeners.remove(listener);
}
/** Returns subscription Ids that were set via {@link #setActiveSubscriptionInfoList}. */
@Implementation(minSdk = LOLLIPOP_MR1)
@HiddenApi
protected int[] getActiveSubscriptionIdList() {
final List<SubscriptionInfo> infos = getActiveSubscriptionInfoList();
if (infos == null) {
return new int[0];
}
int[] ids = new int[infos.size()];
for (int i = 0; i < infos.size(); i++) {
ids[i] = infos.get(i).getSubscriptionId();
}
return ids;
}
/**
* Notifies {@link OnSubscriptionsChangedListener} listeners that the list of {@link
* SubscriptionInfo} has been updated.
*/
private void dispatchOnSubscriptionsChanged() {
for (OnSubscriptionsChangedListener listener : listeners) {
listener.onSubscriptionsChanged();
}
}
/** Clears the local cache of roaming subscription Ids used by {@link #isNetworkRoaming}. */
public void clearNetworkRoamingStatus(){
roamingSimSubscriptionIds.clear();
}
/**
* If isNetworkRoaming is set, it will mark the provided sim subscriptionId as roaming in a local
* cache. If isNetworkRoaming is unset it will remove the subscriptionId from the local cache. The
* local cache is used to provide roaming status returned by {@link #isNetworkRoaming}.
*/
public void setNetworkRoamingStatus(int simSubscriptionId, boolean isNetworkRoaming) {
if (isNetworkRoaming) {
roamingSimSubscriptionIds.add(simSubscriptionId);
} else {
roamingSimSubscriptionIds.remove(simSubscriptionId);
}
}
/**
* Uses the local cache of roaming sim subscription Ids managed by {@link
* #setNetworkRoamingStatus} to return subscription Ids marked as roaming. Otherwise subscription
* Ids will be considered as non-roaming if they are not in the cache.
*/
@Implementation(minSdk = LOLLIPOP_MR1)
protected boolean isNetworkRoaming(int simSubscriptionId) {
return roamingSimSubscriptionIds.contains(simSubscriptionId);
}
@Resetter
public static void reset() {
defaultDataSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
defaultSmsSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
defaultVoiceSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
defaultSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
/** Builder class to create instance of {@link SubscriptionInfo}. */
public static class SubscriptionInfoBuilder {
private final SubscriptionInfo subscriptionInfo =
ReflectionHelpers.callConstructor(SubscriptionInfo.class);
public static SubscriptionInfoBuilder newBuilder() {
return new SubscriptionInfoBuilder();
}
public SubscriptionInfo buildSubscriptionInfo() {
return subscriptionInfo;
}
public SubscriptionInfoBuilder setId(int id) {
ReflectionHelpers.setField(subscriptionInfo, "mId", id);
return this;
}
public SubscriptionInfoBuilder setIccId(String iccId) {
ReflectionHelpers.setField(subscriptionInfo, "mIccId", iccId);
return this;
}
public SubscriptionInfoBuilder setSimSlotIndex(int index) {
ReflectionHelpers.setField(subscriptionInfo, "mSimSlotIndex", index);
return this;
}
public SubscriptionInfoBuilder setDisplayName(String name) {
ReflectionHelpers.setField(subscriptionInfo, "mDisplayName", name);
return this;
}
public SubscriptionInfoBuilder setCarrierName(String carrierName) {
ReflectionHelpers.setField(subscriptionInfo, "mCarrierName", carrierName);
return this;
}
public SubscriptionInfoBuilder setIconTint(int iconTint) {
ReflectionHelpers.setField(subscriptionInfo, "mIconTint", iconTint);
return this;
}
public SubscriptionInfoBuilder setNumber(String number) {
ReflectionHelpers.setField(subscriptionInfo, "mNumber", number);
return this;
}
public SubscriptionInfoBuilder setDataRoaming(int dataRoaming) {
ReflectionHelpers.setField(subscriptionInfo, "mDataRoaming", dataRoaming);
return this;
}
public SubscriptionInfoBuilder setCountryIso(String countryIso) {
ReflectionHelpers.setField(subscriptionInfo, "mCountryIso", countryIso);
return this;
}
// Use {@link #newBuilder} to construct builders.
private SubscriptionInfoBuilder() {}
}
}