Merge "Added qualified networks services" am: 63de9eabec am: f02b6d6679
am: 507bdec1ab
Change-Id: If60c3165dab5316c17cfe7ba0e5e7d8dab782636
diff --git a/Android.bp b/Android.bp
index 1586440..7f4756f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -495,6 +495,8 @@
"telecomm/java/com/android/internal/telecom/RemoteServiceCallback.aidl",
"telephony/java/android/telephony/data/IDataService.aidl",
"telephony/java/android/telephony/data/IDataServiceCallback.aidl",
+ "telephony/java/android/telephony/data/IQualifiedNetworksService.aidl",
+ "telephony/java/android/telephony/data/IQualifiedNetworksServiceCallback.aidl",
"telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl",
"telephony/java/android/telephony/ims/aidl/IImsCapabilityCallback.aidl",
"telephony/java/android/telephony/ims/aidl/IImsConfig.aidl",
diff --git a/api/system-current.txt b/api/system-current.txt
index 9a489d8..6aef50e 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5553,6 +5553,19 @@
field public static final int RESULT_SUCCESS = 0; // 0x0
}
+ public abstract class QualifiedNetworksService extends android.app.Service {
+ ctor public QualifiedNetworksService();
+ method public abstract android.telephony.data.QualifiedNetworksService.NetworkAvailabilityUpdater createNetworkAvailabilityUpdater(int);
+ field public static final java.lang.String QUALIFIED_NETWORKS_SERVICE_INTERFACE = "android.telephony.data.QualifiedNetworksService";
+ }
+
+ public abstract class QualifiedNetworksService.NetworkAvailabilityUpdater implements java.lang.AutoCloseable {
+ ctor public QualifiedNetworksService.NetworkAvailabilityUpdater(int);
+ method public abstract void close();
+ method public final int getSlotIndex();
+ method public final void updateQualifiedNetworkTypes(int, int[]);
+ }
+
}
package android.telephony.euicc {
diff --git a/telephony/java/android/telephony/data/IQualifiedNetworksService.aidl b/telephony/java/android/telephony/data/IQualifiedNetworksService.aidl
new file mode 100644
index 0000000..9c80cb7
--- /dev/null
+++ b/telephony/java/android/telephony/data/IQualifiedNetworksService.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2018 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.telephony.data;
+
+import android.telephony.data.IQualifiedNetworksServiceCallback;
+
+/**
+ * {@hide}
+ */
+interface IQualifiedNetworksService
+{
+ oneway void createNetworkAvailabilityUpdater(int slotId, IQualifiedNetworksServiceCallback callback);
+ oneway void removeNetworkAvailabilityUpdater(int slotId);
+}
diff --git a/telephony/java/android/telephony/data/IQualifiedNetworksServiceCallback.aidl b/telephony/java/android/telephony/data/IQualifiedNetworksServiceCallback.aidl
new file mode 100644
index 0000000..e8e1f01
--- /dev/null
+++ b/telephony/java/android/telephony/data/IQualifiedNetworksServiceCallback.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018 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.telephony.data;
+
+/**
+ * The qualified networks service call back interface
+ * @hide
+ */
+oneway interface IQualifiedNetworksServiceCallback
+{
+ void onQualifiedNetworkTypesChanged(int apnType, in int[] qualifiedNetworkTypesList);
+}
diff --git a/telephony/java/android/telephony/data/QualifiedNetworksService.java b/telephony/java/android/telephony/data/QualifiedNetworksService.java
new file mode 100644
index 0000000..bb89f19
--- /dev/null
+++ b/telephony/java/android/telephony/data/QualifiedNetworksService.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright 2018 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.telephony.data;
+
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.Rlog;
+import android.telephony.data.ApnSetting.ApnType;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Base class of the qualified networks service. Services that extend QualifiedNetworksService must
+ * register the service in their AndroidManifest to be detected by the framework. They must be
+ * protected by the permission "android.permission.BIND_TELEPHONY_QUALIFIED_NETWORKS_SERVICE".
+ * The qualified networks service definition in the manifest must follow the following format:
+ * ...
+ * <service android:name=".xxxQualifiedNetworksService"
+ * android:permission="android.permission.BIND_TELEPHONY_QUALIFIED_NETWORKS_SERVICE" >
+ * <intent-filter>
+ * <action android:name="android.telephony.data.QualifiedNetworksService" />
+ * </intent-filter>
+ * </service>
+ * @hide
+ */
+@SystemApi
+public abstract class QualifiedNetworksService extends Service {
+ private static final String TAG = QualifiedNetworksService.class.getSimpleName();
+
+ public static final String QUALIFIED_NETWORKS_SERVICE_INTERFACE =
+ "android.telephony.data.QualifiedNetworksService";
+
+ private static final int QNS_CREATE_NETWORK_AVAILABILITY_UPDATER = 1;
+ private static final int QNS_REMOVE_NETWORK_AVAILABILITY_UPDATER = 2;
+ private static final int QNS_REMOVE_ALL_NETWORK_AVAILABILITY_UPDATERS = 3;
+ private static final int QNS_UPDATE_QUALIFIED_NETWORKS = 4;
+
+ private final HandlerThread mHandlerThread;
+
+ private final QualifiedNetworksServiceHandler mHandler;
+
+ private final SparseArray<NetworkAvailabilityUpdater> mUpdaters = new SparseArray<>();
+
+ /** @hide */
+ @VisibleForTesting
+ public final IQualifiedNetworksServiceWrapper mBinder = new IQualifiedNetworksServiceWrapper();
+
+ /**
+ * The abstract class of the network availability updater implementation. The vendor qualified
+ * network service must extend this class to report the available networks for data
+ * connection setup. Note that each instance of network availability updater is associated with
+ * one physical SIM slot.
+ */
+ public abstract class NetworkAvailabilityUpdater implements AutoCloseable {
+ private final int mSlotIndex;
+
+ private IQualifiedNetworksServiceCallback mCallback;
+
+ /**
+ * Qualified networks for each APN type. Key is the {@link ApnType}, value is the array
+ * of available networks.
+ */
+ private SparseArray<int[]> mQualifiedNetworkTypesList = new SparseArray<>();
+
+ /**
+ * Constructor
+ * @param slotIndex SIM slot index the network availability updater associated with.
+ */
+ public NetworkAvailabilityUpdater(int slotIndex) {
+ mSlotIndex = slotIndex;
+ }
+
+ /**
+ * @return SIM slot index the network availability updater associated with.
+ */
+ public final int getSlotIndex() {
+ return mSlotIndex;
+ }
+
+ private void registerForQualifiedNetworkTypesChanged(
+ IQualifiedNetworksServiceCallback callback) {
+ mCallback = callback;
+
+ // Force sending the qualified networks upon registered.
+ if (mCallback != null) {
+ for (int i = 0; i < mQualifiedNetworkTypesList.size(); i++) {
+ try {
+ mCallback.onQualifiedNetworkTypesChanged(
+ mQualifiedNetworkTypesList.keyAt(i),
+ mQualifiedNetworkTypesList.valueAt(i));
+ } catch (RemoteException e) {
+ loge("Failed to call onQualifiedNetworksChanged. " + e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Update the qualified networks list. Network availability updater must invoke this method
+ * whenever the qualified networks changes. If this method is never invoked for certain
+ * APN type, then frameworks will always use the default (i.e. cellular) data and network
+ * service.
+ *
+ * @param apnType APN type of the qualified networks
+ * @param qualifiedNetworkTypes List of network types which are qualified for data
+ * connection setup for {@link @apnType} in the preferred order. Each element in the array
+ * is a {@link AccessNetworkType}. An empty list or null indicates no networks are qualified
+ * for data setup.
+ */
+ public final void updateQualifiedNetworkTypes(@ApnType int apnType,
+ int[] qualifiedNetworkTypes) {
+ mHandler.obtainMessage(QNS_UPDATE_QUALIFIED_NETWORKS, mSlotIndex, apnType,
+ qualifiedNetworkTypes).sendToTarget();
+ }
+
+ private void onUpdateQualifiedNetworkTypes(@ApnType int apnType,
+ int[] qualifiedNetworkTypes) {
+ mQualifiedNetworkTypesList.put(apnType, qualifiedNetworkTypes);
+ if (mCallback != null) {
+ try {
+ mCallback.onQualifiedNetworkTypesChanged(apnType, qualifiedNetworkTypes);
+ } catch (RemoteException e) {
+ loge("Failed to call onQualifiedNetworksChanged. " + e);
+ }
+ }
+ }
+
+ /**
+ * Called when the qualified networks updater is removed. The extended class should
+ * implement this method to perform clean up works.
+ */
+ @Override
+ public abstract void close();
+ }
+
+ private class QualifiedNetworksServiceHandler extends Handler {
+ QualifiedNetworksServiceHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message message) {
+ IQualifiedNetworksServiceCallback callback;
+ final int slotIndex = message.arg1;
+ NetworkAvailabilityUpdater updater = mUpdaters.get(slotIndex);
+
+ switch (message.what) {
+ case QNS_CREATE_NETWORK_AVAILABILITY_UPDATER:
+ if (mUpdaters.get(slotIndex) != null) {
+ loge("Network availability updater for slot " + slotIndex
+ + " already existed.");
+ return;
+ }
+
+ updater = createNetworkAvailabilityUpdater(slotIndex);
+ if (updater != null) {
+ mUpdaters.put(slotIndex, updater);
+
+ callback = (IQualifiedNetworksServiceCallback) message.obj;
+ updater.registerForQualifiedNetworkTypesChanged(callback);
+ } else {
+ loge("Failed to create network availability updater. slot index = "
+ + slotIndex);
+ }
+ break;
+
+ case QNS_REMOVE_NETWORK_AVAILABILITY_UPDATER:
+ if (updater != null) {
+ updater.close();
+ mUpdaters.remove(slotIndex);
+ }
+ break;
+
+ case QNS_REMOVE_ALL_NETWORK_AVAILABILITY_UPDATERS:
+ for (int i = 0; i < mUpdaters.size(); i++) {
+ updater = mUpdaters.get(i);
+ if (updater != null) {
+ updater.close();
+ }
+ }
+ mUpdaters.clear();
+ break;
+
+ case QNS_UPDATE_QUALIFIED_NETWORKS:
+ if (updater == null) break;
+ updater.onUpdateQualifiedNetworkTypes(message.arg2, (int[]) message.obj);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Default constructor.
+ */
+ public QualifiedNetworksService() {
+ mHandlerThread = new HandlerThread(TAG);
+ mHandlerThread.start();
+
+ mHandler = new QualifiedNetworksServiceHandler(mHandlerThread.getLooper());
+ log("Qualified networks service created");
+ }
+
+ /**
+ * Create the instance of {@link NetworkAvailabilityUpdater}. Vendor qualified network service
+ * must override this method to facilitate the creation of {@link NetworkAvailabilityUpdater}
+ * instances. The system will call this method after binding the qualified networks service for
+ * each active SIM slot index.
+ *
+ * @param slotIndex SIM slot index the qualified networks service associated with.
+ * @return Qualified networks service instance
+ */
+ public abstract NetworkAvailabilityUpdater createNetworkAvailabilityUpdater(int slotIndex);
+
+ /** @hide */
+ @Override
+ public IBinder onBind(Intent intent) {
+ if (intent == null || !QUALIFIED_NETWORKS_SERVICE_INTERFACE.equals(intent.getAction())) {
+ loge("Unexpected intent " + intent);
+ return null;
+ }
+ return mBinder;
+ }
+
+ /** @hide */
+ @Override
+ public boolean onUnbind(Intent intent) {
+ mHandler.obtainMessage(QNS_REMOVE_ALL_NETWORK_AVAILABILITY_UPDATERS).sendToTarget();
+ return false;
+ }
+
+ /** @hide */
+ @Override
+ public void onDestroy() {
+ mHandlerThread.quit();
+ }
+
+ /**
+ * A wrapper around IQualifiedNetworksService that forwards calls to implementations of
+ * {@link QualifiedNetworksService}.
+ */
+ private class IQualifiedNetworksServiceWrapper extends IQualifiedNetworksService.Stub {
+ @Override
+ public void createNetworkAvailabilityUpdater(int slotIndex,
+ IQualifiedNetworksServiceCallback callback) {
+ mHandler.obtainMessage(QNS_CREATE_NETWORK_AVAILABILITY_UPDATER, slotIndex, 0,
+ callback).sendToTarget();
+ }
+
+ @Override
+ public void removeNetworkAvailabilityUpdater(int slotIndex) {
+ mHandler.obtainMessage(QNS_REMOVE_NETWORK_AVAILABILITY_UPDATER, slotIndex, 0)
+ .sendToTarget();
+ }
+ }
+
+ private void log(String s) {
+ Rlog.d(TAG, s);
+ }
+
+ private void loge(String s) {
+ Rlog.e(TAG, s);
+ }
+}