summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/res/AndroidManifest.xml8
-rw-r--r--services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java77
-rw-r--r--services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionServiceTest.java61
3 files changed, 146 insertions, 0 deletions
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 05b38a562e29..4edf74c55f9f 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -8206,6 +8206,14 @@
</intent-filter>
</service>
+ <service android:name="com.android.server.companion.datatransfer.contextsync.CallMetadataSyncConnectionService"
+ android:permission="android.permission.BIND_CONNECTION_SERVICE"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.telecom.ConnectionService"/>
+ </intent-filter>
+ </service>
+
<provider
android:name="com.android.server.textclassifier.IconsContentProvider"
android:authorities="com.android.textclassifier.icons"
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java
new file mode 100644
index 000000000000..19d8b8783d81
--- /dev/null
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.companion.datatransfer.contextsync;
+
+import android.content.ComponentName;
+import android.telecom.ConnectionService;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/** Service for Telecom to bind to when call metadata is synced between devices. */
+public class CallMetadataSyncConnectionService extends ConnectionService {
+
+ private TelecomManager mTelecomManager;
+ private final Map<String, PhoneAccountHandle> mPhoneAccountHandles = new HashMap<>();
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mTelecomManager = getSystemService(TelecomManager.class);
+ }
+
+ /**
+ * Registers a {@link android.telecom.PhoneAccount} for a given call-capable app on the synced
+ * device.
+ */
+ public void registerPhoneAccount(String packageName, String humanReadableAppName) {
+ final PhoneAccount phoneAccount = createPhoneAccount(packageName, humanReadableAppName);
+ if (phoneAccount != null) {
+ mTelecomManager.registerPhoneAccount(phoneAccount);
+ mTelecomManager.enablePhoneAccount(mPhoneAccountHandles.get(packageName), true);
+ }
+ }
+
+ /**
+ * Unregisters a {@link android.telecom.PhoneAccount} for a given call-capable app on the synced
+ * device.
+ */
+ public void unregisterPhoneAccount(String packageName) {
+ mTelecomManager.unregisterPhoneAccount(mPhoneAccountHandles.remove(packageName));
+ }
+
+ @VisibleForTesting
+ PhoneAccount createPhoneAccount(String packageName, String humanReadableAppName) {
+ if (mPhoneAccountHandles.containsKey(packageName)) {
+ // Already exists!
+ return null;
+ }
+ final PhoneAccountHandle handle = new PhoneAccountHandle(
+ new ComponentName(this, CallMetadataSyncConnectionService.class),
+ UUID.randomUUID().toString());
+ mPhoneAccountHandles.put(packageName, handle);
+ return new PhoneAccount.Builder(handle, humanReadableAppName)
+ .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER
+ | PhoneAccount.CAPABILITY_SELF_MANAGED).build();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionServiceTest.java
new file mode 100644
index 000000000000..3ed95eb3c878
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionServiceTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.companion.datatransfer.contextsync;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.platform.test.annotations.Presubmit;
+import android.telecom.PhoneAccount;
+import android.testing.AndroidTestingRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@RunWith(AndroidTestingRunner.class)
+public class CallMetadataSyncConnectionServiceTest {
+
+ private CallMetadataSyncConnectionService mSyncConnectionService;
+
+ @Before
+ public void setUp() throws Exception {
+ mSyncConnectionService = new CallMetadataSyncConnectionService() {
+ @Override
+ public String getPackageName() {
+ return "android";
+ }
+ };
+ }
+
+ @Test
+ public void createPhoneAccount_success() {
+ final PhoneAccount phoneAccount = mSyncConnectionService.createPhoneAccount(
+ "com.google.test", "Test App");
+ assertWithMessage("Could not create phone account").that(phoneAccount).isNotNull();
+ }
+
+ @Test
+ public void createPhoneAccount_alreadyExists_doesNotCreateAnother() {
+ final PhoneAccount phoneAccount = mSyncConnectionService.createPhoneAccount(
+ "com.google.test", "Test App");
+ final PhoneAccount phoneAccount2 = mSyncConnectionService.createPhoneAccount(
+ "com.google.test", "Test App #2");
+ assertWithMessage("Could not create phone account").that(phoneAccount).isNotNull();
+ assertWithMessage("Unexpectedly created second phone account").that(phoneAccount2).isNull();
+ }
+}