Merge "Add APIs for ImsService RCS UCE implementation"
am: 01f0935054
Change-Id: Ic4953e05afa2187e4566aaba5799dc800e61f548
This commit is contained in:
234
telephony/java/android/telephony/ims/ImsRcsManager.java
Normal file
234
telephony/java/android/telephony/ims/ImsRcsManager.java
Normal file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright (C) 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.ims;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.content.Context;
|
||||
import android.os.Binder;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.ims.aidl.IImsCapabilityCallback;
|
||||
import android.telephony.ims.feature.ImsFeature;
|
||||
import android.telephony.ims.feature.RcsFeature;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Manager for interfacing with the framework RCS services, including the User Capability Exchange
|
||||
* (UCE) service, as well as managing user settings.
|
||||
*
|
||||
* Use {@link #createForSubscriptionId(Context, int)} to create an instance of this manager.
|
||||
* @hide
|
||||
*/
|
||||
public class ImsRcsManager {
|
||||
|
||||
/**
|
||||
* Receives RCS availability status updates from the ImsService.
|
||||
*
|
||||
* @see #isAvailable(int)
|
||||
* @see #registerRcsAvailabilityCallback(Executor, AvailabilityCallback)
|
||||
* @see #unregisterRcsAvailabilityCallback(AvailabilityCallback)
|
||||
*/
|
||||
public static class AvailabilityCallback {
|
||||
|
||||
private static class CapabilityBinder extends IImsCapabilityCallback.Stub {
|
||||
|
||||
private final AvailabilityCallback mLocalCallback;
|
||||
private Executor mExecutor;
|
||||
|
||||
CapabilityBinder(AvailabilityCallback c) {
|
||||
mLocalCallback = c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCapabilitiesStatusChanged(int config) {
|
||||
if (mLocalCallback == null) return;
|
||||
|
||||
Binder.withCleanCallingIdentity(() ->
|
||||
mExecutor.execute(() -> mLocalCallback.onAvailabilityChanged(
|
||||
new RcsFeature.RcsImsCapabilities(config))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueryCapabilityConfiguration(int capability, int radioTech,
|
||||
boolean isEnabled) {
|
||||
// This is not used for public interfaces.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChangeCapabilityConfigurationError(int capability, int radioTech,
|
||||
@ImsFeature.ImsCapabilityError int reason) {
|
||||
// This is not used for public interfaces
|
||||
}
|
||||
|
||||
private void setExecutor(Executor executor) {
|
||||
mExecutor = executor;
|
||||
}
|
||||
}
|
||||
|
||||
private final CapabilityBinder mBinder = new CapabilityBinder(this);
|
||||
|
||||
/**
|
||||
* The availability of the feature's capabilities has changed to either available or
|
||||
* unavailable.
|
||||
* <p>
|
||||
* If unavailable, the feature does not support the capability at the current time. This may
|
||||
* be due to network or subscription provisioning changes, such as the IMS registration
|
||||
* being lost, network type changing, or OMA-DM provisioning updates.
|
||||
*
|
||||
* @param capabilities The new availability of the capabilities.
|
||||
*/
|
||||
public void onAvailabilityChanged(RcsFeature.RcsImsCapabilities capabilities) {
|
||||
}
|
||||
|
||||
/**@hide*/
|
||||
public final IImsCapabilityCallback getBinder() {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
private void setExecutor(Executor executor) {
|
||||
mBinder.setExecutor(executor);
|
||||
}
|
||||
}
|
||||
|
||||
private final int mSubId;
|
||||
private final Context mContext;
|
||||
|
||||
|
||||
/**
|
||||
* Create an instance of ImsRcsManager for the subscription id specified.
|
||||
*
|
||||
* @param context The context to create this ImsRcsManager instance within.
|
||||
* @param subscriptionId The ID of the subscription that this ImsRcsManager will use.
|
||||
* @see android.telephony.SubscriptionManager#getActiveSubscriptionInfoList()
|
||||
* @throws IllegalArgumentException if the subscription is invalid.
|
||||
* @hide
|
||||
*/
|
||||
public static ImsRcsManager createForSubscriptionId(Context context, int subscriptionId) {
|
||||
if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
|
||||
throw new IllegalArgumentException("Invalid subscription ID");
|
||||
}
|
||||
|
||||
return new ImsRcsManager(context, subscriptionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link #createForSubscriptionId(Context, int)} to create an instance of this class.
|
||||
*/
|
||||
private ImsRcsManager(Context context, int subId) {
|
||||
mContext = context;
|
||||
mSubId = subId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an {@link AvailabilityCallback} with the system, which will provide RCS
|
||||
* availability updates for the subscription specified.
|
||||
*
|
||||
* Use {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to
|
||||
* subscription changed events and call
|
||||
* {@link #unregisterRcsAvailabilityCallback(AvailabilityCallback)} to clean up after a
|
||||
* subscription is removed.
|
||||
* <p>
|
||||
* When the callback is registered, it will initiate the callback c to be called with the
|
||||
* current capabilities.
|
||||
*
|
||||
* @param executor The executor the callback events should be run on.
|
||||
* @param c The RCS {@link AvailabilityCallback} to be registered.
|
||||
* @see #unregisterRcsAvailabilityCallback(AvailabilityCallback)
|
||||
* @throws ImsException if the subscription associated with this instance of
|
||||
* {@link ImsRcsManager} is valid, but the ImsService associated with the subscription is not
|
||||
* available. This can happen if the ImsService has crashed, for example, or if the subscription
|
||||
* becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
|
||||
public void registerRcsAvailabilityCallback(@CallbackExecutor Executor executor,
|
||||
@NonNull AvailabilityCallback c) throws ImsException {
|
||||
if (c == null) {
|
||||
throw new IllegalArgumentException("Must include a non-null AvailabilityCallback.");
|
||||
}
|
||||
if (executor == null) {
|
||||
throw new IllegalArgumentException("Must include a non-null Executor.");
|
||||
}
|
||||
c.setExecutor(executor);
|
||||
throw new UnsupportedOperationException("registerRcsAvailabilityCallback is not"
|
||||
+ "supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an existing RCS {@link AvailabilityCallback}.
|
||||
* <p>
|
||||
* When the subscription associated with this callback is removed (SIM removed, ESIM swap,
|
||||
* etc...), this callback will automatically be unregistered. If this method is called for an
|
||||
* inactive subscription, it will result in a no-op.
|
||||
* @param c The RCS {@link AvailabilityCallback} to be removed.
|
||||
* @see #registerRcsAvailabilityCallback(Executor, AvailabilityCallback)
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
|
||||
public void unregisterRcsAvailabilityCallback(@NonNull AvailabilityCallback c) {
|
||||
if (c == null) {
|
||||
throw new IllegalArgumentException("Must include a non-null AvailabilityCallback.");
|
||||
}
|
||||
throw new UnsupportedOperationException("unregisterRcsAvailabilityCallback is not"
|
||||
+ "supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for the capability of an IMS RCS service provided by the framework.
|
||||
* <p>
|
||||
* This only reports the status of RCS capabilities provided by the framework, not necessarily
|
||||
* RCS capabilities provided over-the-top by applications.
|
||||
*
|
||||
* @param capability The RCS capability to query.
|
||||
* @return true if the RCS capability is capable for this subscription, false otherwise. This
|
||||
* does not necessarily mean that we are registered for IMS and the capability is available, but
|
||||
* rather the subscription is capable of this service over IMS.
|
||||
* @see #isAvailable(int)
|
||||
* @see android.telephony.CarrierConfigManager#KEY_USE_RCS_PRESENCE_BOOL
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
|
||||
public boolean isCapable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
|
||||
throw new UnsupportedOperationException("isCapable is not supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the availability of an IMS RCS capability.
|
||||
* <p>
|
||||
* This only reports the status of RCS capabilities provided by the framework, not necessarily
|
||||
* RCS capabilities provided by over-the-top by applications.
|
||||
*
|
||||
* @param capability the RCS capability to query.
|
||||
* @return true if the RCS capability is currently available for the associated subscription,
|
||||
* false otherwise. If the capability is available, IMS is registered and the service is
|
||||
* currently available over IMS.
|
||||
* @see #isCapable(int)
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
|
||||
public boolean isAvailable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
|
||||
throw new UnsupportedOperationException("isAvailable is not supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A new {@link RcsUceAdapter} used for User Capability Exchange (UCE) operations for
|
||||
* this subscription.
|
||||
*/
|
||||
@NonNull
|
||||
public RcsUceAdapter getUceAdapter() {
|
||||
return new RcsUceAdapter(mSubId);
|
||||
}
|
||||
}
|
||||
@@ -387,6 +387,24 @@ public class ProvisioningManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the framework that an RCS autoconfiguration XML file has been received for
|
||||
* provisioning.
|
||||
* @param config The XML file to be read. ASCII/UTF8 encoded text if not compressed.
|
||||
* @param isCompressed The XML file is compressed in gzip format and must be decompressed
|
||||
* before being read.
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
|
||||
public void notifyRcsAutoConfigurationReceived(@NonNull byte[] config, boolean isCompressed) {
|
||||
if (config == null) {
|
||||
throw new IllegalArgumentException("Must include a non-null config XML file.");
|
||||
}
|
||||
// TODO: Connect to ImsConfigImplBase.
|
||||
throw new UnsupportedOperationException("notifyRcsAutoConfigurationReceived is not"
|
||||
+ "supported");
|
||||
}
|
||||
|
||||
private static boolean isImsAvailableOnDevice() {
|
||||
IPackageManager pm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
|
||||
if (pm == null) {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 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.ims;
|
||||
|
||||
parcelable RcsContactUceCapability;
|
||||
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (C) 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.ims;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Contains the User Capability Exchange capabilities corresponding to a contact's URI.
|
||||
* @hide
|
||||
*/
|
||||
public final class RcsContactUceCapability implements Parcelable {
|
||||
|
||||
/** Supports 1-to-1 chat */
|
||||
public static final int CAPABILITY_CHAT_STANDALONE = (1 << 0);
|
||||
/** Supports group chat */
|
||||
public static final int CAPABILITY_CHAT_SESSION = (1 << 1);
|
||||
/** Supports full store and forward group chat information. */
|
||||
public static final int CAPABILITY_CHAT_SESSION_STORE_FORWARD = (1 << 2);
|
||||
/**
|
||||
* Supports file transfer via Message Session Relay Protocol (MSRP) without Store and Forward.
|
||||
*/
|
||||
public static final int CAPABILITY_FILE_TRANSFER = (1 << 3);
|
||||
/** Supports File Transfer Thumbnail */
|
||||
public static final int CAPABILITY_FILE_TRANSFER_THUMBNAIL = (1 << 4);
|
||||
/** Supports File Transfer with Store and Forward */
|
||||
public static final int CAPABILITY_FILE_TRANSFER_STORE_FORWARD = (1 << 5);
|
||||
/** Supports File Transfer via HTTP */
|
||||
public static final int CAPABILITY_FILE_TRANSFER_HTTP = (1 << 6);
|
||||
/** Supports file transfer via SMS */
|
||||
public static final int CAPABILITY_FILE_TRANSFER_SMS = (1 << 7);
|
||||
/** Supports image sharing */
|
||||
public static final int CAPABILITY_IMAGE_SHARE = (1 << 8);
|
||||
/** Supports video sharing during a circuit-switch call (IR.74)*/
|
||||
public static final int CAPABILITY_VIDEO_SHARE_DURING_CS_CALL = (1 << 9);
|
||||
/** Supports video share outside of voice call (IR.84) */
|
||||
public static final int CAPABILITY_VIDEO_SHARE = (1 << 10);
|
||||
/** Supports social presence information */
|
||||
public static final int CAPABILITY_SOCIAL_PRESENCE = (1 << 11);
|
||||
/** Supports capability discovery via presence */
|
||||
public static final int CAPABILITY_DISCOVERY_VIA_PRESENCE = (1 << 12);
|
||||
/** Supports IP Voice calling over LTE or IWLAN (IR.92/IR.51) */
|
||||
public static final int CAPABILITY_IP_VOICE_CALL = (1 << 13);
|
||||
/** Supports IP video calling (IR.94) */
|
||||
public static final int CAPABILITY_IP_VIDEO_CALL = (1 << 14);
|
||||
/** Supports Geolocation PUSH during 1-to-1 or multiparty chat */
|
||||
public static final int CAPABILITY_GEOLOCATION_PUSH = (1 << 15);
|
||||
/** Supports Geolocation PUSH via SMS for fallback. */
|
||||
public static final int CAPABILITY_GEOLOCATION_PUSH_SMS = (1 << 16);
|
||||
/** Supports Geolocation pull. */
|
||||
public static final int CAPABILITY_GEOLOCATION_PULL = (1 << 17);
|
||||
/** Supports Geolocation pull using file transfer support. */
|
||||
public static final int CAPABILITY_GEOLOCATION_PULL_FILE_TRANSFER = (1 << 18);
|
||||
/** Supports RCS voice calling */
|
||||
public static final int CAPABILITY_RCS_VOICE_CALL = (1 << 19);
|
||||
/** Supports RCS video calling */
|
||||
public static final int CAPABILITY_RCS_VIDEO_CALL = (1 << 20);
|
||||
/** Supports RCS video calling, where video media can not be dropped */
|
||||
public static final int CAPABILITY_RCS_VIDEO_ONLY_CALL = (1 << 21);
|
||||
|
||||
/** @hide*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = "CAPABILITY_", flag = true, value = {
|
||||
CAPABILITY_CHAT_STANDALONE,
|
||||
CAPABILITY_CHAT_SESSION,
|
||||
CAPABILITY_CHAT_SESSION_STORE_FORWARD,
|
||||
CAPABILITY_FILE_TRANSFER,
|
||||
CAPABILITY_FILE_TRANSFER_THUMBNAIL,
|
||||
CAPABILITY_FILE_TRANSFER_STORE_FORWARD,
|
||||
CAPABILITY_FILE_TRANSFER_HTTP,
|
||||
CAPABILITY_FILE_TRANSFER_SMS,
|
||||
CAPABILITY_IMAGE_SHARE,
|
||||
CAPABILITY_VIDEO_SHARE_DURING_CS_CALL,
|
||||
CAPABILITY_VIDEO_SHARE,
|
||||
CAPABILITY_SOCIAL_PRESENCE,
|
||||
CAPABILITY_DISCOVERY_VIA_PRESENCE,
|
||||
CAPABILITY_IP_VOICE_CALL,
|
||||
CAPABILITY_IP_VIDEO_CALL,
|
||||
CAPABILITY_GEOLOCATION_PUSH,
|
||||
CAPABILITY_GEOLOCATION_PUSH_SMS,
|
||||
CAPABILITY_GEOLOCATION_PULL,
|
||||
CAPABILITY_GEOLOCATION_PULL_FILE_TRANSFER,
|
||||
CAPABILITY_RCS_VOICE_CALL,
|
||||
CAPABILITY_RCS_VIDEO_CALL,
|
||||
CAPABILITY_RCS_VIDEO_ONLY_CALL
|
||||
})
|
||||
public @interface CapabilityFlag {}
|
||||
|
||||
/**
|
||||
* Builder to help construct {@link RcsContactUceCapability} instances.
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
private final RcsContactUceCapability mCapabilities;
|
||||
|
||||
/**
|
||||
* Create the Builder, which can be used to set UCE capabilities as well as custom
|
||||
* capability extensions.
|
||||
* @param contact The contact URI that the capabilities are attached to.
|
||||
*/
|
||||
public Builder(@NonNull Uri contact) {
|
||||
mCapabilities = new RcsContactUceCapability(contact);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a UCE capability bit-field as well as the associated URI that the framework should
|
||||
* use for those services. This is mainly used for capabilities that may use a URI separate
|
||||
* from the contact's URI, for example the URI to use for VT calls.
|
||||
* @param type The capability to map to a service URI that is different from the contact's
|
||||
* URI.
|
||||
*/
|
||||
public Builder add(@CapabilityFlag int type, @NonNull Uri serviceUri) {
|
||||
mCapabilities.mCapabilities |= type;
|
||||
// Put each of these capabilities into the map separately.
|
||||
for (int shift = 0; shift < Integer.SIZE; shift++) {
|
||||
int cap = type & (1 << shift);
|
||||
if (cap != 0) {
|
||||
mCapabilities.mServiceMap.put(cap, serviceUri);
|
||||
// remove that capability from the field.
|
||||
type &= ~cap;
|
||||
}
|
||||
if (type == 0) {
|
||||
// no need to keep going, end early.
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a UCE capability flag that this contact supports.
|
||||
* @param type the capability that the contact supports.
|
||||
*/
|
||||
public Builder add(@CapabilityFlag int type) {
|
||||
mCapabilities.mCapabilities |= type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a carrier specific service tag.
|
||||
* @param extension A string containing a carrier specific service tag that is an extension
|
||||
* of the {@link CapabilityFlag}s that are defined here.
|
||||
*/
|
||||
public Builder add(@NonNull String extension) {
|
||||
mCapabilities.mExtensionTags.add(extension);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the constructed instance.
|
||||
*/
|
||||
public RcsContactUceCapability build() {
|
||||
return mCapabilities;
|
||||
}
|
||||
}
|
||||
|
||||
private final Uri mContactUri;
|
||||
private int mCapabilities;
|
||||
private List<String> mExtensionTags = new ArrayList<>();
|
||||
private Map<Integer, Uri> mServiceMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Use {@link Builder} to build an instance of this interface.
|
||||
* @param contact The URI associated with this capability information.
|
||||
* @hide
|
||||
*/
|
||||
RcsContactUceCapability(@NonNull Uri contact) {
|
||||
mContactUri = contact;
|
||||
}
|
||||
|
||||
private RcsContactUceCapability(Parcel in) {
|
||||
mContactUri = in.readParcelable(Uri.class.getClassLoader());
|
||||
mCapabilities = in.readInt();
|
||||
in.readStringList(mExtensionTags);
|
||||
// read mServiceMap as key,value pair
|
||||
int mapSize = in.readInt();
|
||||
for (int i = 0; i < mapSize; i++) {
|
||||
mServiceMap.put(in.readInt(), in.readParcelable(Uri.class.getClassLoader()));
|
||||
}
|
||||
}
|
||||
|
||||
public static final Creator<RcsContactUceCapability> CREATOR =
|
||||
new Creator<RcsContactUceCapability>() {
|
||||
@Override
|
||||
public RcsContactUceCapability createFromParcel(Parcel in) {
|
||||
return new RcsContactUceCapability(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RcsContactUceCapability[] newArray(int size) {
|
||||
return new RcsContactUceCapability[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeParcelable(mContactUri, 0);
|
||||
out.writeInt(mCapabilities);
|
||||
out.writeStringList(mExtensionTags);
|
||||
// write mServiceMap as key,value pairs
|
||||
int mapSize = mServiceMap.keySet().size();
|
||||
out.writeInt(mapSize);
|
||||
for (int key : mServiceMap.keySet()) {
|
||||
out.writeInt(key);
|
||||
out.writeParcelable(mServiceMap.get(key), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for a capability
|
||||
* @param type The capability flag to query.
|
||||
* @return true if the capability flag specified is set, false otherwise.
|
||||
*/
|
||||
public boolean isCapable(@CapabilityFlag int type) {
|
||||
return (mCapabilities & type) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the extension service tag is set, false otherwise.
|
||||
*/
|
||||
public boolean isCapable(@NonNull String extensionTag) {
|
||||
return mExtensionTags.contains(extensionTag);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An immutable list containing all of the extension tags that have been set as capable.
|
||||
* @throws UnsupportedOperationException if this list is modified.
|
||||
*/
|
||||
public @NonNull List<String> getCapableExtensionTags() {
|
||||
return Collections.unmodifiableList(mExtensionTags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the {@link Uri} associated with the capability being queried.
|
||||
* <p>
|
||||
* This will typically be the contact {@link Uri} available via {@link #getContactUri()} unless
|
||||
* a different service {@link Uri} was associated with this capability using
|
||||
* {@link Builder#add(int, Uri)}.
|
||||
*
|
||||
* @return a String containing the {@link Uri} associated with the service tag or
|
||||
* {@code null} if this capability is not set as capable.
|
||||
* @see #isCapable(int)
|
||||
*/
|
||||
public @Nullable Uri getServiceUri(@CapabilityFlag int type) {
|
||||
Uri result = mServiceMap.getOrDefault(type, null);
|
||||
// If the capability is capable, but does not have a service URI associated, use the default
|
||||
// contact URI.
|
||||
if (result == null) {
|
||||
return isCapable(type) ? getContactUri() : null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the URI representing the contact associated with the capabilities.
|
||||
*/
|
||||
public @NonNull Uri getContactUri() {
|
||||
return mContactUri;
|
||||
}
|
||||
}
|
||||
276
telephony/java/android/telephony/ims/RcsUceAdapter.java
Normal file
276
telephony/java/android/telephony/ims/RcsUceAdapter.java
Normal file
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
* Copyright (C) 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.ims;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Manages RCS User Capability Exchange for the subscription specified.
|
||||
*
|
||||
* @see ImsRcsManager#getUceAdapter() for information on creating an instance of this class.
|
||||
* @hide
|
||||
*/
|
||||
public class RcsUceAdapter {
|
||||
|
||||
/**
|
||||
* An unknown error has caused the request to fail.
|
||||
*/
|
||||
public static final int ERROR_GENERIC_FAILURE = 1;
|
||||
/**
|
||||
* The carrier network does not have UCE support enabled for this subscriber.
|
||||
*/
|
||||
public static final int ERROR_NOT_ENABLED = 2;
|
||||
/**
|
||||
* The data network that the device is connected to does not support UCE currently (e.g. it is
|
||||
* 1x only currently).
|
||||
*/
|
||||
public static final int ERROR_NOT_AVAILABLE = 3;
|
||||
/**
|
||||
* The network has responded with SIP 403 error and a reason "User not registered."
|
||||
*/
|
||||
public static final int ERROR_NOT_REGISTERED = 4;
|
||||
/**
|
||||
* The network has responded to this request with a SIP 403 error and reason "not authorized for
|
||||
* presence" for this subscriber.
|
||||
*/
|
||||
public static final int ERROR_NOT_AUTHORIZED = 5;
|
||||
/**
|
||||
* The network has responded to this request with a SIP 403 error and no reason.
|
||||
*/
|
||||
public static final int ERROR_FORBIDDEN = 6;
|
||||
/**
|
||||
* The contact URI requested is not provisioned for VoLTE or it is not known as an IMS
|
||||
* subscriber to the carrier network.
|
||||
*/
|
||||
public static final int ERROR_NOT_FOUND = 7;
|
||||
/**
|
||||
* The capabilities request contained too many URIs for the carrier network to handle. Retry
|
||||
* with a lower number of contact numbers. The number varies per carrier.
|
||||
*/
|
||||
// TODO: Try to integrate this into the API so that the service will split based on carrier.
|
||||
public static final int ERROR_REQUEST_TOO_LARGE = 8;
|
||||
/**
|
||||
* The network did not respond to the capabilities request before the request timed out.
|
||||
*/
|
||||
public static final int ERROR_REQUEST_TIMEOUT = 10;
|
||||
/**
|
||||
* The request failed due to the service having insufficient memory.
|
||||
*/
|
||||
public static final int ERROR_INSUFFICIENT_MEMORY = 11;
|
||||
/**
|
||||
* The network was lost while trying to complete the request.
|
||||
*/
|
||||
public static final int ERROR_LOST_NETWORK = 12;
|
||||
/**
|
||||
* The request has failed because the same request has already been added to the queue.
|
||||
*/
|
||||
public static final int ERROR_ALREADY_IN_QUEUE = 13;
|
||||
|
||||
/**@hide*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = "ERROR_", value = {
|
||||
ERROR_GENERIC_FAILURE,
|
||||
ERROR_NOT_ENABLED,
|
||||
ERROR_NOT_AVAILABLE,
|
||||
ERROR_NOT_REGISTERED,
|
||||
ERROR_NOT_AUTHORIZED,
|
||||
ERROR_FORBIDDEN,
|
||||
ERROR_NOT_FOUND,
|
||||
ERROR_REQUEST_TOO_LARGE,
|
||||
ERROR_REQUEST_TIMEOUT,
|
||||
ERROR_INSUFFICIENT_MEMORY,
|
||||
ERROR_LOST_NETWORK,
|
||||
ERROR_ALREADY_IN_QUEUE
|
||||
})
|
||||
public @interface ErrorCode {}
|
||||
|
||||
/**
|
||||
* The last publish has resulted in a "200 OK" response or the device is using SIP OPTIONS for
|
||||
* UCE.
|
||||
*/
|
||||
public static final int PUBLISH_STATE_200_OK = 1;
|
||||
|
||||
/**
|
||||
* The hasn't published its capabilities since boot or hasn't gotten any publish response yet.
|
||||
*/
|
||||
public static final int PUBLISH_STATE_NOT_PUBLISHED = 2;
|
||||
|
||||
/**
|
||||
* The device has tried to publish its capabilities, which has resulted in an error. This error
|
||||
* is related to the fact that the device is not VoLTE provisioned.
|
||||
*/
|
||||
public static final int PUBLISH_STATE_VOLTE_PROVISION_ERROR = 3;
|
||||
|
||||
/**
|
||||
* The device has tried to publish its capabilities, which has resulted in an error. This error
|
||||
* is related to the fact that the device is not RCS or UCE provisioned.
|
||||
*/
|
||||
public static final int PUBLISH_STATE_RCS_PROVISION_ERROR = 4;
|
||||
|
||||
/**
|
||||
* The last publish resulted in a "408 Request Timeout" response.
|
||||
*/
|
||||
public static final int PUBLISH_STATE_REQUEST_TIMEOUT = 5;
|
||||
|
||||
/**
|
||||
* The last publish resulted in another unknown error, such as SIP 503 - "Service Unavailable"
|
||||
* or SIP 423 - "Interval too short".
|
||||
* <p>
|
||||
* Device shall retry with exponential back-off.
|
||||
*/
|
||||
public static final int PUBLISH_STATE_OTHER_ERROR = 6;
|
||||
|
||||
/**@hide*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = "PUBLISH_STATE_", value = {
|
||||
PUBLISH_STATE_200_OK,
|
||||
PUBLISH_STATE_NOT_PUBLISHED,
|
||||
PUBLISH_STATE_VOLTE_PROVISION_ERROR,
|
||||
PUBLISH_STATE_RCS_PROVISION_ERROR,
|
||||
PUBLISH_STATE_REQUEST_TIMEOUT,
|
||||
PUBLISH_STATE_OTHER_ERROR
|
||||
})
|
||||
public @interface PublishState {}
|
||||
|
||||
|
||||
/**
|
||||
* Provides a one-time callback for the response to a UCE request. After this callback is called
|
||||
* by the framework, the reference to this callback will be discarded on the service side.
|
||||
* @see #requestCapabilities(Executor, List, CapabilitiesCallback)
|
||||
*/
|
||||
public static class CapabilitiesCallback {
|
||||
|
||||
/**
|
||||
* Notify this application that the pending capability request has returned successfully.
|
||||
* @param contactCapabilities List of capabilities associated with each contact requested.
|
||||
*/
|
||||
public void onCapabilitiesReceived(
|
||||
@NonNull List<RcsContactUceCapability> contactCapabilities) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The pending request has resulted in an error and may need to be retried, depending on the
|
||||
* error code.
|
||||
* @param errorCode The reason for the framework being unable to process the request.
|
||||
*/
|
||||
public void onError(@ErrorCode int errorCode) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private final int mSubId;
|
||||
|
||||
/**
|
||||
* Not to be instantiated directly, use
|
||||
* {@link ImsRcsManager#createForSubscriptionId(Context, int)} and
|
||||
* {@link ImsRcsManager#getUceAdapter()} to instantiate this manager class.
|
||||
*/
|
||||
RcsUceAdapter(int subId) {
|
||||
mSubId = subId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the User Capability Exchange capabilities for one or more contacts.
|
||||
* <p>
|
||||
* Be sure to check the availability of this feature using
|
||||
* {@link ImsRcsManager#isAvailable(int)} and ensuring
|
||||
* {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or
|
||||
* {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} is enabled or else
|
||||
* this operation will fail with {@link #ERROR_NOT_AVAILABLE} or {@link #ERROR_NOT_ENABLED}.
|
||||
*
|
||||
* @param executor The executor that will be used when the request is completed and the
|
||||
* {@link CapabilitiesCallback} is called.
|
||||
* @param contactNumbers A list of numbers that the capabilities are being requested for.
|
||||
* @param c A one-time callback for when the request for capabilities completes or there is an
|
||||
* error processing the request.
|
||||
* @throws ImsException if the subscription associated with this instance of
|
||||
* {@link RcsUceAdapter} is valid, but the ImsService associated with the subscription is not
|
||||
* available. This can happen if the ImsService has crashed, for example, or if the subscription
|
||||
* becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
|
||||
public void requestCapabilities(@CallbackExecutor Executor executor,
|
||||
@NonNull List<Uri> contactNumbers,
|
||||
@NonNull CapabilitiesCallback c) throws ImsException {
|
||||
throw new UnsupportedOperationException("isUceSettingEnabled is not supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last publish result from the UCE service if the device is using an RCS presence
|
||||
* server.
|
||||
* @return The last publish result from the UCE service. If the device is using SIP OPTIONS,
|
||||
* this method will return {@link #PUBLISH_STATE_200_OK} as well.
|
||||
* @throws ImsException if the subscription associated with this instance of
|
||||
* {@link RcsUceAdapter} is valid, but the ImsService associated with the subscription is not
|
||||
* available. This can happen if the ImsService has crashed, for example, or if the subscription
|
||||
* becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
|
||||
public @PublishState int getUcePublishState() throws ImsException {
|
||||
throw new UnsupportedOperationException("getPublishState is not supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* The user’s setting for whether or not Presence and User Capability Exchange (UCE) is enabled
|
||||
* for the associated subscription.
|
||||
*
|
||||
* @return true if the user’s setting for UCE is enabled, false otherwise. If false,
|
||||
* {@link ImsRcsManager#isCapable(int)} will return false for
|
||||
* {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} and
|
||||
* {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE}
|
||||
* @see #setUceSettingEnabled(boolean)
|
||||
* @throws ImsException if the subscription associated with this instance of
|
||||
* {@link RcsUceAdapter} is valid, but the ImsService associated with the subscription is not
|
||||
* available. This can happen if the ImsService has crashed, for example, or if the subscription
|
||||
* becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
|
||||
public boolean isUceSettingEnabled() throws ImsException {
|
||||
// TODO: add SubscriptionController column for this property.
|
||||
throw new UnsupportedOperationException("isUceSettingEnabled is not supported.");
|
||||
}
|
||||
/**
|
||||
* Change the user’s setting for whether or not UCE is enabled for the associated subscription.
|
||||
* @param isEnabled the user's setting for whether or not they wish for Presence and User
|
||||
* Capability Exchange to be enabled. If false,
|
||||
* {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} and
|
||||
* {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} capability will be
|
||||
* disabled, depending on which type of UCE the carrier supports.
|
||||
* @see #isUceSettingEnabled()
|
||||
* @throws ImsException if the subscription associated with this instance of
|
||||
* {@link RcsUceAdapter} is valid, but the ImsService associated with the subscription is not
|
||||
* available. This can happen if the ImsService has crashed, for example, or if the subscription
|
||||
* becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
|
||||
public void setUceSettingEnabled(boolean isEnabled) throws ImsException {
|
||||
// TODO: add SubscriptionController column for this property.
|
||||
throw new UnsupportedOperationException("setUceSettingEnabled is not supported.");
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,14 @@
|
||||
|
||||
package android.telephony.ims.feature;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.SystemApi;
|
||||
import android.telephony.ims.aidl.IImsRcsFeature;
|
||||
import android.telephony.ims.stub.RcsPresenceExchangeImplBase;
|
||||
import android.telephony.ims.stub.RcsSipOptionsImplBase;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Base implementation of the RcsFeature APIs. Any ImsService wishing to support RCS should extend
|
||||
@@ -32,18 +38,165 @@ public class RcsFeature extends ImsFeature {
|
||||
// Empty Default Implementation.
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains the capabilities defined and supported by a {@link RcsFeature} in the
|
||||
* form of a bitmask. The capabilities that are used in the RcsFeature are
|
||||
* defined as:
|
||||
* {@link RcsImsCapabilityFlag#CAPABILITY_TYPE_OPTIONS_UCE}
|
||||
* {@link RcsImsCapabilityFlag#CAPABILITY_TYPE_PRESENCE_UCE}
|
||||
*
|
||||
* The enabled capabilities of this RcsFeature will be set by the framework
|
||||
* using {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}.
|
||||
* After the capabilities have been set, the RcsFeature may then perform the necessary bring up
|
||||
* of the capability and notify the capability status as true using
|
||||
* {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)}. This will signal to the
|
||||
* framework that the capability is available for usage.
|
||||
* @hide
|
||||
*/
|
||||
public static class RcsImsCapabilities extends Capabilities {
|
||||
/** @hide*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = "CAPABILITY_TYPE_", flag = true, value = {
|
||||
CAPABILITY_TYPE_OPTIONS_UCE,
|
||||
CAPABILITY_TYPE_PRESENCE_UCE
|
||||
})
|
||||
public @interface RcsImsCapabilityFlag {}
|
||||
|
||||
public RcsFeature() {
|
||||
super();
|
||||
/**
|
||||
* This carrier supports User Capability Exchange using SIP OPTIONS as defined by the
|
||||
* framework. If set, the RcsFeature should support capability exchange using SIP OPTIONS.
|
||||
* If not set, this RcsFeature should not service capability requests.
|
||||
* @hide
|
||||
*/
|
||||
public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1 << 0;
|
||||
|
||||
/**
|
||||
* This carrier supports User Capability Exchange using a presence server as defined by the
|
||||
* framework. If set, the RcsFeature should support capability exchange using a presence
|
||||
* server. If not set, this RcsFeature should not publish capabilities or service capability
|
||||
* requests using presence.
|
||||
* @hide
|
||||
*/
|
||||
public static final int CAPABILITY_TYPE_PRESENCE_UCE = 1 << 1;
|
||||
|
||||
/**@hide*/
|
||||
public RcsImsCapabilities(@RcsImsCapabilityFlag int capabilities) {
|
||||
|
||||
}
|
||||
|
||||
/**@hide*/
|
||||
@Override
|
||||
public void addCapabilities(@RcsImsCapabilityFlag int capabilities) {
|
||||
|
||||
}
|
||||
|
||||
/**@hide*/
|
||||
@Override
|
||||
public void removeCapabilities(@RcsImsCapabilityFlag int capabilities) {
|
||||
|
||||
}
|
||||
|
||||
/**@hide*/
|
||||
@Override
|
||||
public boolean isCapable(@RcsImsCapabilityFlag int capabilities) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Query the current {@link RcsImsCapabilities} status set by the RcsFeature. If a capability is
|
||||
* set, the {@link RcsFeature} has brought up the capability and is ready for framework
|
||||
* requests. To change the status of the capabilities
|
||||
* {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)} should be called.
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public final RcsImsCapabilities queryCapabilityStatus() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* Notify the framework that the capabilities status has changed. If a capability is enabled,
|
||||
* this signals to the framework that the capability has been initialized and is ready.
|
||||
* Call {@link #queryCapabilityStatus()} to return the current capability status.
|
||||
* @hide
|
||||
*/
|
||||
public final void notifyCapabilitiesStatusChanged(RcsImsCapabilities c) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the RcsFeature with the ability to return the framework capability configuration set
|
||||
* by the framework. When the framework calls
|
||||
* {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)} to
|
||||
* enable or disable capability A, this method should return the correct configuration for
|
||||
* capability A afterwards (until it has changed).
|
||||
* @hide
|
||||
*/
|
||||
public boolean queryCapabilityConfiguration(
|
||||
@RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
/**
|
||||
* Called from the framework when the {@link RcsImsCapabilities} that have been configured for
|
||||
* this {@link RcsFeature} has changed.
|
||||
* <p>
|
||||
* For each newly enabled capability flag, the corresponding capability should be brought up in
|
||||
* the {@link RcsFeature} and registered on the network. For each newly disabled capability
|
||||
* flag, the corresponding capability should be brought down, and deregistered. Once a new
|
||||
* capability has been initialized and is ready for usage, the status of that capability should
|
||||
* also be set to true using {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)}. This
|
||||
* will notify the framework that the capability is ready.
|
||||
* <p>
|
||||
* If for some reason one or more of these capabilities can not be enabled/disabled,
|
||||
* {@link CapabilityCallbackProxy#onChangeCapabilityConfigurationError(int, int, int)} should
|
||||
* be called for each capability change that resulted in an error.
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public void changeEnabledCapabilities(CapabilityChangeRequest request,
|
||||
CapabilityCallbackProxy c) {
|
||||
// Do nothing for base implementation.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the implementation of SIP OPTIONS for this {@link RcsFeature}.
|
||||
* <p>
|
||||
* Will only be requested by the framework if capability exchange via SIP OPTIONS is
|
||||
* configured as capable during a
|
||||
* {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}
|
||||
* operation and the RcsFeature sets the status of the capability to true using
|
||||
* {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)}.
|
||||
*
|
||||
* @return An instance of {@link RcsSipOptionsImplBase} that implements SIP options exchange if
|
||||
* it is supported by the device.
|
||||
* @hide
|
||||
*/
|
||||
public RcsSipOptionsImplBase getOptionsExchangeImpl() {
|
||||
// Base Implementation, override to implement functionality
|
||||
return new RcsSipOptionsImplBase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the implementation of UCE presence for this {@link RcsFeature}.
|
||||
* Will only be requested by the framework if presence exchang is configured as capable during
|
||||
* a {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}
|
||||
* operation and the RcsFeature sets the status of the capability to true using
|
||||
* {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)}.
|
||||
*
|
||||
* @return An instance of {@link RcsPresenceExchangeImplBase} that implements presence
|
||||
* exchange if it is supported by the device.
|
||||
* @hide
|
||||
*/
|
||||
public RcsPresenceExchangeImplBase getPresenceExchangeImpl() {
|
||||
// Base Implementation, override to implement functionality.
|
||||
return new RcsPresenceExchangeImplBase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@link RcsFeature} instance.
|
||||
*/
|
||||
public RcsFeature() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**{@inheritDoc}*/
|
||||
|
||||
@@ -341,6 +341,17 @@ public class ImsConfigImplBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The framework has received an RCS autoconfiguration XML file for provisioning.
|
||||
*
|
||||
* @param config The XML file to be read, if not compressed, it should be in ASCII/UTF8 format.
|
||||
* @param isCompressed The XML file is compressed in gzip format and must be decompressed
|
||||
* before being read.
|
||||
* @hide
|
||||
*/
|
||||
public void notifyRcsAutoConfigurationReceived(byte[] config, boolean isCompressed) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the configuration value for this ImsService.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 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.ims.stub;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Base class for different types of Capability exchange, presence using
|
||||
* {@link RcsPresenceExchangeImplBase} and SIP OPTIONS exchange using {@link RcsSipOptionsImplBase}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class RcsCapabilityExchange {
|
||||
|
||||
/** Service is unknown. */
|
||||
public static final int COMMAND_CODE_SERVICE_UNKNOWN = 0;
|
||||
/** The command completed successfully. */
|
||||
public static final int COMMAND_CODE_SUCCESS = 1;
|
||||
/** The command failed with an unknown error. */
|
||||
public static final int COMMAND_CODE_GENERIC_FAILURE = 2;
|
||||
/** Invalid parameter(s). */
|
||||
public static final int COMMAND_CODE_INVALID_PARAM = 3;
|
||||
/** Fetch error. */
|
||||
public static final int COMMAND_CODE_FETCH_ERROR = 4;
|
||||
/** Request timed out. */
|
||||
public static final int COMMAND_CODE_REQUEST_TIMEOUT = 5;
|
||||
/** Failure due to insufficient memory available. */
|
||||
public static final int COMMAND_CODE_INSUFFICIENT_MEMORY = 6;
|
||||
/** Network connection is lost. */
|
||||
public static final int COMMAND_CODE_LOST_NETWORK_CONNECTION = 7;
|
||||
/** Requested feature/resource is not supported. */
|
||||
public static final int COMMAND_CODE_NOT_SUPPORTED = 8;
|
||||
/** Contact or resource is not found. */
|
||||
public static final int COMMAND_CODE_NOT_FOUND = 9;
|
||||
/** Service is not available. */
|
||||
public static final int COMMAND_CODE_SERVICE_UNAVAILABLE = 10;
|
||||
/** No Change in Capabilities */
|
||||
public static final int COMMAND_CODE_NO_CHANGE_IN_CAP = 11;
|
||||
|
||||
/** @hide*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = "COMMAND_CODE_", value = {
|
||||
COMMAND_CODE_SERVICE_UNKNOWN,
|
||||
COMMAND_CODE_SUCCESS,
|
||||
COMMAND_CODE_GENERIC_FAILURE,
|
||||
COMMAND_CODE_INVALID_PARAM,
|
||||
COMMAND_CODE_FETCH_ERROR,
|
||||
COMMAND_CODE_REQUEST_TIMEOUT,
|
||||
COMMAND_CODE_INSUFFICIENT_MEMORY,
|
||||
COMMAND_CODE_LOST_NETWORK_CONNECTION,
|
||||
COMMAND_CODE_NOT_SUPPORTED,
|
||||
COMMAND_CODE_NOT_FOUND,
|
||||
COMMAND_CODE_SERVICE_UNAVAILABLE,
|
||||
COMMAND_CODE_NO_CHANGE_IN_CAP
|
||||
})
|
||||
public @interface CommandCode {}
|
||||
|
||||
/**
|
||||
* Provides the framework with an update as to whether or not a command completed successfully
|
||||
* locally. This includes capabilities requests and updates from the network. If it does not
|
||||
* complete successfully, then the framework may retry the command again later, depending on the
|
||||
* error. If the command does complete successfully, the framework will then wait for network
|
||||
* updates.
|
||||
*
|
||||
* @param code The result of the pending command. If {@link #COMMAND_CODE_SUCCESS}, further
|
||||
* updates will be sent for this command using the associated operationToken.
|
||||
* @param operationToken the token associated with the pending command.
|
||||
*/
|
||||
public final void onCommandUpdate(@CommandCode int code, int operationToken) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (C) 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.ims.stub;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.net.Uri;
|
||||
import android.telephony.ims.RcsContactUceCapability;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Base implementation for RCS User Capability Exchange using Presence. Any ImsService implementing
|
||||
* this service must implement the stub methods {@link #requestCapabilities(List, int)} and
|
||||
* {@link #updateCapabilities(RcsContactUceCapability, int)}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class RcsPresenceExchangeImplBase extends RcsCapabilityExchange {
|
||||
|
||||
private static final String LOG_TAG = "RcsPresenceExchangeIB";
|
||||
|
||||
/**
|
||||
* The request has resulted in any other 4xx/5xx/6xx that is not covered below. No retry will be
|
||||
* attempted.
|
||||
*/
|
||||
public static final int RESPONSE_SUBSCRIBE_GENERIC_FAILURE = -1;
|
||||
|
||||
/**
|
||||
* The request has succeeded with a “200” message from the network.
|
||||
*/
|
||||
public static final int RESPONSE_SUCCESS = 0;
|
||||
|
||||
/**
|
||||
* The request has resulted in a “403” (User Not Registered) error from the network. Will retry
|
||||
* capability polling with an exponential backoff.
|
||||
*/
|
||||
public static final int RESPONSE_NOT_REGISTERED = 1;
|
||||
|
||||
/**
|
||||
* The request has resulted in a “403” (not authorized (Requestor)) error from the network. No
|
||||
* retry will be attempted.
|
||||
*/
|
||||
public static final int RESPONSE_NOT_AUTHORIZED_FOR_PRESENCE = 2;
|
||||
|
||||
/**
|
||||
* The request has resulted in a "403” (Forbidden) or other “403” error from the network and
|
||||
* will be handled the same as “404” Not found. No retry will be attempted.
|
||||
*/
|
||||
public static final int RESPONSE_FORBIDDEN = 3;
|
||||
|
||||
/**
|
||||
* The request has resulted in a “404” (Not found) result from the network. No retry will be
|
||||
* attempted.
|
||||
*/
|
||||
public static final int RESPONSE_NOT_FOUND = 4;
|
||||
|
||||
/**
|
||||
* The request has resulted in a “408” response. Retry after exponential backoff.
|
||||
*/
|
||||
public static final int RESPONSE_SIP_REQUEST_TIMEOUT = 5;
|
||||
|
||||
/**
|
||||
* The network has responded with a “413” (Too Large) response from the network. Capability
|
||||
* request contains too many items and must be shrunk before the request will be accepted.
|
||||
*/
|
||||
public static final int RESPONSE_SUBSCRIBE_TOO_LARGE = 6;
|
||||
|
||||
/**
|
||||
* The request has resulted in a “423” response. Retry after exponential backoff.
|
||||
*/
|
||||
public static final int RESPONSE_SIP_INTERVAL_TOO_SHORT = 7;
|
||||
|
||||
/**
|
||||
* The request has resulted in a “503” response. Retry after exponential backoff.
|
||||
*/
|
||||
public static final int RESPONSE_SIP_SERVICE_UNAVAILABLE = 8;
|
||||
|
||||
/** @hide*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = "RESPONSE_", value = {
|
||||
RESPONSE_SUBSCRIBE_GENERIC_FAILURE,
|
||||
RESPONSE_SUCCESS,
|
||||
RESPONSE_NOT_REGISTERED,
|
||||
RESPONSE_NOT_AUTHORIZED_FOR_PRESENCE,
|
||||
RESPONSE_FORBIDDEN,
|
||||
RESPONSE_NOT_FOUND,
|
||||
RESPONSE_SIP_REQUEST_TIMEOUT,
|
||||
RESPONSE_SUBSCRIBE_TOO_LARGE,
|
||||
RESPONSE_SIP_INTERVAL_TOO_SHORT,
|
||||
RESPONSE_SIP_SERVICE_UNAVAILABLE
|
||||
})
|
||||
public @interface PresenceResponseCode {}
|
||||
|
||||
/**
|
||||
* Provide the framework with a subsequent network response update to
|
||||
* {@link #updateCapabilities(RcsContactUceCapability, int)} and
|
||||
* {@link #requestCapabilities(List, int)} operations.
|
||||
* @param code The SIP response code sent from the network for the operation token specified.
|
||||
* @param reason The optional reason response from the network. If the network provided no
|
||||
* reason with the code, the string should be empty.
|
||||
* @param operationToken The token associated with the operation this service is providing a
|
||||
* response for.
|
||||
*/
|
||||
public final void onNetworkResponse(@PresenceResponseCode int code, @NonNull String reason,
|
||||
int operationToken) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the framework with the requested contacts’ capabilities requested by the framework
|
||||
* using {@link #requestCapabilities(List, int)} .
|
||||
*/
|
||||
public final void onCapabilityRequestResponse(@NonNull List<RcsContactUceCapability> infos,
|
||||
int operationToken) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger the framework to provide a capability update using
|
||||
* {@link #updateCapabilities(RcsContactUceCapability, int)}. This is typically used when trying
|
||||
* to generate an initial PUBLISH for a new subscription to the network.
|
||||
* <p>
|
||||
* The device will cache all presence publications after boot until this method is called once.
|
||||
*/
|
||||
public final void onNotifyUpdateCapabilites() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the framework that the device’s capabilities have been unpublished from the network.
|
||||
*/
|
||||
public final void onUnpublish() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* The user capabilities of one or multiple contacts have been requested.
|
||||
* <p>
|
||||
* This must be followed up with one call to {@link #onCommandUpdate(int, int)} with an update
|
||||
* as to whether or not the command completed as well as subsequent network
|
||||
* updates using {@link #onNetworkResponse(int, String, int)}. When the operation is completed,
|
||||
* {@link #onCapabilityRequestResponse(List, int)} should be called with
|
||||
* the presence information for the contacts specified.
|
||||
* @param uris A {@link List} of the URIs that the framework is requesting the UCE capabilities
|
||||
* for.
|
||||
* @param operationToken The token associated with this operation. Updates to this request using
|
||||
* {@link #onCommandUpdate(int, int)}, {@link #onNetworkResponse(int, String, int)}, and
|
||||
* {@link #onCapabilityRequestResponse(List, int)} must use the same operation token
|
||||
* in response.
|
||||
*/
|
||||
public void requestCapabilities(@NonNull List<Uri> uris, int operationToken) {
|
||||
// Stub - to be implemented by service
|
||||
Log.w(LOG_TAG, "requestCapabilities called with no implementation.");
|
||||
onCommandUpdate(COMMAND_CODE_GENERIC_FAILURE, operationToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* The capabilities of this device have been updated and should be published
|
||||
* to the network. The framework will expect one {@link #onCommandUpdate(int, int)} call to
|
||||
* indicate whether or not this operation failed first as well as network response
|
||||
* updates to this update using {@link #onNetworkResponse(int, String, int)}.
|
||||
* @param capabilities The capabilities for this device.
|
||||
* @param operationToken The token associated with this operation. Any subsequent
|
||||
* {@link #onCommandUpdate(int, int)} or {@link #onNetworkResponse(int, String, int)}
|
||||
* calls regarding this update must use the same token.
|
||||
*/
|
||||
public void updateCapabilities(@NonNull RcsContactUceCapability capabilities,
|
||||
int operationToken) {
|
||||
// Stub - to be implemented by service
|
||||
Log.w(LOG_TAG, "updateCapabilities called with no implementation.");
|
||||
onCommandUpdate(COMMAND_CODE_GENERIC_FAILURE, operationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (C) 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.ims.stub;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.net.Uri;
|
||||
import android.telephony.ims.RcsContactUceCapability;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Base implementation for RCS User Capability Exchange using SIP OPTIONS.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class RcsSipOptionsImplBase extends RcsCapabilityExchange {
|
||||
|
||||
private static final String LOG_TAG = "RcsSipOptionsImplBase";
|
||||
|
||||
/**
|
||||
* Indicates a SIP response from the remote user other than 200, 480, 408, 404, or 604.
|
||||
*/
|
||||
public static final int RESPONSE_GENERIC_FAILURE = -1;
|
||||
|
||||
/**
|
||||
* Indicates that the remote user responded with a 200 OK response.
|
||||
*/
|
||||
public static final int RESPONSE_SUCCESS = 0;
|
||||
|
||||
/**
|
||||
* Indicates that the remote user responded with a 480 TEMPORARY UNAVAILABLE response.
|
||||
*/
|
||||
public static final int RESPONSE_TEMPORARILY_UNAVAILABLE = 1;
|
||||
|
||||
/**
|
||||
* Indicates that the remote user responded with a 408 REQUEST TIMEOUT response.
|
||||
*/
|
||||
public static final int RESPONSE_REQUEST_TIMEOUT = 2;
|
||||
|
||||
/**
|
||||
* Indicates that the remote user responded with a 404 NOT FOUND response.
|
||||
*/
|
||||
public static final int RESPONSE_NOT_FOUND = 3;
|
||||
|
||||
/**
|
||||
* Indicates that the remote user responded with a 604 DOES NOT EXIST ANYWHERE response.
|
||||
*/
|
||||
public static final int RESPONSE_DOES_NOT_EXIST_ANYWHERE = 4;
|
||||
|
||||
/** @hide*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = "RESPONSE_", value = {
|
||||
RESPONSE_GENERIC_FAILURE,
|
||||
RESPONSE_SUCCESS,
|
||||
RESPONSE_TEMPORARILY_UNAVAILABLE,
|
||||
RESPONSE_REQUEST_TIMEOUT,
|
||||
RESPONSE_NOT_FOUND,
|
||||
RESPONSE_DOES_NOT_EXIST_ANYWHERE
|
||||
})
|
||||
public @interface SipResponseCode {}
|
||||
|
||||
/**
|
||||
* Send the response of a SIP OPTIONS capability exchange to the framework. If {@code code} is
|
||||
* {@link #RESPONSE_SUCCESS}, info must be non-null.
|
||||
* @param code The SIP response code that was sent by the network in response to the request
|
||||
* sent by {@link #sendCapabilityRequest(Uri, RcsContactUceCapability, int)}.
|
||||
* @param reason The optional SIP response reason sent by the network. If none was sent, this
|
||||
* should be an empty string.
|
||||
* @param info the contact's UCE capabilities associated with the capability request.
|
||||
* @param operationToken The token associated with the original capability request, set by
|
||||
* {@link #sendCapabilityRequest(Uri, RcsContactUceCapability, int)}.
|
||||
*/
|
||||
public final void onCapabilityRequestResponse(@SipResponseCode int code, @NonNull String reason,
|
||||
@Nullable RcsContactUceCapability info, int operationToken) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Inform the framework of a query for this device's UCE capabilities.
|
||||
* <p>
|
||||
* The framework will respond via the
|
||||
* {@link #respondToCapabilityRequest(String, RcsContactUceCapability, int)} or
|
||||
* {@link #respondToCapabilityRequestWithError(Uri, int, String, int)} method.
|
||||
* @param contactUri The URI associated with the remote contact that is requesting capabilities.
|
||||
* @param remoteInfo The remote contact's capability information.
|
||||
* @param operationToken An unique operation token that you have generated that will be returned
|
||||
* by the framework in
|
||||
* {@link #respondToCapabilityRequest(String, RcsContactUceCapability, int)}.
|
||||
*/
|
||||
public final void onRemoteCapabilityRequest(@NonNull Uri contactUri,
|
||||
@NonNull RcsContactUceCapability remoteInfo, int operationToken) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Push one's own capabilities to a remote user via the SIP OPTIONS presence exchange mechanism
|
||||
* in order to receive the capabilities of the remote user in response.
|
||||
* <p>
|
||||
* The implementer must call
|
||||
* {@link #onCapabilityRequestResponse(int, String, RcsContactUceCapability, int)} to send the
|
||||
* response of this query back to the framework.
|
||||
* @param contactUri The URI of the remote user that we wish to get the capabilities of.
|
||||
* @param capabilities The capabilities of this device to send to the remote user.
|
||||
* @param operationToken A token generated by the framework that will be passed through
|
||||
* {@link #onCapabilityRequestResponse(int, String, RcsContactUceCapability, int)} when this
|
||||
* operation has succeeded.
|
||||
*/
|
||||
public void sendCapabilityRequest(@NonNull Uri contactUri,
|
||||
@NonNull RcsContactUceCapability capabilities, int operationToken) {
|
||||
// Stub - to be implemented by service
|
||||
Log.w(LOG_TAG, "sendCapabilityRequest called with no implementation.");
|
||||
onCommandUpdate(COMMAND_CODE_GENERIC_FAILURE, operationToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to a remote capability request from the contact specified with the capabilities of
|
||||
* this device.
|
||||
* <p>
|
||||
* The framework will use the same token and uri as what was passed in to
|
||||
* {@link #onRemoteCapabilityRequest(Uri, RcsContactUceCapability, int)}.
|
||||
* @param contactUri The URI of the remote contact.
|
||||
* @param ownCapabilities The capabilities of this device.
|
||||
* @param operationToken The token generated by the framework that this service obtained when
|
||||
* {@link #onRemoteCapabilityRequest(Uri, RcsContactUceCapability, int)} was called.
|
||||
*/
|
||||
public void respondToCapabilityRequest(@NonNull String contactUri,
|
||||
@NonNull RcsContactUceCapability ownCapabilities, int operationToken) {
|
||||
// Stub - to be implemented by service
|
||||
Log.w(LOG_TAG, "respondToCapabilityRequest called with no implementation.");
|
||||
onCommandUpdate(COMMAND_CODE_GENERIC_FAILURE, operationToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to a remote capability request from the contact specified with the specified error.
|
||||
* <p>
|
||||
* The framework will use the same token and uri as what was passed in to
|
||||
* {@link #onRemoteCapabilityRequest(Uri, RcsContactUceCapability, int)}.
|
||||
* @param contactUri A URI containing the remote contact.
|
||||
* @param code The SIP response code to respond with.
|
||||
* @param reason A non-null String containing the reason associated with the SIP code.
|
||||
* @param operationToken The token provided by the framework when
|
||||
* {@link #onRemoteCapabilityRequest(Uri, RcsContactUceCapability, int)} was called.
|
||||
*
|
||||
*/
|
||||
public void respondToCapabilityRequestWithError(@NonNull Uri contactUri,
|
||||
@SipResponseCode int code, @NonNull String reason, int operationToken) {
|
||||
// Stub - to be implemented by service
|
||||
Log.w(LOG_TAG, "respondToCapabiltyRequestWithError called with no implementation.");
|
||||
onCommandUpdate(COMMAND_CODE_GENERIC_FAILURE, operationToken);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user