Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9a101f6 authored by Christine Franks's avatar Christine Franks
Browse files

Add ConnectionService for Telecom to bind to

Bug: 278664139
Test: atest FrameworksServicesTests:com.android.server.companion.datatransfer.contextsync
Change-Id: I226b5f58731ffa03e39c04d1154a66954e7aa208
parent 13f1b02e
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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"
+77 −0
Original line number Diff line number Diff line
/*
 * 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();
    }
}
+61 −0
Original line number Diff line number Diff line
/*
 * 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();
    }
}