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

Commit 2f7e83f8 authored by Joe Antonetti's avatar Joe Antonetti
Browse files

Create TaskContinuityMessenge

Create TaskContinuityMessage, which will be the primary data class
for passing application messages. Corresponding serialization and deserialization
logic has also been added

Flag: android.companion.enable_task_continuity
Test: Added unit tests for TaskContinuityMessage, and ContinuityDeviceConnected
Bug: 400970610

Change-Id: Ic5d80056647fc9a474807d45e143d572bacbafb8
parent 899202ec
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -260,6 +260,12 @@ public final class CompanionDeviceManager {
     * @hide
     * @hide
     */
     */
    public static final int MESSAGE_REQUEST_CONTEXT_SYNC = 0x63678883; // ?CXS
    public static final int MESSAGE_REQUEST_CONTEXT_SYNC = 0x63678883; // ?CXS
    /**
     * Message header assigned to task continuity messages.
     *
     * @hide
     */
    public static final int MESSAGE_TASK_CONTINUITY = 0x63678884; // ?TSK
    /**
    /**
     * Message header assigned to the permission restore request.
     * Message header assigned to the permission restore request.
     *
     *
+2 −0
Original line number Original line Diff line number Diff line
include /core/java/android/companion/OWNERS
include /core/java/android/companion/OWNERS
joeantonetti@google.com
jackshira@google.com
+32 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2025 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.
 */

syntax = "proto3";

package android.companion;

option java_multiple_files = true;

// Next index: 2
message TaskContinuityMessage {
    oneof data {
        ContinuityDeviceConnected device_connected = 1;
    }
}

message ContinuityDeviceConnected {
    int32 currentForegroundTaskId = 1;
}
+74 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2025 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.continuity.messages;

import android.util.proto.ProtoInputStream;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoParseException;

import java.io.IOException;

/**
 * Deserialized version of the {@link ContinuityDeviceConnected} proto.
 */
public class ContinuityDeviceConnected implements TaskContinuityMessageData {

    private int mCurrentForegroundTaskId = 0;

    public ContinuityDeviceConnected(int currentForegroundTaskId) {
        mCurrentForegroundTaskId = currentForegroundTaskId;
    }

    ContinuityDeviceConnected(ProtoInputStream pis)
        throws IOException, ProtoParseException {

        boolean hasReadForegroundTaskId = false;
        while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
            switch (pis.getFieldNumber()) {
                case (int) android.companion.ContinuityDeviceConnected.CURRENT_FOREGROUND_TASK_ID:
                    mCurrentForegroundTaskId = pis.readInt(
                        android.companion.ContinuityDeviceConnected.CURRENT_FOREGROUND_TASK_ID
                    );

                    hasReadForegroundTaskId = true;
                    break;
            }
        }

        if (!hasReadForegroundTaskId) {
            throw new ProtoParseException(
                "Missing required field: current_foreground_task_id");
        }
    }

    /**
     * Returns the current foreground task ID.
     */
    public int getCurrentForegroundTaskId() {
        return mCurrentForegroundTaskId;
    }

    /**
     * Writes this object to a proto output stream.
     */
    @Override
    public void writeToProto(ProtoOutputStream pos) {
        pos.writeInt32(
            android.companion.ContinuityDeviceConnected.CURRENT_FOREGROUND_TASK_ID,
            mCurrentForegroundTaskId);
    }
}
 No newline at end of file
+107 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2025 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.continuity.messages;

import android.util.proto.ProtoInputStream;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoParseException;

import java.io.IOException;

/**
 * Serialized version of the {@link TaskContinuityMessage} proto, allowing for
 * serialization and deserialization from bytes.
 */
public final class TaskContinuityMessage {

    private TaskContinuityMessageData mData;

    TaskContinuityMessage(Builder builder) {
        mData = builder.mData;
    }

    public TaskContinuityMessage(byte[] data)
        throws IOException, ProtoParseException {

        ProtoInputStream pis = new ProtoInputStream(data);
        while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
            switch (pis.getFieldNumber()) {
                case (int) android.companion.TaskContinuityMessage.DEVICE_CONNECTED:
                    final long deviceConnectedToken = pis.start(
                        android.companion.TaskContinuityMessage.DEVICE_CONNECTED
                    );

                    mData = new ContinuityDeviceConnected(pis);
                    pis.end(deviceConnectedToken);
                    break;
            }
        }
    }

    /**
     * Returns the value of the data field.
     */
    public TaskContinuityMessageData getData() {
        return mData;
    }

    /**
     * Serializes this message to bytes.
     */
    public byte[] toBytes() {
        ProtoOutputStream pos = new ProtoOutputStream();
        switch (mData) {
            case ContinuityDeviceConnected continuityDeviceConnected:
                long token = pos.start(
                    android.companion.TaskContinuityMessage.DEVICE_CONNECTED
                );

                continuityDeviceConnected.writeToProto(pos);
                pos.end(token);
                break;
            default:
                break;
        }

        return pos.getBytes();
    }

    /**
     * Builder for {@link TaskContinuityMessage}.
     */
    public static final class Builder {
        private TaskContinuityMessageData mData;

        public Builder() {
        }

        /**
         * Sets the value of the data field.
         */
        public Builder setData(TaskContinuityMessageData data) {
            mData = data;
            return this;
        }

        /**
         * Builds a {@link TaskContinuityMessage}.
         */
        public TaskContinuityMessage build() {
            return new TaskContinuityMessage(this);
        }
    }
}
 No newline at end of file
Loading