summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-07-15 02:04:00 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-07-15 02:04:00 +0000
commite8ec56bca2679facd9ead218d5c784bbbaf95a16 (patch)
treeb24321ac17884be632351c22f458e3f75ece2aa2
parent64303b1fde0bcb5ad9d71043955445c03ccadd1e (diff)
parentb29f3c0303d491e2bebb50ecd48527d87f836aa9 (diff)
downloadims-android12-mainline-resolv-release.tar.gz
Change-Id: I8ffcc55846f3dc255a333543c730445d18337b42
-rw-r--r--METADATA3
-rw-r--r--rcs/presencepolling/Android.bp33
-rw-r--r--rcs/presencepolling/AndroidManifest.xml73
-rw-r--r--rcs/presencepolling/CleanSpec.mk44
-rw-r--r--rcs/presencepolling/src/com/android/service/ims/presence/CapabilityPolling.java63
-rw-r--r--rcs/presencepolling/src/com/android/service/ims/presence/PollingService.java1
-rw-r--r--rcs/presencepolling/src/com/android/service/ims/presence/PollingTask.java3
-rw-r--r--rcs/presencepolling/tests/Android.bp9
-rw-r--r--rcs/rcsmanager/Android.bp17
-rw-r--r--rcs/rcsmanager/src/java/com/android/ims/ResultCode.java14
-rw-r--r--rcs/rcsmanager/src/java/com/android/ims/internal/ContactNumberUtils.java15
-rw-r--r--rcs/rcsservice/Android.bp20
-rw-r--r--rcs/rcsservice/AndroidManifest.xml44
-rw-r--r--rcs/rcsservice/CleanSpec.mk45
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/PresenceInfoParser.java58
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/RcsService.java37
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java15
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/RcsStackAdaptor.java48
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/presence/PresenceCapabilityTask.java3
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/presence/PresencePublication.java41
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/presence/PresenceSubscriber.java20
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) {