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

Commit dfa17750 authored by Christine Franks's avatar Christine Franks Committed by Automerger Merge Worker
Browse files

Merge "Send / recv contextsync messages via securechannel" into udc-dev am: 6a6bb409

parents a3033d0b 6a6bb409
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -20,9 +20,9 @@ package android.companion;

option java_multiple_files = true;

// Next index: 2
// Next index: 4
message Telecom {
  // Next index: 5
  // Next index: 6
  message Call {
    // UUID representing this call
    int64 id = 1;
@@ -34,6 +34,8 @@ message Telecom {
      // Human-readable name of the app processing this call
      string app_name = 2;
      bytes app_icon = 3;
      // Unique identifier for this app, such as a package name.
      string app_identifier = 4;
    }
    Origin origin = 2;

@@ -59,9 +61,11 @@ message Telecom {
      REJECT_AND_BLOCK = 9;
      IGNORE = 10;
    }
    repeated Control controls_available = 4;
    repeated Control controls = 4;
  }

  // The list of active calls.
  repeated Call calls = 1;
  // The list of requested calls or call changes.
  repeated Call requests = 2;
}
+41 −0
Original line number Diff line number Diff line
@@ -107,6 +107,9 @@ import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.companion.datatransfer.SystemDataTransferProcessor;
import com.android.server.companion.datatransfer.SystemDataTransferRequestStore;
import com.android.server.companion.datatransfer.contextsync.CrossDeviceCall;
import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncController;
import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncControllerCallback;
import com.android.server.companion.presence.CompanionDevicePresenceMonitor;
import com.android.server.companion.transport.CompanionTransportManager;
import com.android.server.pm.UserManagerInternal;
@@ -116,6 +119,7 @@ import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -199,6 +203,8 @@ public class CompanionDeviceManagerService extends SystemService {
    private final RemoteCallbackList<IOnAssociationsChangedListener> mListeners =
            new RemoteCallbackList<>();

    private CrossDeviceSyncController mCrossDeviceSyncController;

    public CompanionDeviceManagerService(Context context) {
        super(context);

@@ -238,6 +244,8 @@ public class CompanionDeviceManagerService extends SystemService {
        mTransportManager = new CompanionTransportManager(context, mAssociationStore);
        mSystemDataTransferProcessor = new SystemDataTransferProcessor(this, mAssociationStore,
                mSystemDataTransferRequestStore, mTransportManager);
        // TODO(b/279663946): move context sync to a dedicated system service
        mCrossDeviceSyncController = new CrossDeviceSyncController(getContext(), mTransportManager);

        // Publish "binder" service.
        final CompanionDeviceManagerImpl impl = new CompanionDeviceManagerImpl();
@@ -1353,6 +1361,39 @@ public class CompanionDeviceManagerService extends SystemService {
        public void removeInactiveSelfManagedAssociations() {
            CompanionDeviceManagerService.this.removeInactiveSelfManagedAssociations();
        }

        @Override
        public void registerCallMetadataSyncCallback(CrossDeviceSyncControllerCallback callback) {
            if (CompanionDeviceConfig.isEnabled(
                    CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
                mCrossDeviceSyncController.registerCallMetadataSyncCallback(callback);
            }
        }

        @Override
        public void crossDeviceSync(int userId, Collection<CrossDeviceCall> calls) {
            if (CompanionDeviceConfig.isEnabled(
                    CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
                mCrossDeviceSyncController.syncToAllDevicesForUserId(userId, calls);
            }
        }

        @Override
        public void crossDeviceSync(AssociationInfo associationInfo,
                Collection<CrossDeviceCall> calls) {
            if (CompanionDeviceConfig.isEnabled(
                    CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
                mCrossDeviceSyncController.syncToSingleDevice(associationInfo, calls);
            }
        }

        @Override
        public void sendCrossDeviceSyncMessage(int associationId, byte[] message) {
            if (CompanionDeviceConfig.isEnabled(
                    CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
                mCrossDeviceSyncController.syncMessageToDevice(associationId, message);
            }
        }
    }

    /**
+30 −1
Original line number Diff line number Diff line
@@ -16,12 +16,41 @@

package com.android.server.companion;

import android.companion.AssociationInfo;

import com.android.server.companion.datatransfer.contextsync.CrossDeviceCall;
import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncControllerCallback;

import java.util.Collection;

/**
 * Companion Device Manager Local System Service Interface.
 */
interface CompanionDeviceManagerServiceInternal {
public interface CompanionDeviceManagerServiceInternal {
    /**
     * @see CompanionDeviceManagerService#removeInactiveSelfManagedAssociations
     */
    void removeInactiveSelfManagedAssociations();

    /**
     * Registers a callback from an InCallService / ConnectionService to CDM to process sync
     * requests and perform call control actions.
     */
    void registerCallMetadataSyncCallback(CrossDeviceSyncControllerCallback callback);

    /**
     * Requests a sync from an InCallService / ConnectionService to CDM, for the given association
     * and message.
     */
    void sendCrossDeviceSyncMessage(int associationId, byte[] message);

    /**
     * Requests a sync from an InCallService to CDM, for the given user and call metadata.
     */
    void crossDeviceSync(int userId, Collection<CrossDeviceCall> calls);

    /**
     * Requests a sync from an InCallService to CDM, for the given association and call metadata.
     */
    void crossDeviceSync(AssociationInfo associationInfo, Collection<CrossDeviceCall> calls);
}
+124 −63
Original line number Diff line number Diff line
@@ -17,15 +17,20 @@
package com.android.server.companion.datatransfer.contextsync;

import android.annotation.Nullable;
import android.companion.AssociationInfo;
import android.telecom.Call;
import android.telecom.InCallService;
import android.telecom.TelecomManager;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import com.android.server.companion.CompanionDeviceConfig;
import com.android.server.companion.CompanionDeviceManagerServiceInternal;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.stream.Collectors;

@@ -35,21 +40,49 @@ import java.util.stream.Collectors;
 */
public class CallMetadataSyncInCallService extends InCallService {

    private static final String TAG = "CallMetadataIcs";
    private static final long NOT_VALID = -1L;

    private CompanionDeviceManagerServiceInternal mCdmsi;

    @VisibleForTesting
    final Map<Call, CrossDeviceCall> mCurrentCalls = new HashMap<>();
    @VisibleForTesting
    boolean mShouldSync;
    @VisibleForTesting int mNumberOfActiveSyncAssociations;
    final Call.Callback mTelecomCallback = new Call.Callback() {
        @Override
        public void onDetailsChanged(Call call, Call.Details details) {
            mCurrentCalls.get(call).updateCallDetails(details);
            if (mNumberOfActiveSyncAssociations > 0) {
                final CrossDeviceCall crossDeviceCall = mCurrentCalls.get(call);
                if (crossDeviceCall != null) {
                    crossDeviceCall.updateCallDetails(details);
                    sync(getUserId());
                } else {
                    Slog.w(TAG, "Could not update details for nonexistent call");
                }
            }
        }
    };
    final CallMetadataSyncCallback mCallMetadataSyncCallback = new CallMetadataSyncCallback() {
    final CrossDeviceSyncControllerCallback
            mCrossDeviceSyncControllerCallback = new CrossDeviceSyncControllerCallback() {
                @Override
        void processCallControlAction(int crossDeviceCallId, int callControlAction) {
                void processContextSyncMessage(int associationId,
                        CallMetadataSyncData callMetadataSyncData) {
                    final Iterator<CallMetadataSyncData.Call> iterator =
                            callMetadataSyncData.getRequests().iterator();
                    while (iterator.hasNext()) {
                        final CallMetadataSyncData.Call call = iterator.next();
                        if (call.getId() != 0) {
                            // The call is already assigned an id; treat as control invocations.
                            for (int control : call.getControls()) {
                                processCallControlAction(call.getId(), control);
                            }
                        }
                        iterator.remove();
                    }
                }

                private void processCallControlAction(long crossDeviceCallId,
                        int callControlAction) {
                    final CrossDeviceCall crossDeviceCall = getCallForId(crossDeviceCallId,
                            mCurrentCalls.values());
                    switch (callControlAction) {
@@ -92,16 +125,24 @@ public class CallMetadataSyncInCallService extends InCallService {
                }

                @Override
        void requestCrossDeviceSync(int userId) {
                void requestCrossDeviceSync(AssociationInfo associationInfo) {
                    if (associationInfo.getUserId() == getUserId()) {
                        sync(associationInfo);
                    }
                }

                @Override
        void updateStatus(int userId, boolean shouldSyncCallMetadata) {
                void updateNumberOfActiveSyncAssociations(int userId, boolean added) {
                    if (userId == getUserId()) {
                mShouldSync = shouldSyncCallMetadata;
                if (shouldSyncCallMetadata) {
                    initializeCalls();
                        final boolean wasActivelySyncing = mNumberOfActiveSyncAssociations > 0;
                        if (added) {
                            mNumberOfActiveSyncAssociations++;
                        } else {
                            mNumberOfActiveSyncAssociations--;
                        }
                        if (!wasActivelySyncing && mNumberOfActiveSyncAssociations > 0) {
                            initializeCalls();
                        } else if (wasActivelySyncing && mNumberOfActiveSyncAssociations <= 0) {
                            mCurrentCalls.clear();
                        }
                    }
@@ -111,14 +152,20 @@ public class CallMetadataSyncInCallService extends InCallService {
    @Override
    public void onCreate() {
        super.onCreate();
        initializeCalls();
        if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
            mCdmsi = LocalServices.getService(CompanionDeviceManagerServiceInternal.class);
            mCdmsi.registerCallMetadataSyncCallback(mCrossDeviceSyncControllerCallback);
        }
    }

    private void initializeCalls() {
        if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)
                && mShouldSync) {
                && mNumberOfActiveSyncAssociations > 0) {
            mCurrentCalls.putAll(getCalls().stream().collect(Collectors.toMap(call -> call,
                    call -> new CrossDeviceCall(getPackageManager(), call, getCallAudioState()))));
            mCurrentCalls.keySet().forEach(call -> call.registerCallback(mTelecomCallback,
                    getMainThreadHandler()));
            sync(getUserId());
        }
    }

@@ -139,33 +186,39 @@ public class CallMetadataSyncInCallService extends InCallService {
    @Override
    public void onCallAdded(Call call) {
        if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)
                && mShouldSync) {
                && mNumberOfActiveSyncAssociations > 0) {
            mCurrentCalls.put(call,
                    new CrossDeviceCall(getPackageManager(), call, getCallAudioState()));
            call.registerCallback(mTelecomCallback);
            sync(getUserId());
        }
    }

    @Override
    public void onCallRemoved(Call call) {
        if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)
                && mShouldSync) {
                && mNumberOfActiveSyncAssociations > 0) {
            mCurrentCalls.remove(call);
            call.unregisterCallback(mTelecomCallback);
            sync(getUserId());
        }
    }

    @Override
    public void onMuteStateChanged(boolean isMuted) {
        if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)
                && mShouldSync) {
                && mNumberOfActiveSyncAssociations > 0) {
            mCurrentCalls.values().forEach(call -> call.updateMuted(isMuted));
            sync(getUserId());
        }
    }

    @Override
    public void onSilenceRinger() {
        if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)
                && mShouldSync) {
                && mNumberOfActiveSyncAssociations > 0) {
            mCurrentCalls.values().forEach(call -> call.updateSilencedIfRinging());
            sync(getUserId());
        }
    }

@@ -183,4 +236,12 @@ public class CallMetadataSyncInCallService extends InCallService {
            telecomManager.silenceRinger();
        }
    }

    private void sync(int userId) {
        mCdmsi.crossDeviceSync(userId, mCurrentCalls.values());
    }

    private void sync(AssociationInfo associationInfo) {
        mCdmsi.crossDeviceSync(associationInfo, mCurrentCalls.values());
    }
}
 No newline at end of file
+272 −108

File changed.

Preview size limit exceeded, changes collapsed.

Loading