diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-07-15 02:04:00 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-07-15 02:04:00 +0000 |
commit | e8ec56bca2679facd9ead218d5c784bbbaf95a16 (patch) | |
tree | b24321ac17884be632351c22f458e3f75ece2aa2 | |
parent | 64303b1fde0bcb5ad9d71043955445c03ccadd1e (diff) | |
parent | b29f3c0303d491e2bebb50ecd48527d87f836aa9 (diff) | |
download | ims-android12-mainline-resolv-release.tar.gz |
Snap for 7550930 from b29f3c0303d491e2bebb50ecd48527d87f836aa9 to mainline-resolv-releaseandroid-mainline-12.0.0_r94android-mainline-12.0.0_r80android-mainline-12.0.0_r65android-mainline-12.0.0_r52android-mainline-12.0.0_r35android-mainline-12.0.0_r16android-mainline-12.0.0_r124android-mainline-12.0.0_r108android12-mainline-resolv-release
Change-Id: I8ffcc55846f3dc255a333543c730445d18337b42
21 files changed, 479 insertions, 127 deletions
diff --git a/METADATA b/METADATA new file mode 100644 index 0000000..d97975c --- /dev/null +++ b/METADATA @@ -0,0 +1,3 @@ +third_party { + license_type: NOTICE +} diff --git a/rcs/presencepolling/Android.bp b/rcs/presencepolling/Android.bp index dfe9f68..ed4a656 100644 --- a/rcs/presencepolling/Android.bp +++ b/rcs/presencepolling/Android.bp @@ -24,12 +24,43 @@ // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH // DAMAGE. +package { + default_applicable_licenses: ["external_ims_rcs_presencepolling_license"], +} + +// Added automatically by a large-scale-change that took the approach of +// 'apply every license found to every target'. While this makes sure we respect +// every license restriction, it may not be entirely correct. +// +// e.g. GPL in an MIT project might only apply to the contrib/ directory. +// +// Please consider splitting the single license below into multiple licenses, +// taking care not to lose any license_kind information, and overriding the +// default license using the 'licenses: [...]' property on targets as needed. +// +// For unused files, consider creating a 'fileGroup' with "//visibility:private" +// to attach the license to, and including a comment whether the files may be +// used in the current project. +// See: http://go/android-license-faq +license { + name: "external_ims_rcs_presencepolling_license", + visibility: [":__subpackages__"], + license_kinds: [ + "SPDX-license-identifier-Apache-2.0", + "SPDX-license-identifier-BSD", + ], + license_text: [ + "LICENSE", + ], +} + java_defaults { name: "presence_polling_defaults", srcs: ["src/**/*.java"], static_libs: ["com.android.ims.rcsmanager"], - platform_apis: true, certificate: "platform", + system_ext_specific: true, + platform_apis: true, optimize: { proguard_flags_files: ["proguard.flags"], }, diff --git a/rcs/presencepolling/AndroidManifest.xml b/rcs/presencepolling/AndroidManifest.xml index 9ee86ef..2ffcc5c 100644 --- a/rcs/presencepolling/AndroidManifest.xml +++ b/rcs/presencepolling/AndroidManifest.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8" standalone="no"?> +<?xml version="1.0" encoding="utf-8"?> <!-- * Copyright (c) 2015, Motorola Mobility LLC * All rights reserved. @@ -28,20 +28,20 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" - package="com.android.service.ims.presence" - android:sharedUserId="android.uid.phone" - coreApp="true"> + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + package="com.android.service.ims.presence" + android:sharedUserId="android.uid.phone" + coreApp="true"> <uses-sdk android:minSdkVersion="19"/> <permission android:name="com.android.rcs.eab.permission.READ_WRITE_EAB" - android:protectionLevel="signatureOrSystem" /> + android:protectionLevel="signatureOrSystem"/> - <protected-broadcast android:name="android.provider.rcs.eab.EAB_NEW_CONTACT_INSERTED" /> - <protected-broadcast android:name="android.provider.rcs.eab.EAB_DATABASE_RESET" /> - <protected-broadcast android:name="com.android.service.ims.presence.capability_polling_retry" /> - <protected-broadcast android:name="com.android.service.ims.presence.periodical_capability_discovery" /> + <protected-broadcast android:name="android.provider.rcs.eab.EAB_NEW_CONTACT_INSERTED"/> + <protected-broadcast android:name="android.provider.rcs.eab.EAB_DATABASE_RESET"/> + <protected-broadcast android:name="com.android.service.ims.presence.capability_polling_retry"/> + <protected-broadcast android:name="com.android.service.ims.presence.periodical_capability_discovery"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.BROADCAST_STICKY"/> @@ -51,64 +51,65 @@ <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> - <uses-permission android:name="android.permission.GET_ACCOUNTS" /> + <uses-permission android:name="android.permission.GET_ACCOUNTS"/> <uses-permission android:name="com.android.rcs.eab.permission.READ_WRITE_EAB"/> <uses-permission android:name="android.permission.READ_PROFILE"/> <uses-permission android:name="com.android.ims.rcs.permission.STATUS_CHANGED"/> <uses-permission android:name="com.android.ims.permission.PRESENCE_ACCESS"/> - <application - android:label="@string/app_label" - android:singleUser="true" - android:process="com.android.ims.rcsservice"> + <application android:label="@string/app_label" + android:singleUser="true" + android:process="com.android.ims.rcsservice"> - <service - android:name=".PollingService" - android:excludeFromRecents="true" - android:singleUser="true" - android:permission="com.android.ims.permission.PRESENCE_ACCESS"> + <service android:name=".PollingService" + android:excludeFromRecents="true" + android:singleUser="true" + android:permission="com.android.ims.permission.PRESENCE_ACCESS"> </service> - <receiver android:name=".DeviceBoot" androidprv:systemUserOnly="true"> + <receiver android:name=".DeviceBoot" + androidprv:systemUserOnly="true" + android:exported="true"> <intent-filter android:priority="103"> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver> - <receiver android:name=".DeviceShutdown" androidprv:systemUserOnly="true"> + <receiver android:name=".DeviceShutdown" + androidprv:systemUserOnly="true" + android:exported="true"> <intent-filter> <action android:name="android.intent.action.ACTION_SHUTDOWN"/> </intent-filter> </receiver> <receiver android:name=".AlarmBroadcastReceiver" - androidprv:systemUserOnly="true" - android:permission="com.android.ims.permission.PRESENCE_ACCESS"> + androidprv:systemUserOnly="true" + android:permission="com.android.ims.permission.PRESENCE_ACCESS" + android:exported="true"> <intent-filter> <action android:name="com.android.service.ims.presence.periodical_capability_discovery"/> <action android:name="com.android.service.ims.presence.capability_polling_retry"/> - <action android:name="android.provider.rcs.eab.EAB_NEW_CONTACT_INSERTED" /> + <action android:name="android.provider.rcs.eab.EAB_NEW_CONTACT_INSERTED"/> </intent-filter> </receiver> <service android:name=".PersistService" - android:exported="false" - android:permission="com.android.ims.permission.PRESENCE_ACCESS"> + android:exported="false" + android:permission="com.android.ims.permission.PRESENCE_ACCESS"> <intent-filter> <action android:name="com.android.ims.ACTION_PRESENCE_CHANGED"/> </intent-filter> </service> - <service - android:name="com.android.service.ims.presence.EABService" - android:enabled="true"> + <service android:name="com.android.service.ims.presence.EABService" + android:enabled="true"> </service> - <provider - android:name=".EABProvider" - android:permission="com.android.rcs.eab.permission.READ_WRITE_EAB" - android:exported="true" - android:enabled="true" - android:authorities="com.android.rcs.eab" /> + <provider android:name=".EABProvider" + android:permission="com.android.rcs.eab.permission.READ_WRITE_EAB" + android:exported="true" + android:enabled="true" + android:authorities="com.android.rcs.eab"/> </application> </manifest> diff --git a/rcs/presencepolling/CleanSpec.mk b/rcs/presencepolling/CleanSpec.mk new file mode 100644 index 0000000..f9d044f --- /dev/null +++ b/rcs/presencepolling/CleanSpec.mk @@ -0,0 +1,44 @@ +# Copyright (C) 2021 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. +# + +# If you don't need to do a full clean build but would like to touch +# a file or delete some intermediate files, add a clean step to the end +# of the list. These steps will only be run once, if they haven't been +# run before. +# +# E.g.: +# $(call add-clean-step, touch -c external/sqlite/sqlite3.h) +# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates) +# +# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with +# files that are missing or have been moved. +# +# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory. +# Use $(OUT_DIR) to refer to the "out" directory. +# +# If you need to re-do something that's already mentioned, just copy +# the command and add it to the bottom of the list. E.g., if a change +# that you made last week required touching a file and a change you +# made today requires touching the same file, just copy the old +# touch step and add it to the end of the list. +# +# ***************************************************************** +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THE BANNER +# ***************************************************************** +# Remove old version of PresencePolling in system, since this moved to system-ext +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/PresencePolling) +# ****************************************************************** +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER +# ****************************************************************** diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/CapabilityPolling.java b/rcs/presencepolling/src/com/android/service/ims/presence/CapabilityPolling.java index d2e2178..5002b60 100644 --- a/rcs/presencepolling/src/com/android/service/ims/presence/CapabilityPolling.java +++ b/rcs/presencepolling/src/com/android/service/ims/presence/CapabilityPolling.java @@ -31,6 +31,7 @@ package com.android.service.ims.presence; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -44,7 +45,9 @@ import android.telephony.PhoneNumberUtils; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.ims.ImsException; +import android.telephony.ims.ImsManager; import android.telephony.ims.ProvisioningManager; +import android.telephony.ims.RcsUceAdapter; import android.text.format.TimeMigrationUtils; import android.text.TextUtils; @@ -62,6 +65,10 @@ public class CapabilityPolling { private Logger logger = Logger.getLogger(this.getClass().getName()); private final Context mContext; + private static final String PERSIST_SERVICE_NAME = + "com.android.service.ims.presence.PersistService"; + private static final String PERSIST_SERVICE_PACKAGE = "com.android.service.ims.presence"; + public static final String ACTION_PERIODICAL_DISCOVERY_ALARM = "com.android.service.ims.presence.periodical_capability_discovery"; private PendingIntent mDiscoveryAlarmIntent = null; @@ -83,6 +90,7 @@ public class CapabilityPolling { private int mPublished = -1; private int mProvisioned = -1; private int mDefaultSubId; + private boolean isInitializing = false; private HandlerThread mDiscoveryThread; private Handler mDiscoveryHandler; @@ -126,6 +134,25 @@ public class CapabilityPolling { } }; + private RcsUceAdapter.OnPublishStateChangedListener mPublishStateCallback = + new RcsUceAdapter.OnPublishStateChangedListener() { + @Override + public void onPublishStateChange(int publishState) { + logger.info("publish state changed: " + publishState); + Intent intent = new Intent(RcsPresence.ACTION_PUBLISH_STATE_CHANGED); + intent.putExtra(RcsPresence.EXTRA_PUBLISH_STATE, publishState); + mContext.sendStickyBroadcast(intent); + launchPersistService(intent); + } + }; + + private void launchPersistService(Intent intent) { + ComponentName component = new ComponentName(PERSIST_SERVICE_PACKAGE, + PERSIST_SERVICE_NAME); + intent.setComponent(component); + mContext.startService(intent); + } + private Runnable mRegisterCallbackRunnable = this::tryProvisioningManagerRegistration; private static CapabilityPolling sInstance = null; @@ -234,6 +261,7 @@ public class CapabilityPolling { cancelDiscoveryAlarm(); clearPollingTasks(); mContext.unregisterReceiver(mReceiver); + unregisterPublishStateChangedCallback(); mDiscoveryThread.quit(); if (SubscriptionManager.isValidSubscriptionId(mDefaultSubId)) { @@ -253,6 +281,29 @@ public class CapabilityPolling { mContext.registerReceiver(mReceiver, intentFilter); } + private void registerPublishStateChangedCallback() { + try { + ImsManager imsManager = + (ImsManager) mContext.getSystemService(Context.TELEPHONY_IMS_SERVICE); + RcsUceAdapter uceAdapter = imsManager.getImsRcsManager(mDefaultSubId).getUceAdapter(); + uceAdapter.addOnPublishStateChangedListener(mContext.getMainExecutor(), + mPublishStateCallback); + } catch (Exception ex) { + logger.warn("register publish state callback failed, exception: " + ex); + } + } + + private void unregisterPublishStateChangedCallback() { + try { + ImsManager imsManager = + (ImsManager) mContext.getSystemService(Context.TELEPHONY_IMS_SERVICE); + RcsUceAdapter uceAdapter = imsManager.getImsRcsManager(mDefaultSubId).getUceAdapter(); + uceAdapter.removeOnPublishStateChangedListener(mPublishStateCallback); + } catch (Exception ex) { + logger.warn("unregister publish state callback failed, exception: " + ex); + } + } + private boolean isPollingReady() { RcsManager rcsManager = RcsManager.getInstance(mContext, 0); if (rcsManager != null) { @@ -423,7 +474,7 @@ public class CapabilityPolling { intent.putExtra("pollingType", type); mDiscoveryAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent, - PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + msec, mDiscoveryAlarmIntent); @@ -755,18 +806,23 @@ public class CapabilityPolling { // Track the default subscription (the closest we can get to MSIM). // call from main thread only. public void handleDefaultSubscriptionChanged(int newDefaultSubId) { - logger.print("registerImsCallbacksAndSetAssociatedSubscription: new default= " + logger.print("handleDefaultSubscriptionChanged: new default= " + newDefaultSubId); + if (!SubscriptionManager.isValidSubscriptionId(newDefaultSubId)) { return; } - if (mDefaultSubId == newDefaultSubId) { + if (isInitializing && (mDefaultSubId == newDefaultSubId)) { return; + } else { + isInitializing = true; } // unregister old default first if (SubscriptionManager.isValidSubscriptionId(mDefaultSubId)) { ProvisioningManager pm = ProvisioningManager.createForSubscriptionId(mDefaultSubId); pm.unregisterProvisioningChangedCallback(mProvisioningManagerCallback); + + unregisterPublishStateChangedCallback(); } // register new default and clear old cached values in EAB only if we are changing the // default sub ID. @@ -783,6 +839,7 @@ public class CapabilityPolling { enqueueSettingsChanged(); // load settings for new default. enqueueProvisionStateChanged(); + registerPublishStateChangedCallback(); } public void tryProvisioningManagerRegistration() { diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/PollingService.java b/rcs/presencepolling/src/com/android/service/ims/presence/PollingService.java index ed511e7..8bfd8d1 100644 --- a/rcs/presencepolling/src/com/android/service/ims/presence/PollingService.java +++ b/rcs/presencepolling/src/com/android/service/ims/presence/PollingService.java @@ -209,6 +209,7 @@ public class PollingService extends Service { logger.info("Starting CapabilityPolling..."); mCapabilityPolling = CapabilityPolling.getInstance(this); mCapabilityPolling.start(); + mCapabilityPolling.handleDefaultSubscriptionChanged(mDefaultSubId); } } diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/PollingTask.java b/rcs/presencepolling/src/com/android/service/ims/presence/PollingTask.java index f3b17dd..b9835bb 100644 --- a/rcs/presencepolling/src/com/android/service/ims/presence/PollingTask.java +++ b/rcs/presencepolling/src/com/android/service/ims/presence/PollingTask.java @@ -201,7 +201,7 @@ public class PollingTask { intent.putExtra("pollingTaskId", mId); mRetryAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent, - PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); @@ -254,4 +254,3 @@ public class PollingTask { return sb.toString(); } } - diff --git a/rcs/presencepolling/tests/Android.bp b/rcs/presencepolling/tests/Android.bp index 3dfc931..9f0bdd1 100644 --- a/rcs/presencepolling/tests/Android.bp +++ b/rcs/presencepolling/tests/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "external_ims_rcs_presencepolling_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["external_ims_rcs_presencepolling_license"], +} + android_test { name: "PresencePollingTests", srcs: ["src/**/*.java"], diff --git a/rcs/rcsmanager/Android.bp b/rcs/rcsmanager/Android.bp index 8a12412..0058f80 100644 --- a/rcs/rcsmanager/Android.bp +++ b/rcs/rcsmanager/Android.bp @@ -24,6 +24,23 @@ // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH // DAMAGE. +package { + default_applicable_licenses: ["external_ims_rcs_rcsmanager_license"], +} + +// Added automatically by a large-scale-change +// See: http://go/android-license-faq +license { + name: "external_ims_rcs_rcsmanager_license", + visibility: [":__subpackages__"], + license_kinds: [ + "SPDX-license-identifier-BSD", + ], + license_text: [ + "LICENSE", + ], +} + java_library { name: "com.android.ims.rcsmanager", aidl: { diff --git a/rcs/rcsmanager/src/java/com/android/ims/ResultCode.java b/rcs/rcsmanager/src/java/com/android/ims/ResultCode.java index 2119d5c..8934115 100644 --- a/rcs/rcsmanager/src/java/com/android/ims/ResultCode.java +++ b/rcs/rcsmanager/src/java/com/android/ims/ResultCode.java @@ -178,4 +178,18 @@ public class ResultCode { * The Client should not send any EAB traffic after get this error. */ public static final int PUBLISH_NOT_PROVISIONED = ResultCode.SUBSCRIBER_ERROR_CODE_END - 3; + + public static final int PUBLISH_NOT_REGISTERED = ResultCode.SUBSCRIBER_ERROR_CODE_END - 4; + + public static final int PUBLISH_FORBIDDEN = ResultCode.SUBSCRIBER_ERROR_CODE_END - 5; + + public static final int PUBLISH_NOT_FOUND = ResultCode.SUBSCRIBER_ERROR_CODE_END - 6; + + public static final int PUBLISH_REQUEST_TIMEOUT = ResultCode.SUBSCRIBER_ERROR_CODE_END - 7; + + public static final int PUBLISH_TOO_LARGE = ResultCode.SUBSCRIBER_ERROR_CODE_END - 8; + + public static final int PUBLISH_TOO_SHORT = ResultCode.SUBSCRIBER_ERROR_CODE_END - 9; + + public static final int PUBLISH_TEMPORARY_ERROR = ResultCode.SUBSCRIBER_ERROR_CODE_END - 10; } diff --git a/rcs/rcsmanager/src/java/com/android/ims/internal/ContactNumberUtils.java b/rcs/rcsmanager/src/java/com/android/ims/internal/ContactNumberUtils.java index 1ed03f9..094afb4 100644 --- a/rcs/rcsmanager/src/java/com/android/ims/internal/ContactNumberUtils.java +++ b/rcs/rcsmanager/src/java/com/android/ims/internal/ContactNumberUtils.java @@ -134,7 +134,9 @@ public class ContactNumberUtils { public static int NUMBER_INVALID = 5; /** - * Check if it is a valid contact number for presence + * Check if it is a valid contact number for presence. + * + * Note: mContext must be set via setContext() before calling this method. * * @param phoneNumber read from contact db. * @return contact number error code. @@ -161,7 +163,16 @@ public class ContactNumberUtils { return NUMBER_INVALID; } - if (PhoneNumberUtils.isEmergencyNumber(number)) { + boolean isEmergencyNumber; + if (mContext == null) { + Log.e(TAG, "context is unexpectedly null to provide emergency identification service"); + isEmergencyNumber = false; + } else { + TelephonyManager tm = mContext.getSystemService(TelephonyManager.class); + isEmergencyNumber = tm.isEmergencyNumber(number); + } + + if (isEmergencyNumber) { return NUMBER_EMERGENCY; // TODO: To handle short code //} else if ((mContext != null) && PhoneNumberUtils.isN11Number(mContext, number)) { diff --git a/rcs/rcsservice/Android.bp b/rcs/rcsservice/Android.bp index 775275b..ad24544 100644 --- a/rcs/rcsservice/Android.bp +++ b/rcs/rcsservice/Android.bp @@ -28,6 +28,23 @@ // Build the application : Presence.apk //######################################################################### +package { + default_applicable_licenses: ["external_ims_rcs_rcsservice_license"], +} + +// Added automatically by a large-scale-change +// See: http://go/android-license-faq +license { + name: "external_ims_rcs_rcsservice_license", + visibility: [":__subpackages__"], + license_kinds: [ + "SPDX-license-identifier-BSD", + ], + license_text: [ + "LICENSE", + ], +} + java_library { name: "ucepresencelib", // We only want this to be used as a static import. @@ -44,7 +61,6 @@ java_library { android_app { // This is the target being built. (Name of APK) name: "RcsService", - platform_apis: true, // Only compile source java files in this apk. srcs: [ "src/com/android/service/ims/AlarmBroadcastReceiver.java", @@ -62,4 +78,6 @@ android_app { "com.android.ims.rcsmanager" ], certificate: "platform", + system_ext_specific: true, + platform_apis: true, } diff --git a/rcs/rcsservice/AndroidManifest.xml b/rcs/rcsservice/AndroidManifest.xml index 77921c3..6d108a1 100644 --- a/rcs/rcsservice/AndroidManifest.xml +++ b/rcs/rcsservice/AndroidManifest.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8" standalone="no"?> +<?xml version="1.0" encoding="utf-8"?> <!-- * Copyright (c) 2015, Motorola Mobility LLC * All rights reserved. @@ -28,23 +28,22 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" - android:versionCode="1" - android:versionName="2.4.6" - coreApp="true" - android:sharedUserId="android.uid.phone" - package="com.android.service.ims"> + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:versionCode="1" + android:versionName="2.4.6" + coreApp="true" + android:sharedUserId="android.uid.phone" + package="com.android.service.ims"> <uses-sdk android:minSdkVersion="19"/> - <permission - android:name="com.android.ims.rcs.permission.STATUS_CHANGED" - android:protectionLevel="signatureOrSystem" /> + <permission android:name="com.android.ims.rcs.permission.STATUS_CHANGED" + android:protectionLevel="signatureOrSystem"/> <permission android:name="com.android.ims.permission.PRESENCE_ACCESS" - android:label="@string/ims_presence_permission" - android:description="@string/ims_ims_permission_desc" - android:protectionLevel="signatureOrSystem" /> + android:label="@string/ims_presence_permission" + android:description="@string/ims_ims_permission_desc" + android:protectionLevel="signatureOrSystem"/> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.BROADCAST_STICKY"/> @@ -55,24 +54,27 @@ <uses-permission android:name="com.android.ims.permission.PRESENCE_ACCESS"/> <uses-permission android:name="com.android.rcs.eab.permission.READ_WRITE_EAB"/> - <application android:name="RcsServiceApp" android:persistent="true" - android:process="com.android.ims.rcsservice"> + <application android:name="RcsServiceApp" + android:persistent="true" + android:process="com.android.ims.rcsservice"> <service android:name="com.android.service.ims.RcsService" - android:exported="true" - android:enabled="true" - android:permission="com.android.ims.permission.PRESENCE_ACCESS"> + android:exported="true" + android:enabled="true" + android:permission="com.android.ims.permission.PRESENCE_ACCESS"> </service> <receiver android:name="com.android.service.ims.DeviceShutdown" - androidprv:systemUserOnly="true"> + androidprv:systemUserOnly="true" + android:exported="true"> <intent-filter> <action android:name="android.intent.action.ACTION_SHUTDOWN"/> </intent-filter> </receiver> <receiver android:name=".AlarmBroadcastReceiver" - android:permission="com.android.ims.permission.PRESENCE_ACCESS" - androidprv:systemUserOnly="true"> + android:permission="com.android.ims.permission.PRESENCE_ACCESS" + androidprv:systemUserOnly="true" + android:exported="true"> <intent-filter> <action android:name="com.android.service.ims.presence.retry"/> <action android:name="com.android.service.ims.presence.task.timeout"/> diff --git a/rcs/rcsservice/CleanSpec.mk b/rcs/rcsservice/CleanSpec.mk new file mode 100644 index 0000000..5fb4204 --- /dev/null +++ b/rcs/rcsservice/CleanSpec.mk @@ -0,0 +1,45 @@ +# Copyright (C) 2021 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. +# + +# If you don't need to do a full clean build but would like to touch +# a file or delete some intermediate files, add a clean step to the end +# of the list. These steps will only be run once, if they haven't been +# run before. +# +# E.g.: +# $(call add-clean-step, touch -c external/sqlite/sqlite3.h) +# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates) +# +# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with +# files that are missing or have been moved. +# +# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory. +# Use $(OUT_DIR) to refer to the "out" directory. +# +# If you need to re-do something that's already mentioned, just copy +# the command and add it to the bottom of the list. E.g., if a change +# that you made last week required touching a file and a change you +# made today requires touching the same file, just copy the old +# touch step and add it to the end of the list. +# +# ***************************************************************** +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THE BANNER +# ***************************************************************** +# Remove old version of RcsService in system, since this moved to system-ext +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/RcsService) + +# ****************************************************************** +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER +# ****************************************************************** diff --git a/rcs/rcsservice/src/com/android/service/ims/PresenceInfoParser.java b/rcs/rcsservice/src/com/android/service/ims/PresenceInfoParser.java index 5edb9a1..dac1401 100644 --- a/rcs/rcsservice/src/com/android/service/ims/PresenceInfoParser.java +++ b/rcs/rcsservice/src/com/android/service/ims/PresenceInfoParser.java @@ -29,7 +29,10 @@ package com.android.service.ims; import android.net.Uri; +import android.telephony.ims.RcsContactPresenceTuple; +import android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities; import android.telephony.ims.RcsContactUceCapability; +import android.telephony.ims.RcsContactUceCapability.PresenceBuilder; import java.lang.String; import java.util.ArrayList; @@ -274,36 +277,57 @@ public class PresenceInfoParser{ } public static RcsContactUceCapability getUceCapability(RcsPresenceInfo info) { - RcsContactUceCapability.Builder result = new RcsContactUceCapability.Builder( - PresenceUtils.convertContactNumber(info.getContactNumber())); + boolean volteCapable = false; if (ServiceState.ONLINE == info.getServiceState(ServiceType.VOLTE_CALL)) { - result.add(RcsContactUceCapability.CAPABILITY_IP_VOICE_CALL, - PresenceUtils.convertContactNumber( - info.getServiceContact(ServiceType.VOLTE_CALL))); + volteCapable = true; } + + boolean vtCapable = false; if (ServiceState.ONLINE == info.getServiceState(ServiceType.VT_CALL)) { - result.add(RcsContactUceCapability.CAPABILITY_IP_VIDEO_CALL, - PresenceUtils.convertContactNumber( - info.getServiceContact(ServiceType.VT_CALL))); + vtCapable = true; } - return result.build(); + + ServiceCapabilities.Builder servCapsBuilder = new ServiceCapabilities.Builder( + volteCapable, vtCapable); + servCapsBuilder.addSupportedDuplexMode(ServiceCapabilities.DUPLEX_MODE_FULL); + + Uri contactUri = PresenceUtils.convertContactNumber(info.getContactNumber()); + + RcsContactPresenceTuple.Builder tupleBuilder = new RcsContactPresenceTuple.Builder( + RcsContactPresenceTuple.TUPLE_BASIC_STATUS_OPEN, + RcsContactPresenceTuple.SERVICE_ID_MMTEL, "1.0"); + tupleBuilder.setContactUri(contactUri).setServiceCapabilities(servCapsBuilder.build()); + + PresenceBuilder presenceBuilder = new PresenceBuilder(contactUri, + RcsContactUceCapability.SOURCE_TYPE_CACHED, + RcsContactUceCapability.REQUEST_RESULT_FOUND); + presenceBuilder.addCapabilityTuple(tupleBuilder.build()); + + return presenceBuilder.build(); } public static RcsPresenceInfo getRcsPresenceInfo(RcsContactUceCapability capability) { - int volteCapable = capability.isCapable(RcsContactUceCapability.CAPABILITY_IP_VOICE_CALL) ? - ServiceState.ONLINE : ServiceState.OFFLINE; - int vtCapable = capability.isCapable(RcsContactUceCapability.CAPABILITY_IP_VIDEO_CALL) ? - ServiceState.ONLINE : ServiceState.OFFLINE; + int volteCapable = ServiceState.OFFLINE; + int vtCapable = ServiceState.OFFLINE; + RcsContactPresenceTuple presenceTuple = capability.getCapabilityTuple( + RcsContactPresenceTuple.SERVICE_ID_MMTEL); + if (presenceTuple != null) { + ServiceCapabilities serviceCaps = presenceTuple.getServiceCapabilities(); + if (serviceCaps != null && serviceCaps.isAudioCapable()) { + volteCapable = ServiceState.ONLINE; + } + if (serviceCaps != null && serviceCaps.isVideoCapable()) { + vtCapable = ServiceState.ONLINE; + } + } return new RcsPresenceInfo(capability.getContactUri().getSchemeSpecificPart(), // Not sure what the difference is, just track voice capable. (volteCapable == ServiceState.ONLINE) ? RcsPresenceInfo.VolteStatus.VOLTE_ENABLED : RcsPresenceInfo.VolteStatus.VOLTE_DISABLED, volteCapable, - PresenceUtils.getNumber(capability.getServiceUri( - RcsContactUceCapability.CAPABILITY_IP_VOICE_CALL)), + PresenceUtils.getNumber(capability.getContactUri()), // We always use system current time instead of time from server System.currentTimeMillis(), vtCapable, - PresenceUtils.getNumber(capability.getServiceUri( - RcsContactUceCapability.CAPABILITY_IP_VIDEO_CALL)), + PresenceUtils.getNumber(capability.getContactUri()), // We always use system current time instead of time from server System.currentTimeMillis()); } diff --git a/rcs/rcsservice/src/com/android/service/ims/RcsService.java b/rcs/rcsservice/src/com/android/service/ims/RcsService.java index cbd4a8b..7d7b744 100644 --- a/rcs/rcsservice/src/com/android/service/ims/RcsService.java +++ b/rcs/rcsservice/src/com/android/service/ims/RcsService.java @@ -218,7 +218,7 @@ public class RcsService extends Service { mRcsStackAdaptor.getListener().setPresenceSubscriber(mSubscriber); mPublication.setSubscriber(mSubscriber); - ConnectivityManager cm = ConnectivityManager.from(this); + final ConnectivityManager cm = getSystemService(ConnectivityManager.class); if (cm != null) { boolean enabled = Settings.Global.getInt(getContentResolver(), Settings.Global.MOBILE_DATA, 1) == 1; @@ -275,15 +275,12 @@ public class RcsService extends Service { return; } int defaultSub = RcsSettingUtils.getDefaultSubscriptionId(this); - if (!SubscriptionManager.isValidSubscriptionId(defaultSub)) { - mAssociatedSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID; - handleAssociatedSubscriptionChanged(mAssociatedSubscription); - return; + // If the presence SIP PUBLISH procedure is not supported, treat it as if there is no valid + // associated sub + if (!RcsSettingUtils.isPublishEnabled(this, defaultSub)) { + defaultSub = SubscriptionManager.INVALID_SUBSCRIPTION_ID; } - ImsMmTelManager imsManager = ImsMmTelManager.createForSubscriptionId(defaultSub); - ProvisioningManager provisioningManager = - ProvisioningManager.createForSubscriptionId(defaultSub); try { if (defaultSub == mAssociatedSubscription) { // Don't register duplicate callbacks for the same subscription. @@ -301,15 +298,23 @@ public class RcsService extends Service { mProvisioningChangedCallback); logger.print("callbacks unregistered for sub " + mAssociatedSubscription); } - // move over registrations. - imsManager.registerImsRegistrationCallback(getMainExecutor(), mImsRegistrationCallback); - imsManager.registerMmTelCapabilityCallback(getMainExecutor(), mCapabilityCallback); - provisioningManager.registerProvisioningChangedCallback(getMainExecutor(), - mProvisioningChangedCallback); - mAssociatedSubscription = defaultSub; + if (SubscriptionManager.isValidSubscriptionId(defaultSub)) { + ImsMmTelManager imsManager = ImsMmTelManager.createForSubscriptionId(defaultSub); + ProvisioningManager provisioningManager = + ProvisioningManager.createForSubscriptionId(defaultSub); + // move over registrations if the new sub id is valid. + imsManager.registerImsRegistrationCallback(getMainExecutor(), + mImsRegistrationCallback); + imsManager.registerMmTelCapabilityCallback(getMainExecutor(), mCapabilityCallback); + provisioningManager.registerProvisioningChangedCallback(getMainExecutor(), + mProvisioningChangedCallback); + mAssociatedSubscription = defaultSub; + logger.print("callbacks registered for sub " + mAssociatedSubscription); + } else { + mAssociatedSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID; + } logger.print("registerImsCallbacksAndSetAssociatedSubscription: new default=" - + defaultSub); - logger.print("callbacks registered for sub " + mAssociatedSubscription); + + mAssociatedSubscription); handleAssociatedSubscriptionChanged(mAssociatedSubscription); } catch (ImsException e) { logger.info("Couldn't register callbacks for " + defaultSub + ": " diff --git a/rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java b/rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java index 056e4d0..d39952f 100644 --- a/rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java +++ b/rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java @@ -134,6 +134,21 @@ public class RcsSettingUtils { return isProvisioned; } + public static boolean isPublishEnabled(Context context, int subId) { + if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + logger.debug("isPublishEnabled: no valid subscriptions!"); + return false; + } + CarrierConfigManager configManager = (CarrierConfigManager) + context.getSystemService(Context.CARRIER_CONFIG_SERVICE); + if (configManager != null) { + PersistableBundle config = configManager.getConfigForSubId(subId); + return (config != null) && config.getBoolean( + CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, false); + } + return false; + } + public static boolean hasUserEnabledContactDiscovery(Context context, int subId) { if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { logger.debug("hasUserEnabledContactDiscovery: no valid subscriptions!"); diff --git a/rcs/rcsservice/src/com/android/service/ims/RcsStackAdaptor.java b/rcs/rcsservice/src/com/android/service/ims/RcsStackAdaptor.java index d864701..e279c83 100644 --- a/rcs/rcsservice/src/com/android/service/ims/RcsStackAdaptor.java +++ b/rcs/rcsservice/src/com/android/service/ims/RcsStackAdaptor.java @@ -44,6 +44,8 @@ import android.os.SystemClock; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; +import android.telephony.ims.RcsContactPresenceTuple; +import android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities; import android.telephony.ims.RcsContactUceCapability; import com.android.ims.ResultCode; @@ -253,14 +255,16 @@ public class RcsStackAdaptor implements PresencePublisher, SubscribePublisher { public void updatePublisherState(@PresenceBase.PresencePublishState int publishState) { synchronized (mSyncObj) { logger.print("mPublishingState=" + mPublishingState + " publishState=" + publishState); + if (mPublishingState != publishState ) { + Intent publishIntent = new Intent(RcsPresence.ACTION_PUBLISH_STATE_CHANGED); + publishIntent.putExtra(RcsPresence.EXTRA_PUBLISH_STATE, publishState); + // Start PersistService and broadcast to other receivers that are listening + // dynamically. + mContext.sendStickyBroadcast(publishIntent); + launchPersistService(publishIntent); + } mPublishingState = publishState; } - Intent publishIntent = new Intent(RcsPresence.ACTION_PUBLISH_STATE_CHANGED); - publishIntent.putExtra(RcsPresence.EXTRA_PUBLISH_STATE, publishState); - // Start PersistService and broadcast to other receivers that are listening - // dynamically. - mContext.sendStickyBroadcast(publishIntent); - launchPersistService(publishIntent); } @Override @@ -376,10 +380,8 @@ public class RcsStackAdaptor implements PresencePublisher, SubscribePublisher { pMyCapInfo.setContactUri(myUri); CapInfo capInfo = new CapInfo(); - capInfo.setIpVoiceSupported(capabilities.isCapable( - RcsContactUceCapability.CAPABILITY_IP_VOICE_CALL)); - capInfo.setIpVideoSupported(capabilities.isCapable( - RcsContactUceCapability.CAPABILITY_IP_VIDEO_CALL)); + capInfo.setIpVoiceSupported(isVolteSupported(capabilities)); + capInfo.setIpVideoSupported(isVtSupported(capabilities)); capInfo.setCdViaPresenceSupported(true); capInfo.setFtSupported(false); // TODO: support FT @@ -417,6 +419,30 @@ public class RcsStackAdaptor implements PresencePublisher, SubscribePublisher { return ResultCode.SUCCESS; } + private boolean isVolteSupported(RcsContactUceCapability capabilities) { + RcsContactPresenceTuple presenceTuple = capabilities.getCapabilityTuple( + RcsContactPresenceTuple.SERVICE_ID_MMTEL); + if (presenceTuple != null) { + ServiceCapabilities serviceCaps = presenceTuple.getServiceCapabilities(); + if (serviceCaps != null && serviceCaps.isAudioCapable()) { + return true; + } + } + return false; + } + + private boolean isVtSupported(RcsContactUceCapability capabilities) { + RcsContactPresenceTuple presenceTuple = capabilities.getCapabilityTuple( + RcsContactPresenceTuple.SERVICE_ID_MMTEL); + if (presenceTuple != null) { + ServiceCapabilities serviceCaps = presenceTuple.getServiceCapabilities(); + if (serviceCaps != null && serviceCaps.isVideoCapable()) { + return true; + } + } + return false; + } + private void launchPersistService(Intent intent) { ComponentName component = new ComponentName(PERSIST_SERVICE_PACKAGE, PERSIST_SERVICE_NAME); @@ -671,7 +697,7 @@ public class RcsStackAdaptor implements PresencePublisher, SubscribePublisher { intent.putExtra("times", times); intent.setPackage(mContext.getPackageName()); mRetryAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent, - PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); // Wait for 1s to ignore duplicate init request as possible as we can. long timeSkip = 1000; diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceCapabilityTask.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceCapabilityTask.java index e94e51a..fb22b5e 100644 --- a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceCapabilityTask.java +++ b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceCapabilityTask.java @@ -109,7 +109,7 @@ public class PresenceCapabilityTask extends PresenceTask{ intent.setPackage(mContext.getPackageName()); intent.putExtra("taskId", mTaskId); PendingIntent mAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent, - PendingIntent.FLAG_ONE_SHOT); + PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT); if(sAlarmManager == null){ sAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); @@ -162,4 +162,3 @@ public class PresenceCapabilityTask extends PresenceTask{ TaskManager.getDefault().removeTask(mTaskId); } }; - diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublication.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublication.java index 0b6b2ea..29391f7 100644 --- a/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublication.java +++ b/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublication.java @@ -44,7 +44,10 @@ import android.telecom.TelecomManager; import android.telephony.AccessNetworkConstants; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; +import android.telephony.ims.RcsContactPresenceTuple; +import android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities; import android.telephony.ims.RcsContactUceCapability; +import android.telephony.ims.RcsContactUceCapability.PresenceBuilder; import android.telephony.ims.feature.MmTelFeature; import android.text.TextUtils; @@ -906,14 +909,10 @@ public class PresencePublication extends PresenceBase { return; } - RcsContactUceCapability.Builder presenceInfoBuilder = - new RcsContactUceCapability.Builder(myUri); - if (publishRequest.getVolteCapable()) { - presenceInfoBuilder.add(RcsContactUceCapability.CAPABILITY_IP_VOICE_CALL); - } - if (publishRequest.getVtCapable()) { - presenceInfoBuilder.add(RcsContactUceCapability.CAPABILITY_IP_VIDEO_CALL); - } + boolean isVolteCapble = publishRequest.getVolteCapable(); + boolean isVtCapable = publishRequest.getVtCapable(); + RcsContactUceCapability presenceInfo = + getRcsContactUceCapability(myUri, isVolteCapble, isVtCapable); synchronized(mSyncObj) { mPublishingRequest = publishRequest; @@ -923,8 +922,7 @@ public class PresencePublication extends PresenceBase { String myNumber = getNumberFromUri(myUri); int taskId = TaskManager.getDefault().addPublishTask(myNumber); logger.print("doPublish, uri=" + myUri + ", myNumber=" + myNumber + ", taskId=" + taskId); - int ret = presencePublisher.requestPublication(presenceInfoBuilder.build(), - myUri.toString(), taskId); + int ret = presencePublisher.requestPublication(presenceInfo, myUri.toString(), taskId); if (ret != ResultCode.SUCCESS) { logger.print("doPublish, task=" + taskId + " failed with code=" + ret); TaskManager.getDefault().removeTask(taskId); @@ -933,6 +931,27 @@ public class PresencePublication extends PresenceBase { mHasCachedTrigger = (ret == ResultCode.ERROR_SERVICE_NOT_AVAILABLE); } + private RcsContactUceCapability getRcsContactUceCapability(Uri contact, boolean isVolteCapable, + boolean isVtCapable) { + + ServiceCapabilities.Builder servCapsBuilder = new ServiceCapabilities.Builder( + isVolteCapable, isVtCapable); + servCapsBuilder.addSupportedDuplexMode(ServiceCapabilities.DUPLEX_MODE_FULL); + + RcsContactPresenceTuple.Builder tupleBuilder = new RcsContactPresenceTuple.Builder( + RcsContactPresenceTuple.TUPLE_BASIC_STATUS_OPEN, + RcsContactPresenceTuple.SERVICE_ID_MMTEL, "1.0"); + tupleBuilder.setContactUri(contact) + .setServiceCapabilities(servCapsBuilder.build()); + + PresenceBuilder presenceBuilder = new PresenceBuilder(contact, + RcsContactUceCapability.SOURCE_TYPE_CACHED, + RcsContactUceCapability.REQUEST_RESULT_FOUND); + presenceBuilder.addCapabilityTuple(tupleBuilder.build()); + + return presenceBuilder.build(); + } + private String getNumberFromUri(Uri uri) { if (uri == null) return null; String number = uri.getSchemeSpecificPart(); @@ -1014,7 +1033,7 @@ public class PresencePublication extends PresenceBase { Intent intent = new Intent(ACTION_RETRY_PUBLISH_ALARM); intent.setPackage(mContext.getPackageName()); mRetryAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent, - PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent.FLAG_UPDATE_CURRENT|PendingIntent.FLAG_IMMUTABLE); if(mAlarmManager == null) { mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceSubscriber.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceSubscriber.java index c804675..fb2b57e 100644 --- a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceSubscriber.java +++ b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceSubscriber.java @@ -29,9 +29,11 @@ package com.android.service.ims.presence; import android.content.Context; +import android.net.Uri; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.ims.RcsContactUceCapability; +import android.telephony.ims.RcsContactUceCapability.PresenceBuilder; import android.text.TextUtils; import com.android.ims.ResultCode; @@ -449,8 +451,8 @@ public class PresenceSubscriber extends PresenceBase { } logger.debug("onSipResponse: contact= " + contacts[i] + ", not found."); // Build contacts with no capabilities. - contactCapabilities.add(new RcsContactUceCapability.Builder( - PresenceUtils.convertContactNumber(contacts[i])).build()); + contactCapabilities.add(buildContactWithNoCapabilities( + PresenceUtils.convertContactNumber(contacts[i]))); } handleCapabilityUpdate(task, contactCapabilities, true); @@ -461,6 +463,13 @@ public class PresenceSubscriber extends PresenceBase { handleCallback(task, errorCode, false); } + private RcsContactUceCapability buildContactWithNoCapabilities(Uri contactUri) { + PresenceBuilder presenceBuilder = new PresenceBuilder(contactUri, + RcsContactUceCapability.SOURCE_TYPE_CACHED, + RcsContactUceCapability.REQUEST_RESULT_FOUND); + return presenceBuilder.build(); + } + private void handleCapabilityUpdate(Task task, List<RcsContactUceCapability> capabilities, boolean updateLastTimestamp) { if (task == null || task.mListener == null ) { @@ -568,8 +577,11 @@ public class PresenceSubscriber extends PresenceBase { continue; } // Add each contacts with no capabilities. - presenceInfoList.add(new RcsContactUceCapability.Builder( - PresenceUtils.convertContactNumber(task.mContacts[i])).build()); + Uri uri = PresenceUtils.convertContactNumber(task.mContacts[i]); + PresenceBuilder presenceBuilder = new PresenceBuilder(uri, + RcsContactUceCapability.SOURCE_TYPE_CACHED, + RcsContactUceCapability.REQUEST_RESULT_FOUND); + presenceInfoList.add(presenceBuilder.build()); } if(presenceInfoList.size() > 0) { |