summaryrefslogtreecommitdiff
path: root/rcs/presencepolling
diff options
context:
space:
mode:
Diffstat (limited to 'rcs/presencepolling')
-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
7 files changed, 184 insertions, 42 deletions
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"],