diff options
author | Meng Wang <mewan@google.com> | 2019-11-27 21:23:31 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2019-11-27 21:23:31 +0000 |
commit | 306786abd496f026a03312162a208df35fa2d785 (patch) | |
tree | 2d40371036aff469d21c8363e8de94f933970d45 /telephony/java | |
parent | 4d0df870cd052c995d3938b39a86140dd5b73e36 (diff) | |
parent | a9ed60663673867c9972c2065fe4d5e622acdf88 (diff) |
Merge "Move CarrierIdentifier/CarrierService to telephony"
Diffstat (limited to 'telephony/java')
4 files changed, 467 insertions, 0 deletions
diff --git a/telephony/java/android/service/carrier/CarrierIdentifier.aidl b/telephony/java/android/service/carrier/CarrierIdentifier.aidl new file mode 100644 index 000000000000..48b13983050d --- /dev/null +++ b/telephony/java/android/service/carrier/CarrierIdentifier.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2015, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.carrier; + +parcelable CarrierIdentifier; diff --git a/telephony/java/android/service/carrier/CarrierIdentifier.java b/telephony/java/android/service/carrier/CarrierIdentifier.java new file mode 100644 index 000000000000..af5bf7475f95 --- /dev/null +++ b/telephony/java/android/service/carrier/CarrierIdentifier.java @@ -0,0 +1,255 @@ +/** + * Copyright (c) 2015, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.carrier; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; +import android.telephony.Rlog; +import android.telephony.TelephonyManager; + +import com.android.internal.telephony.uicc.IccUtils; + +import java.util.Objects; + +/** + * Used to pass info to CarrierConfigService implementations so they can decide what values to + * return. Instead of passing mcc, mnc, gid1, gid2, spn, imsi to locate carrier information, + * CarrierIdentifier also include carrier id {@link TelephonyManager#getSimCarrierId()}, + * a platform-wide unique identifier for each carrier. CarrierConfigService can directly use + * carrier id as the key to look up the carrier info. + */ +public class CarrierIdentifier implements Parcelable { + + /** Used to create a {@link CarrierIdentifier} from a {@link Parcel}. */ + public static final @android.annotation.NonNull Creator<CarrierIdentifier> CREATOR = new Creator<CarrierIdentifier>() { + @Override + public CarrierIdentifier createFromParcel(Parcel parcel) { + return new CarrierIdentifier(parcel); + } + + @Override + public CarrierIdentifier[] newArray(int i) { + return new CarrierIdentifier[i]; + } + }; + + private String mMcc; + private String mMnc; + private @Nullable String mSpn; + private @Nullable String mImsi; + private @Nullable String mGid1; + private @Nullable String mGid2; + private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; + private int mSpecificCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; + + public CarrierIdentifier(String mcc, String mnc, @Nullable String spn, @Nullable String imsi, + @Nullable String gid1, @Nullable String gid2) { + this(mcc, mnc, spn, imsi, gid1, gid2, TelephonyManager.UNKNOWN_CARRIER_ID, + TelephonyManager.UNKNOWN_CARRIER_ID); + } + + /** + * @param mcc mobile country code + * @param mnc mobile network code + * @param spn service provider name + * @param imsi International Mobile Subscriber Identity {@link TelephonyManager#getSubscriberId()} + * @param gid1 group id level 1 {@link TelephonyManager#getGroupIdLevel1()} + * @param gid2 group id level 2 + * @param carrierid carrier unique identifier {@link TelephonyManager#getSimCarrierId()}, used + * to uniquely identify the carrier and look up the carrier configurations. + * @param specificCarrierId specific carrier identifier + * {@link TelephonyManager#getSimSpecificCarrierId()} + */ + public CarrierIdentifier(@NonNull String mcc, @NonNull String mnc, @Nullable String spn, + @Nullable String imsi, @Nullable String gid1, @Nullable String gid2, + int carrierid, int specificCarrierId) { + mMcc = mcc; + mMnc = mnc; + mSpn = spn; + mImsi = imsi; + mGid1 = gid1; + mGid2 = gid2; + mCarrierId = carrierid; + mSpecificCarrierId = specificCarrierId; + } + + /** + * Creates a carrier identifier instance. + * + * @param mccMnc A 3-byte array as defined by 3GPP TS 24.008. + * @param gid1 The group identifier level 1. + * @param gid2 The group identifier level 2. + * @throws IllegalArgumentException If the length of {@code mccMnc} is not 3. + */ + public CarrierIdentifier(byte[] mccMnc, @Nullable String gid1, @Nullable String gid2) { + if (mccMnc.length != 3) { + throw new IllegalArgumentException( + "MCC & MNC must be set by a 3-byte array: byte[" + mccMnc.length + "]"); + } + String hex = IccUtils.bytesToHexString(mccMnc); + mMcc = new String(new char[] {hex.charAt(1), hex.charAt(0), hex.charAt(3)}); + if (hex.charAt(2) == 'F') { + mMnc = new String(new char[] {hex.charAt(5), hex.charAt(4)}); + } else { + mMnc = new String(new char[] {hex.charAt(5), hex.charAt(4), hex.charAt(2)}); + } + mGid1 = gid1; + mGid2 = gid2; + mSpn = null; + mImsi = null; + } + + /** @hide */ + public CarrierIdentifier(Parcel parcel) { + readFromParcel(parcel); + } + + /** Get the mobile country code. */ + public String getMcc() { + return mMcc; + } + + /** Get the mobile network code. */ + public String getMnc() { + return mMnc; + } + + /** Get the service provider name. */ + @Nullable + public String getSpn() { + return mSpn; + } + + /** Get the international mobile subscriber identity. */ + @Nullable + public String getImsi() { + return mImsi; + } + + /** Get the group identifier level 1. */ + @Nullable + public String getGid1() { + return mGid1; + } + + /** Get the group identifier level 2. */ + @Nullable + public String getGid2() { + return mGid2; + } + + /** + * Returns the carrier id. + * @see TelephonyManager#getSimCarrierId() + */ + public int getCarrierId() { + return mCarrierId; + } + + /** + * A specific carrier ID returns the fine-grained carrier ID of the current subscription. + * It can represent the fact that a carrier may be in effect an aggregation of other carriers + * (ie in an MVNO type scenario) where each of these specific carriers which are used to make + * up the actual carrier service may have different carrier configurations. + * A specific carrier ID could also be used, for example, in a scenario where a carrier requires + * different carrier configuration for different service offering such as a prepaid plan. + * + * @see TelephonyManager#getSimSpecificCarrierId() + */ + public int getSpecificCarrierId() { + return mSpecificCarrierId; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + + CarrierIdentifier that = (CarrierIdentifier) obj; + return Objects.equals(mMcc, that.mMcc) + && Objects.equals(mMnc, that.mMnc) + && Objects.equals(mSpn, that.mSpn) + && Objects.equals(mImsi, that.mImsi) + && Objects.equals(mGid1, that.mGid1) + && Objects.equals(mGid2, that.mGid2) + && Objects.equals(mCarrierId, that.mCarrierId) + && Objects.equals(mSpecificCarrierId, that.mSpecificCarrierId); + } + + @Override + public int hashCode(){ + return Objects.hash(mMcc, mMnc, mSpn, mImsi, mGid1, mGid2, mCarrierId, mSpecificCarrierId); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeString(mMcc); + out.writeString(mMnc); + out.writeString(mSpn); + out.writeString(mImsi); + out.writeString(mGid1); + out.writeString(mGid2); + out.writeInt(mCarrierId); + out.writeInt(mSpecificCarrierId); + } + + @Override + public String toString() { + return "CarrierIdentifier{" + + "mcc=" + mMcc + + ",mnc=" + mMnc + + ",spn=" + mSpn + + ",imsi=" + Rlog.pii(false, mImsi) + + ",gid1=" + mGid1 + + ",gid2=" + mGid2 + + ",carrierid=" + mCarrierId + + ",specificCarrierId=" + mSpecificCarrierId + + "}"; + } + + /** @hide */ + public void readFromParcel(Parcel in) { + mMcc = in.readString(); + mMnc = in.readString(); + mSpn = in.readString(); + mImsi = in.readString(); + mGid1 = in.readString(); + mGid2 = in.readString(); + mCarrierId = in.readInt(); + mSpecificCarrierId = in.readInt(); + } + + /** @hide */ + public interface MatchType { + int ALL = 0; + int SPN = 1; + int IMSI_PREFIX = 2; + int GID1 = 3; + int GID2 = 4; + } +} diff --git a/telephony/java/android/service/carrier/CarrierService.java b/telephony/java/android/service/carrier/CarrierService.java new file mode 100644 index 000000000000..eefc1b70bac9 --- /dev/null +++ b/telephony/java/android/service/carrier/CarrierService.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.service.carrier; + +import android.annotation.CallSuper; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.IBinder; +import android.os.PersistableBundle; +import android.os.ResultReceiver; +import android.telephony.TelephonyRegistryManager; +import android.util.Log; + +/** + * A service that exposes carrier-specific functionality to the system. + * <p> + * To extend this class, you must declare the service in your manifest file to require the + * {@link android.Manifest.permission#BIND_CARRIER_SERVICES} permission and include an intent + * filter with the {@link #CARRIER_SERVICE_INTERFACE}. If the service should have a long-lived + * binding, set <code>android.service.carrier.LONG_LIVED_BINDING</code> to <code>true</code> in the + * service's metadata. For example: + * </p> + * + * <pre>{@code + * <service android:name=".MyCarrierService" + * android:label="@string/service_name" + * android:permission="android.permission.BIND_CARRIER_SERVICES"> + * <intent-filter> + * <action android:name="android.service.carrier.CarrierService" /> + * </intent-filter> + * <meta-data android:name="android.service.carrier.LONG_LIVED_BINDING" + * android:value="true" /> + * </service> + * }</pre> + */ +public abstract class CarrierService extends Service { + + private static final String LOG_TAG = "CarrierService"; + + public static final String CARRIER_SERVICE_INTERFACE = "android.service.carrier.CarrierService"; + + private final ICarrierService.Stub mStubWrapper; + + public CarrierService() { + mStubWrapper = new ICarrierServiceWrapper(); + } + + /** + * Override this method to set carrier configuration. + * <p> + * This method will be called by telephony services to get carrier-specific configuration + * values. The returned config will be saved by the system until, + * <ol> + * <li>The carrier app package is updated, or</li> + * <li>The carrier app requests a reload with + * {@link android.telephony.CarrierConfigManager#notifyConfigChangedForSubId + * notifyConfigChangedForSubId}.</li> + * </ol> + * This method can be called after a SIM card loads, which may be before or after boot. + * </p> + * <p> + * This method should not block for a long time. If expensive operations (e.g. network access) + * are required, this method can schedule the work and return null. Then, use + * {@link android.telephony.CarrierConfigManager#notifyConfigChangedForSubId + * notifyConfigChangedForSubId} to trigger a reload when the config is ready. + * </p> + * <p> + * Implementations should use the keys defined in {@link android.telephony.CarrierConfigManager + * CarrierConfigManager}. Any configuration values not set in the returned {@link + * PersistableBundle} may be overridden by the system's default configuration service. + * </p> + * + * @param id contains details about the current carrier that can be used do decide what + * configuration values to return. Instead of using details like MCCMNC to decide + * current carrier, it also contains subscription carrier id + * {@link android.telephony.TelephonyManager#getSimCarrierId()}, a platform-wide + * unique identifier for each carrier, CarrierConfigService can directly use carrier + * id as the key to look up the carrier info. + * @return a {@link PersistableBundle} object containing the configuration or null if default + * values should be used. + */ + public abstract PersistableBundle onLoadConfig(CarrierIdentifier id); + + /** + * Informs the system of an intentional upcoming carrier network change by + * a carrier app. This call is optional and is only used to allow the + * system to provide alternative UI while telephony is performing an action + * that may result in intentional, temporary network lack of connectivity. + * <p> + * Based on the active parameter passed in, this method will either show or + * hide the alternative UI. There is no timeout associated with showing + * this UX, so a carrier app must be sure to call with active set to false + * sometime after calling with it set to true. + * <p> + * Requires Permission: calling app has carrier privileges. + * + * @param active Whether the carrier network change is or shortly will be + * active. Set this value to true to begin showing + * alternative UI and false to stop. + * @see android.telephony.TelephonyManager#hasCarrierPrivileges + */ + public final void notifyCarrierNetworkChange(boolean active) { + TelephonyRegistryManager telephonyRegistryMgr = + (TelephonyRegistryManager) this.getSystemService( + Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryMgr != null) { + telephonyRegistryMgr.notifyCarrierNetworkChange(active); + } + } + + /** + * If overriding this method, call through to the super method for any unknown actions. + * {@inheritDoc} + */ + @Override + @CallSuper + public IBinder onBind(Intent intent) { + return mStubWrapper; + } + + /** + * A wrapper around ICarrierService that forwards calls to implementations of + * {@link CarrierService}. + * @hide + */ + public class ICarrierServiceWrapper extends ICarrierService.Stub { + /** @hide */ + public static final int RESULT_OK = 0; + /** @hide */ + public static final int RESULT_ERROR = 1; + /** @hide */ + public static final String KEY_CONFIG_BUNDLE = "config_bundle"; + + @Override + public void getCarrierConfig(CarrierIdentifier id, ResultReceiver result) { + try { + Bundle data = new Bundle(); + data.putParcelable(KEY_CONFIG_BUNDLE, CarrierService.this.onLoadConfig(id)); + result.send(RESULT_OK, data); + } catch (Exception e) { + Log.e(LOG_TAG, "Error in onLoadConfig: " + e.getMessage(), e); + result.send(RESULT_ERROR, null); + } + } + } +} diff --git a/telephony/java/android/service/carrier/ICarrierService.aidl b/telephony/java/android/service/carrier/ICarrierService.aidl new file mode 100644 index 000000000000..ac6f9614d8f5 --- /dev/null +++ b/telephony/java/android/service/carrier/ICarrierService.aidl @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2015, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.carrier; + +import android.os.PersistableBundle; +import android.os.ResultReceiver; +import android.service.carrier.CarrierIdentifier; + +/** + * Service used to expose carrier-specific functionality to the system. + * + * @see android.service.carrier.CarrierService + * @hide + */ +interface ICarrierService { + + /** @see android.service.carrier.CarrierService#onLoadConfig */ + oneway void getCarrierConfig(in CarrierIdentifier id, in ResultReceiver result); +} |