Merge "Added data service interface"
am: 3965e3bbc6
Change-Id: I7543aff2abadb4c6b2556f37cd5e763cb5a8c08c
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
540
telephony/java/android/telephony/data/DataService.java
Normal file
540
telephony/java/android/telephony/data/DataService.java
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
172
telephony/java/android/telephony/data/DataServiceCallback.java
Normal file
172
telephony/java/android/telephony/data/DataServiceCallback.java
Normal file
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
39
telephony/java/android/telephony/data/IDataService.aidl
Normal file
39
telephony/java/android/telephony/data/IDataService.aidl
Normal file
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user