diff options
| -rw-r--r-- | Android.bp | 2 | ||||
| -rw-r--r-- | api/system-current.txt | 32 | ||||
| -rw-r--r-- | telephony/java/android/telephony/data/DataService.java | 540 | ||||
| -rw-r--r-- | telephony/java/android/telephony/data/DataServiceCallback.java | 172 | ||||
| -rw-r--r-- | telephony/java/android/telephony/data/IDataService.aidl | 39 | ||||
| -rw-r--r-- | telephony/java/android/telephony/data/IDataServiceCallback.aidl | 33 |
6 files changed, 818 insertions, 0 deletions
diff --git a/Android.bp b/Android.bp index facc741578e0..f61115a5f0fe 100644 --- a/Android.bp +++ b/Android.bp @@ -455,6 +455,8 @@ java_library { "telecomm/java/com/android/internal/telecom/IInCallService.aidl", "telecomm/java/com/android/internal/telecom/ITelecomService.aidl", "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/ims/internal/aidl/IImsCallSessionListener.aidl", "telephony/java/android/telephony/ims/internal/aidl/IImsCapabilityCallback.aidl", "telephony/java/android/telephony/ims/internal/aidl/IImsConfig.aidl", diff --git a/api/system-current.txt b/api/system-current.txt index aa84f32d7fec..282dfaa6a25f 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4123,6 +4123,38 @@ package android.telephony.data { field public static final int TYPE_COMMON = 0; // 0x0 } + public abstract class DataService extends android.app.Service { + method public abstract android.telephony.data.DataService.DataServiceProvider createDataServiceProvider(int); + field public static final java.lang.String DATA_SERVICE_EXTRA_SLOT_ID = "android.telephony.data.extra.SLOT_ID"; + field public static final java.lang.String DATA_SERVICE_INTERFACE = "android.telephony.data.DataService"; + } + + public class DataService.DataServiceProvider { + ctor public DataService.DataServiceProvider(int); + method public void deactivateDataCall(int, boolean, boolean, android.telephony.data.DataServiceCallback); + method public void getDataCallList(android.telephony.data.DataServiceCallback); + method public final int getSlotId(); + method public final void notifyDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>); + method protected void onDestroy(); + method public void setDataProfile(java.util.List<android.telephony.data.DataProfile>, boolean, android.telephony.data.DataServiceCallback); + method public void setInitialAttachApn(android.telephony.data.DataProfile, boolean, android.telephony.data.DataServiceCallback); + method public void setupDataCall(int, android.telephony.data.DataProfile, boolean, boolean, boolean, android.net.LinkProperties, android.telephony.data.DataServiceCallback); + } + + public class DataServiceCallback { + method public void onDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>); + method public void onDeactivateDataCallComplete(int); + method public void onGetDataCallListComplete(int, java.util.List<android.telephony.data.DataCallResponse>); + method public void onSetDataProfileComplete(int); + method public void onSetInitialAttachApnComplete(int); + method public void onSetupDataCallComplete(int, android.telephony.data.DataCallResponse); + field public static final int RESULT_ERROR_BUSY = 3; // 0x3 + field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4 + field public static final int RESULT_ERROR_INVALID_ARG = 2; // 0x2 + field public static final int RESULT_ERROR_UNSUPPORTED = 1; // 0x1 + field public static final int RESULT_SUCCESS = 0; // 0x0 + } + } package android.telephony.ims { diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java new file mode 100644 index 000000000000..ea0817551369 --- /dev/null +++ b/telephony/java/android/telephony/data/DataService.java @@ -0,0 +1,540 @@ +/* + * Copyright 2017 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.CallSuper; +import android.annotation.SystemApi; +import android.app.Service; +import android.content.Intent; +import android.net.LinkProperties; +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; +import android.telephony.Rlog; +import android.telephony.SubscriptionManager; +import android.util.SparseArray; + +import java.util.ArrayList; +import java.util.List; + +/** + * Base class of data service. Services that extend DataService must register the service in + * their AndroidManifest to be detected by the framework. They must be protected by the permission + * "android.permission.BIND_DATA_SERVICE". The data service definition in the manifest must follow + * the following format: + * ... + * <service android:name=".xxxDataService" + * android:permission="android.permission.BIND_DATA_SERVICE" > + * <intent-filter> + * <action android:name="android.telephony.data.DataService" /> + * </intent-filter> + * </service> + * @hide + */ +@SystemApi +public abstract class DataService extends Service { + private static final String TAG = DataService.class.getSimpleName(); + + public static final String DATA_SERVICE_INTERFACE = "android.telephony.data.DataService"; + public static final String DATA_SERVICE_EXTRA_SLOT_ID = "android.telephony.data.extra.SLOT_ID"; + + private static final int DATA_SERVICE_INTERNAL_REQUEST_INITIALIZE_SERVICE = 1; + private static final int DATA_SERVICE_REQUEST_SETUP_DATA_CALL = 2; + private static final int DATA_SERVICE_REQUEST_DEACTIVATE_DATA_CALL = 3; + private static final int DATA_SERVICE_REQUEST_SET_INITIAL_ATTACH_APN = 4; + private static final int DATA_SERVICE_REQUEST_SET_DATA_PROFILE = 5; + private static final int DATA_SERVICE_REQUEST_GET_DATA_CALL_LIST = 6; + private static final int DATA_SERVICE_REQUEST_REGISTER_DATA_CALL_LIST_CHANGED = 7; + private static final int DATA_SERVICE_REQUEST_UNREGISTER_DATA_CALL_LIST_CHANGED = 8; + private static final int DATA_SERVICE_INDICATION_DATA_CALL_LIST_CHANGED = 9; + + private final HandlerThread mHandlerThread; + + private final DataServiceHandler mHandler; + + private final SparseArray<DataServiceProvider> mServiceMap = new SparseArray<>(); + + private final SparseArray<IDataServiceWrapper> mBinderMap = new SparseArray<>(); + + /** + * The abstract class of the actual data service implementation. The data service provider + * must extend this class to support data connection. Note that each instance of data service + * provider is associated with one physical SIM slot. + */ + public class DataServiceProvider { + + private final int mSlotId; + + private final List<IDataServiceCallback> mDataCallListChangedCallbacks = new ArrayList<>(); + + /** + * Constructor + * @param slotId SIM slot id the data service provider associated with. + */ + public DataServiceProvider(int slotId) { + mSlotId = slotId; + } + + /** + * @return SIM slot id the data service provider associated with. + */ + public final int getSlotId() { + return mSlotId; + } + + /** + * Setup a data connection. The data service provider must implement this method to support + * establishing a packet data connection. When completed or error, the service must invoke + * the provided callback to notify the platform. + * + * @param accessNetworkType Access network type that the data call will be established on. + * Must be one of {@link AccessNetworkConstants.AccessNetworkType}. + * @param dataProfile Data profile used for data call setup. See {@link DataProfile} + * @param isRoaming True if the device is data roaming. + * @param allowRoaming True if data roaming is allowed by the user. + * @param isHandover True if the request is for IWLAN handover. + * @param linkProperties If {@code isHandover} is true, this is the link properties of the + * existing data connection, otherwise null. + * @param callback The result callback for this request. + */ + public void setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming, + boolean allowRoaming, boolean isHandover, + LinkProperties linkProperties, DataServiceCallback callback) { + // The default implementation is to return unsupported. + callback.onSetupDataCallComplete(DataServiceCallback.RESULT_ERROR_UNSUPPORTED, null); + } + + /** + * Deactivate a data connection. The data service provider must implement this method to + * support data connection tear down. When completed or error, the service must invoke the + * provided callback to notify the platform. + * + * @param cid Call id returned in the callback of {@link DataServiceProvider#setupDataCall( + * int, DataProfile, boolean, boolean, boolean, LinkProperties, DataServiceCallback)}. + * @param reasonRadioShutDown True if the deactivate request reason is device shut down. + * @param isHandover True if the request is for IWLAN handover. + * @param callback The result callback for this request. + */ + public void deactivateDataCall(int cid, boolean reasonRadioShutDown, boolean isHandover, + DataServiceCallback callback) { + // The default implementation is to return unsupported. + callback.onDeactivateDataCallComplete(DataServiceCallback.RESULT_ERROR_UNSUPPORTED); + } + + /** + * Set an APN to initial attach network. + * + * @param dataProfile Data profile used for data call setup. See {@link DataProfile}. + * @param isRoaming True if the device is data roaming. + * @param callback The result callback for this request. + */ + public void setInitialAttachApn(DataProfile dataProfile, boolean isRoaming, + DataServiceCallback callback) { + // The default implementation is to return unsupported. + callback.onSetInitialAttachApnComplete(DataServiceCallback.RESULT_ERROR_UNSUPPORTED); + } + + /** + * Send current carrier's data profiles to the data service for data call setup. This is + * only for CDMA carrier that can change the profile through OTA. The data service should + * always uses the latest data profile sent by the framework. + * + * @param dps A list of data profiles. + * @param isRoaming True if the device is data roaming. + * @param callback The result callback for this request. + */ + public void setDataProfile(List<DataProfile> dps, boolean isRoaming, + DataServiceCallback callback) { + // The default implementation is to return unsupported. + callback.onSetDataProfileComplete(DataServiceCallback.RESULT_ERROR_UNSUPPORTED); + } + + /** + * Get the active data call list. + * + * @param callback The result callback for this request. + */ + public void getDataCallList(DataServiceCallback callback) { + // The default implementation is to return unsupported. + callback.onGetDataCallListComplete(DataServiceCallback.RESULT_ERROR_UNSUPPORTED, null); + } + + private void registerForDataCallListChanged(IDataServiceCallback callback) { + synchronized (mDataCallListChangedCallbacks) { + mDataCallListChangedCallbacks.add(callback); + } + } + + private void unregisterForDataCallListChanged(IDataServiceCallback callback) { + synchronized (mDataCallListChangedCallbacks) { + mDataCallListChangedCallbacks.remove(callback); + } + } + + /** + * Notify the system that current data call list changed. Data service must invoke this + * method whenever there is any data call status changed. + * + * @param dataCallList List of the current active data call. + */ + public final void notifyDataCallListChanged(List<DataCallResponse> dataCallList) { + synchronized (mDataCallListChangedCallbacks) { + for (IDataServiceCallback callback : mDataCallListChangedCallbacks) { + mHandler.obtainMessage(DATA_SERVICE_INDICATION_DATA_CALL_LIST_CHANGED, mSlotId, + 0, new DataCallListChangedIndication(dataCallList, callback)) + .sendToTarget(); + } + } + } + + /** + * Called when the instance of data service is destroyed (e.g. got unbind or binder died). + */ + @CallSuper + protected void onDestroy() { + mDataCallListChangedCallbacks.clear(); + } + } + + private static final class SetupDataCallRequest { + public final int accessNetworkType; + public final DataProfile dataProfile; + public final boolean isRoaming; + public final boolean allowRoaming; + public final boolean isHandover; + public final LinkProperties linkProperties; + public final IDataServiceCallback callback; + SetupDataCallRequest(int accessNetworkType, DataProfile dataProfile, boolean isRoaming, + boolean allowRoaming, boolean isHandover, + LinkProperties linkProperties, IDataServiceCallback callback) { + this.accessNetworkType = accessNetworkType; + this.dataProfile = dataProfile; + this.isRoaming = isRoaming; + this.allowRoaming = allowRoaming; + this.linkProperties = linkProperties; + this.isHandover = isHandover; + this.callback = callback; + } + } + + private static final class DeactivateDataCallRequest { + public final int cid; + public final boolean reasonRadioShutDown; + public final boolean isHandover; + public final IDataServiceCallback callback; + DeactivateDataCallRequest(int cid, boolean reasonRadioShutDown, boolean isHandover, + IDataServiceCallback callback) { + this.cid = cid; + this.reasonRadioShutDown = reasonRadioShutDown; + this.isHandover = isHandover; + this.callback = callback; + } + } + + private static final class SetInitialAttachApnRequest { + public final DataProfile dataProfile; + public final boolean isRoaming; + public final IDataServiceCallback callback; + SetInitialAttachApnRequest(DataProfile dataProfile, boolean isRoaming, + IDataServiceCallback callback) { + this.dataProfile = dataProfile; + this.isRoaming = isRoaming; + this.callback = callback; + } + } + + private static final class SetDataProfileRequest { + public final List<DataProfile> dps; + public final boolean isRoaming; + public final IDataServiceCallback callback; + SetDataProfileRequest(List<DataProfile> dps, boolean isRoaming, + IDataServiceCallback callback) { + this.dps = dps; + this.isRoaming = isRoaming; + this.callback = callback; + } + } + + private static final class DataCallListChangedIndication { + public final List<DataCallResponse> dataCallList; + public final IDataServiceCallback callback; + DataCallListChangedIndication(List<DataCallResponse> dataCallList, + IDataServiceCallback callback) { + this.dataCallList = dataCallList; + this.callback = callback; + } + } + + private class DataServiceHandler extends Handler { + + DataServiceHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message message) { + IDataServiceCallback callback; + final int slotId = message.arg1; + DataServiceProvider service; + + synchronized (mServiceMap) { + service = mServiceMap.get(slotId); + } + + switch (message.what) { + case DATA_SERVICE_INTERNAL_REQUEST_INITIALIZE_SERVICE: + service = createDataServiceProvider(message.arg1); + if (service != null) { + mServiceMap.put(slotId, service); + } + break; + case DATA_SERVICE_REQUEST_SETUP_DATA_CALL: + if (service == null) break; + SetupDataCallRequest setupDataCallRequest = (SetupDataCallRequest) message.obj; + service.setupDataCall(setupDataCallRequest.accessNetworkType, + setupDataCallRequest.dataProfile, setupDataCallRequest.isRoaming, + setupDataCallRequest.allowRoaming, setupDataCallRequest.isHandover, + setupDataCallRequest.linkProperties, + new DataServiceCallback(setupDataCallRequest.callback)); + + break; + case DATA_SERVICE_REQUEST_DEACTIVATE_DATA_CALL: + if (service == null) break; + DeactivateDataCallRequest deactivateDataCallRequest = + (DeactivateDataCallRequest) message.obj; + service.deactivateDataCall(deactivateDataCallRequest.cid, + deactivateDataCallRequest.reasonRadioShutDown, + deactivateDataCallRequest.isHandover, + new DataServiceCallback(deactivateDataCallRequest.callback)); + break; + case DATA_SERVICE_REQUEST_SET_INITIAL_ATTACH_APN: + if (service == null) break; + SetInitialAttachApnRequest setInitialAttachApnRequest = + (SetInitialAttachApnRequest) message.obj; + service.setInitialAttachApn(setInitialAttachApnRequest.dataProfile, + setInitialAttachApnRequest.isRoaming, + new DataServiceCallback(setInitialAttachApnRequest.callback)); + break; + case DATA_SERVICE_REQUEST_SET_DATA_PROFILE: + if (service == null) break; + SetDataProfileRequest setDataProfileRequest = + (SetDataProfileRequest) message.obj; + service.setDataProfile(setDataProfileRequest.dps, + setDataProfileRequest.isRoaming, + new DataServiceCallback(setDataProfileRequest.callback)); + break; + case DATA_SERVICE_REQUEST_GET_DATA_CALL_LIST: + if (service == null) break; + + service.getDataCallList(new DataServiceCallback( + (IDataServiceCallback) message.obj)); + break; + case DATA_SERVICE_REQUEST_REGISTER_DATA_CALL_LIST_CHANGED: + if (service == null) break; + service.registerForDataCallListChanged((IDataServiceCallback) message.obj); + break; + case DATA_SERVICE_REQUEST_UNREGISTER_DATA_CALL_LIST_CHANGED: + if (service == null) break; + callback = (IDataServiceCallback) message.obj; + service.unregisterForDataCallListChanged(callback); + break; + case DATA_SERVICE_INDICATION_DATA_CALL_LIST_CHANGED: + if (service == null) break; + DataCallListChangedIndication indication = + (DataCallListChangedIndication) message.obj; + try { + indication.callback.onDataCallListChanged(indication.dataCallList); + } catch (RemoteException e) { + loge("Failed to call onDataCallListChanged. " + e); + } + break; + } + } + } + + private DataService() { + mHandlerThread = new HandlerThread(TAG); + mHandlerThread.start(); + + mHandler = new DataServiceHandler(mHandlerThread.getLooper()); + log("Data service created"); + } + + /** + * Create the instance of {@link DataServiceProvider}. Data service provider must override + * this method to facilitate the creation of {@link DataServiceProvider} instances. The system + * will call this method after binding the data service for each active SIM slot id. + * + * @param slotId SIM slot id the data service associated with. + * @return Data service object + */ + public abstract DataServiceProvider createDataServiceProvider(int slotId); + + /** @hide */ + @Override + public IBinder onBind(Intent intent) { + if (intent == null || !DATA_SERVICE_INTERFACE.equals(intent.getAction())) { + loge("Unexpected intent " + intent); + return null; + } + + int slotId = intent.getIntExtra( + DATA_SERVICE_EXTRA_SLOT_ID, SubscriptionManager.INVALID_SIM_SLOT_INDEX); + + if (!SubscriptionManager.isValidSlotIndex(slotId)) { + loge("Invalid slot id " + slotId); + return null; + } + + log("onBind: slot id=" + slotId); + + IDataServiceWrapper binder = mBinderMap.get(slotId); + if (binder == null) { + Message msg = mHandler.obtainMessage(DATA_SERVICE_INTERNAL_REQUEST_INITIALIZE_SERVICE); + msg.arg1 = slotId; + msg.sendToTarget(); + + binder = new IDataServiceWrapper(slotId); + mBinderMap.put(slotId, binder); + } + + return binder; + } + + /** @hide */ + @Override + public boolean onUnbind(Intent intent) { + int slotId = intent.getIntExtra(DATA_SERVICE_EXTRA_SLOT_ID, + SubscriptionManager.INVALID_SIM_SLOT_INDEX); + if (mBinderMap.get(slotId) != null) { + DataServiceProvider serviceImpl; + synchronized (mServiceMap) { + serviceImpl = mServiceMap.get(slotId); + } + if (serviceImpl != null) { + serviceImpl.onDestroy(); + } + mBinderMap.remove(slotId); + } + + // If all clients unbinds, quit the handler thread + if (mBinderMap.size() == 0) { + mHandlerThread.quit(); + } + + return false; + } + + /** @hide */ + @Override + public void onDestroy() { + synchronized (mServiceMap) { + for (int i = 0; i < mServiceMap.size(); i++) { + DataServiceProvider serviceImpl = mServiceMap.get(i); + if (serviceImpl != null) { + serviceImpl.onDestroy(); + } + } + mServiceMap.clear(); + } + + mHandlerThread.quit(); + } + + /** + * A wrapper around IDataService that forwards calls to implementations of {@link DataService}. + */ + private class IDataServiceWrapper extends IDataService.Stub { + + private final int mSlotId; + + IDataServiceWrapper(int slotId) { + mSlotId = slotId; + } + + @Override + public void setupDataCall(int accessNetworkType, DataProfile dataProfile, + boolean isRoaming, boolean allowRoaming, boolean isHandover, + LinkProperties linkProperties, IDataServiceCallback callback) { + mHandler.obtainMessage(DATA_SERVICE_REQUEST_SETUP_DATA_CALL, mSlotId, 0, + new SetupDataCallRequest(accessNetworkType, dataProfile, isRoaming, + allowRoaming, isHandover, linkProperties, callback)) + .sendToTarget(); + } + + @Override + public void deactivateDataCall(int cid, boolean reasonRadioShutDown, boolean isHandover, + IDataServiceCallback callback) { + mHandler.obtainMessage(DATA_SERVICE_REQUEST_DEACTIVATE_DATA_CALL, mSlotId, 0, + new DeactivateDataCallRequest(cid, reasonRadioShutDown, isHandover, callback)) + .sendToTarget(); + } + + @Override + public void setInitialAttachApn(DataProfile dataProfile, boolean isRoaming, + IDataServiceCallback callback) { + mHandler.obtainMessage(DATA_SERVICE_REQUEST_SET_INITIAL_ATTACH_APN, mSlotId, 0, + new SetInitialAttachApnRequest(dataProfile, isRoaming, callback)) + .sendToTarget(); + } + + @Override + public void setDataProfile(List<DataProfile> dps, boolean isRoaming, + IDataServiceCallback callback) { + mHandler.obtainMessage(DATA_SERVICE_REQUEST_SET_DATA_PROFILE, mSlotId, 0, + new SetDataProfileRequest(dps, isRoaming, callback)).sendToTarget(); + } + + @Override + public void getDataCallList(IDataServiceCallback callback) { + mHandler.obtainMessage(DATA_SERVICE_REQUEST_GET_DATA_CALL_LIST, mSlotId, 0, + callback).sendToTarget(); + } + + @Override + public void registerForDataCallListChanged(IDataServiceCallback callback) { + if (callback == null) { + loge("Callback is null"); + return; + } + mHandler.obtainMessage(DATA_SERVICE_REQUEST_REGISTER_DATA_CALL_LIST_CHANGED, mSlotId, + 0, callback).sendToTarget(); + } + + @Override + public void unregisterForDataCallListChanged(IDataServiceCallback callback) { + if (callback == null) { + loge("Callback is null"); + return; + } + mHandler.obtainMessage(DATA_SERVICE_REQUEST_UNREGISTER_DATA_CALL_LIST_CHANGED, mSlotId, + 0, callback).sendToTarget(); + } + } + + private void log(String s) { + Rlog.d(TAG, s); + } + + private void loge(String s) { + Rlog.e(TAG, s); + } +} diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java new file mode 100644 index 000000000000..b6a81f94028b --- /dev/null +++ b/telephony/java/android/telephony/data/DataServiceCallback.java @@ -0,0 +1,172 @@ +/* + * Copyright 2017 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.IntDef; +import android.annotation.SystemApi; +import android.os.RemoteException; +import android.telephony.Rlog; +import android.telephony.data.DataService.DataServiceProvider; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.ref.WeakReference; +import java.util.List; + +/** + * Data service callback, which is for bound data service to invoke for solicited and unsolicited + * response. The caller is responsible to create a callback object for each single asynchronous + * request. + * + * @hide + */ +@SystemApi +public class DataServiceCallback { + + private static final String mTag = DataServiceCallback.class.getSimpleName(); + + /** + * Result of data requests + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({RESULT_SUCCESS, RESULT_ERROR_UNSUPPORTED, RESULT_ERROR_INVALID_ARG, RESULT_ERROR_BUSY, + RESULT_ERROR_ILLEGAL_STATE}) + public @interface Result {} + + /** Request is completed successfully */ + public static final int RESULT_SUCCESS = 0; + /** Request is not support */ + public static final int RESULT_ERROR_UNSUPPORTED = 1; + /** Request contains invalid arguments */ + public static final int RESULT_ERROR_INVALID_ARG = 2; + /** Service is busy */ + public static final int RESULT_ERROR_BUSY = 3; + /** Request sent in illegal state */ + public static final int RESULT_ERROR_ILLEGAL_STATE = 4; + + private final WeakReference<IDataServiceCallback> mCallback; + + /** @hide */ + public DataServiceCallback(IDataServiceCallback callback) { + mCallback = new WeakReference<>(callback); + } + + /** + * Called to indicate result for the request {@link DataServiceProvider#setupDataCall(int, + * DataProfile, boolean, boolean, boolean, DataServiceCallback)}. + * + * @param result The result code. Must be one of the {@link Result}. + * @param response Setup data call response. + */ + public void onSetupDataCallComplete(@Result int result, DataCallResponse response) { + IDataServiceCallback callback = mCallback.get(); + if (callback != null) { + try { + callback.onSetupDataCallComplete(result, response); + } catch (RemoteException e) { + Rlog.e(mTag, "Failed to onSetupDataCallComplete on the remote"); + } + } + } + + /** + * Called to indicate result for the request {@link DataServiceProvider#deactivateDataCall(int, + * boolean, boolean, DataServiceCallback)}. + * + * @param result The result code. Must be one of the {@link Result}. + */ + public void onDeactivateDataCallComplete(@Result int result) { + IDataServiceCallback callback = mCallback.get(); + if (callback != null) { + try { + callback.onDeactivateDataCallComplete(result); + } catch (RemoteException e) { + Rlog.e(mTag, "Failed to onDeactivateDataCallComplete on the remote"); + } + } + } + + /** + * Called to indicate result for the request {@link DataServiceProvider#setInitialAttachApn( + * DataProfile, boolean, DataServiceCallback)}. + * + * @param result The result code. Must be one of the {@link Result}. + */ + public void onSetInitialAttachApnComplete(@Result int result) { + IDataServiceCallback callback = mCallback.get(); + if (callback != null) { + try { + callback.onSetInitialAttachApnComplete(result); + } catch (RemoteException e) { + Rlog.e(mTag, "Failed to onSetInitialAttachApnComplete on the remote"); + } + } + } + + /** + * Called to indicate result for the request {@link DataServiceProvider#setDataProfile(List, + * boolean, DataServiceCallback)}. + * + * @param result The result code. Must be one of the {@link Result}. + */ + @SystemApi + public void onSetDataProfileComplete(@Result int result) { + IDataServiceCallback callback = mCallback.get(); + if (callback != null) { + try { + callback.onSetDataProfileComplete(result); + } catch (RemoteException e) { + Rlog.e(mTag, "Failed to onSetDataProfileComplete on the remote"); + } + } + } + + /** + * Called to indicate result for the request {@link DataServiceProvider#getDataCallList( + * DataServiceCallback)}. + * + * @param result The result code. Must be one of the {@link Result}. + * @param dataCallList List of the current active data connection. + */ + public void onGetDataCallListComplete(@Result int result, List<DataCallResponse> dataCallList) { + IDataServiceCallback callback = mCallback.get(); + if (callback != null) { + try { + callback.onGetDataCallListComplete(result, dataCallList); + } catch (RemoteException e) { + Rlog.e(mTag, "Failed to onGetDataCallListComplete on the remote"); + } + } + } + + /** + * Called to indicate that data connection list changed. + * + * @param dataCallList List of the current active data connection. + */ + public void onDataCallListChanged(List<DataCallResponse> dataCallList) { + IDataServiceCallback callback = mCallback.get(); + if (callback != null) { + try { + callback.onDataCallListChanged(dataCallList); + } catch (RemoteException e) { + Rlog.e(mTag, "Failed to onDataCallListChanged on the remote"); + } + } + } +} diff --git a/telephony/java/android/telephony/data/IDataService.aidl b/telephony/java/android/telephony/data/IDataService.aidl new file mode 100644 index 000000000000..4eaaa252da02 --- /dev/null +++ b/telephony/java/android/telephony/data/IDataService.aidl @@ -0,0 +1,39 @@ +/* + * Copyright 2017 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.net.LinkProperties; +import android.telephony.data.DataProfile; +import android.telephony.data.IDataServiceCallback; + +/** + * {@hide} + */ +oneway interface IDataService +{ + void setupDataCall(int accessNetwork, in DataProfile dataProfile, boolean isRoaming, + boolean allowRoaming, boolean isHandover, in LinkProperties linkProperties, + IDataServiceCallback callback); + void deactivateDataCall(int cid, boolean reasonRadioShutDown, boolean isHandover, + IDataServiceCallback callback); + void setInitialAttachApn(in DataProfile dataProfile, boolean isRoaming, + IDataServiceCallback callback); + void setDataProfile(in List<DataProfile> dps, boolean isRoaming, IDataServiceCallback callback); + void getDataCallList(IDataServiceCallback callback); + void registerForDataCallListChanged(IDataServiceCallback callback); + void unregisterForDataCallListChanged(IDataServiceCallback callback); +} diff --git a/telephony/java/android/telephony/data/IDataServiceCallback.aidl b/telephony/java/android/telephony/data/IDataServiceCallback.aidl new file mode 100644 index 000000000000..856185b2974f --- /dev/null +++ b/telephony/java/android/telephony/data/IDataServiceCallback.aidl @@ -0,0 +1,33 @@ +/* + * Copyright 2017 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.DataCallResponse; + +/** + * The call back interface + * @hide + */ +oneway interface IDataServiceCallback +{ + void onSetupDataCallComplete(int result, in DataCallResponse dataCallResponse); + void onDeactivateDataCallComplete(int result); + void onSetInitialAttachApnComplete(int result); + void onSetDataProfileComplete(int result); + void onGetDataCallListComplete(int result, in List<DataCallResponse> dataCallList); + void onDataCallListChanged(in List<DataCallResponse> dataCallList); +} |