Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63de9eab authored by Jack Yu's avatar Jack Yu Committed by Gerrit Code Review
Browse files

Merge "Added qualified networks services"

parents a6d6bf81 a3ab5750
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -488,6 +488,8 @@ java_library {
        "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",
+13 −0
Original line number Diff line number Diff line
@@ -5426,6 +5426,19 @@ package android.telephony.data {
    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 {
+28 −0
Original line number Diff line number Diff line
/*
 * 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);
}
+26 −0
Original line number Diff line number Diff line
/*
 * 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);
}
+286 −0
Original line number Diff line number Diff line
/*
 * 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);
    }
}