Loading services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java +16 −105 Original line number Diff line number Diff line Loading @@ -19,10 +19,8 @@ package com.android.server.companion.transport; import static android.Manifest.permission.DELIVER_COMPANION_MESSAGES; import static com.android.server.companion.transport.Transport.MESSAGE_REQUEST_PERMISSION_RESTORE; import static com.android.server.companion.transport.Transport.MESSAGE_REQUEST_PLATFORM_INFO; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.app.ActivityManagerInternal; import android.companion.AssociationInfo; Loading @@ -33,7 +31,6 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Binder; import android.os.Build; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteCallbackList; import android.os.RemoteException; Loading @@ -46,7 +43,6 @@ import com.android.server.companion.AssociationStore; import java.io.FileDescriptor; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; Loading @@ -58,19 +54,8 @@ public class CompanionTransportManager { private static final String TAG = "CDM_CompanionTransportManager"; private static final boolean DEBUG = false; private static final int SECURE_CHANNEL_AVAILABLE_SDK = Build.VERSION_CODES.UPSIDE_DOWN_CAKE; private static final int NON_ANDROID = -1; private boolean mSecureTransportEnabled = true; private static boolean isRequest(int message) { return (message & 0xFF000000) == 0x63000000; } private static boolean isResponse(int message) { return (message & 0xFF000000) == 0x33000000; } private final Context mContext; private final AssociationStore mAssociationStore; Loading @@ -84,10 +69,6 @@ public class CompanionTransportManager { @NonNull private final SparseArray<IOnMessageReceivedListener> mMessageListeners = new SparseArray<>(); @Nullable private Transport mTempTransport; public CompanionTransportManager(Context context, AssociationStore associationStore) { mContext = context; mAssociationStore = associationStore; Loading Loading @@ -199,7 +180,8 @@ public class CompanionTransportManager { detachSystemDataTransport(packageName, userId, associationId); } initializeTransport(associationId, fd); // TODO: Implement new API to pass a PSK initializeTransport(associationId, fd, null); notifyOnTransportsChanged(); } Loading Loading @@ -237,107 +219,36 @@ public class CompanionTransportManager { }); } private void initializeTransport(int associationId, ParcelFileDescriptor fd) { private void initializeTransport(int associationId, ParcelFileDescriptor fd, byte[] preSharedKey) { Slog.i(TAG, "Initializing transport"); Transport transport; if (!isSecureTransportEnabled()) { Transport transport = new RawTransport(associationId, fd, mContext); addMessageListenersToTransport(transport); transport.start(); synchronized (mTransports) { mTransports.put(associationId, transport); } Slog.i(TAG, "RawTransport is created"); return; } // Exchange platform info to decide which transport should be created mTempTransport = new RawTransport(associationId, fd, mContext); addMessageListenersToTransport(mTempTransport); IOnMessageReceivedListener listener = new IOnMessageReceivedListener() { @Override public void onMessageReceived(int associationId, byte[] data) throws RemoteException { synchronized (mTransports) { onPlatformInfoReceived(associationId, data); } } @Override public IBinder asBinder() { return null; } }; mTempTransport.addListener(MESSAGE_REQUEST_PLATFORM_INFO, listener); mTempTransport.start(); int sdk = Build.VERSION.SDK_INT; String release = Build.VERSION.RELEASE; // data format: | SDK_INT (int) | release length (int) | release | final ByteBuffer data = ByteBuffer.allocate(4 + 4 + release.getBytes().length) .putInt(sdk) .putInt(release.getBytes().length) .put(release.getBytes()); // TODO: it should check if preSharedKey is given try { mTempTransport.sendMessage(MESSAGE_REQUEST_PLATFORM_INFO, data.array()); } catch (IOException e) { Slog.e(TAG, "Failed to exchange platform info"); } } /** * Depending on the remote platform info to decide which transport should be created */ private void onPlatformInfoReceived(int associationId, byte[] data) { if (mTempTransport.getAssociationId() != associationId) { return; } // TODO: it should check if preSharedKey is given ByteBuffer buffer = ByteBuffer.wrap(data); int remoteSdk = buffer.getInt(); byte[] remoteRelease = new byte[buffer.getInt()]; buffer.get(remoteRelease); Slog.i(TAG, "Remote device SDK: " + remoteSdk + ", release:" + new String(remoteRelease)); Transport transport = mTempTransport; mTempTransport.stop(); int sdk = Build.VERSION.SDK_INT; String release = Build.VERSION.RELEASE; if (sdk < SECURE_CHANNEL_AVAILABLE_SDK || remoteSdk < SECURE_CHANNEL_AVAILABLE_SDK) { // If either device is Android T or below, use raw channel // TODO: depending on the release version, either // 1) using a RawTransport for old T versions // 2) or an Ukey2 handshaked transport for UKey2 backported T versions Slog.d(TAG, "Secure channel is not supported. Using raw transport"); transport = new RawTransport(transport.getAssociationId(), transport.getFd(), mContext); // If secure transport is explicitly disabled for testing, use raw transport Slog.i(TAG, "Secure channel is disabled. Creating raw transport"); transport = new RawTransport(associationId, fd, mContext); } else if (Build.isDebuggable()) { // If device is debug build, use hardcoded test key for authentication Slog.d(TAG, "Creating an unauthenticated secure channel"); final byte[] testKey = "CDM".getBytes(StandardCharsets.UTF_8); transport = new SecureTransport(transport.getAssociationId(), transport.getFd(), mContext, testKey, null); } else if (sdk == NON_ANDROID || remoteSdk == NON_ANDROID) { transport = new SecureTransport(associationId, fd, mContext, testKey, null); } else if (preSharedKey != null) { // If either device is not Android, then use app-specific pre-shared key // TODO: pass in a real preSharedKey Slog.d(TAG, "Creating a PSK-authenticated secure channel"); transport = new SecureTransport(transport.getAssociationId(), transport.getFd(), mContext, new byte[0], null); transport = new SecureTransport(associationId, fd, mContext, preSharedKey, null); } else { // If none of the above applies, then use secure channel with attestation verification Slog.d(TAG, "Creating a secure channel"); transport = new SecureTransport(transport.getAssociationId(), transport.getFd(), mContext); transport = new SecureTransport(associationId, fd, mContext); } addMessageListenersToTransport(transport); transport.start(); synchronized (mTransports) { mTransports.put(transport.getAssociationId(), transport); mTransports.put(associationId, transport); } // Doesn't need to notifyTransportsChanged here, it'll be done in attachSystemDataTransport } public Future<?> requestPermissionRestore(int associationId, byte[] data) { Loading services/companion/java/com/android/server/companion/transport/RawTransport.java +3 −3 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ class RawTransport extends Transport { } @Override public void start() { void start() { if (DEBUG) { Slog.d(TAG, "Starting raw transport."); } Loading @@ -54,7 +54,7 @@ class RawTransport extends Transport { } @Override public void stop() { void stop() { if (DEBUG) { Slog.d(TAG, "Stopping raw transport."); } Loading @@ -62,7 +62,7 @@ class RawTransport extends Transport { } @Override public void close() { void close() { stop(); if (DEBUG) { Loading services/companion/java/com/android/server/companion/transport/SecureTransport.java +3 −3 Original line number Diff line number Diff line Loading @@ -51,18 +51,18 @@ class SecureTransport extends Transport implements SecureChannel.Callback { } @Override public void start() { void start() { mSecureChannel.start(); } @Override public void stop() { void stop() { mSecureChannel.stop(); mShouldProcessRequests = false; } @Override public void close() { void close() { mSecureChannel.close(); mShouldProcessRequests = false; } Loading services/companion/java/com/android/server/companion/transport/Transport.java +3 −9 Original line number Diff line number Diff line Loading @@ -47,7 +47,6 @@ public abstract class Transport { protected static final boolean DEBUG = Build.IS_DEBUGGABLE; static final int MESSAGE_REQUEST_PING = 0x63807378; // ?PIN public static final int MESSAGE_REQUEST_PLATFORM_INFO = 0x63807073; // ?PFI public static final int MESSAGE_REQUEST_CONTEXT_SYNC = 0x63678883; // ?CXS public static final int MESSAGE_REQUEST_PERMISSION_RESTORE = 0x63826983; // ?RES Loading Loading @@ -113,17 +112,17 @@ public abstract class Transport { /** * Start listening to messages. */ public abstract void start(); abstract void start(); /** * Soft stop listening to the incoming data without closing the streams. */ public abstract void stop(); abstract void stop(); /** * Stop listening to the incoming data and close the streams. */ public abstract void close(); abstract void close(); protected abstract void sendMessage(int message, int sequence, @NonNull byte[] data) throws IOException; Loading Loading @@ -183,11 +182,6 @@ public abstract class Transport { sendMessage(MESSAGE_RESPONSE_SUCCESS, sequence, data); break; } case MESSAGE_REQUEST_PLATFORM_INFO: { callback(message, data); // DO NOT SEND A RESPONSE! break; } case MESSAGE_REQUEST_CONTEXT_SYNC: { callback(message, data); sendMessage(MESSAGE_RESPONSE_SUCCESS, sequence, EmptyArray.BYTE); Loading Loading
services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java +16 −105 Original line number Diff line number Diff line Loading @@ -19,10 +19,8 @@ package com.android.server.companion.transport; import static android.Manifest.permission.DELIVER_COMPANION_MESSAGES; import static com.android.server.companion.transport.Transport.MESSAGE_REQUEST_PERMISSION_RESTORE; import static com.android.server.companion.transport.Transport.MESSAGE_REQUEST_PLATFORM_INFO; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.app.ActivityManagerInternal; import android.companion.AssociationInfo; Loading @@ -33,7 +31,6 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Binder; import android.os.Build; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteCallbackList; import android.os.RemoteException; Loading @@ -46,7 +43,6 @@ import com.android.server.companion.AssociationStore; import java.io.FileDescriptor; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; Loading @@ -58,19 +54,8 @@ public class CompanionTransportManager { private static final String TAG = "CDM_CompanionTransportManager"; private static final boolean DEBUG = false; private static final int SECURE_CHANNEL_AVAILABLE_SDK = Build.VERSION_CODES.UPSIDE_DOWN_CAKE; private static final int NON_ANDROID = -1; private boolean mSecureTransportEnabled = true; private static boolean isRequest(int message) { return (message & 0xFF000000) == 0x63000000; } private static boolean isResponse(int message) { return (message & 0xFF000000) == 0x33000000; } private final Context mContext; private final AssociationStore mAssociationStore; Loading @@ -84,10 +69,6 @@ public class CompanionTransportManager { @NonNull private final SparseArray<IOnMessageReceivedListener> mMessageListeners = new SparseArray<>(); @Nullable private Transport mTempTransport; public CompanionTransportManager(Context context, AssociationStore associationStore) { mContext = context; mAssociationStore = associationStore; Loading Loading @@ -199,7 +180,8 @@ public class CompanionTransportManager { detachSystemDataTransport(packageName, userId, associationId); } initializeTransport(associationId, fd); // TODO: Implement new API to pass a PSK initializeTransport(associationId, fd, null); notifyOnTransportsChanged(); } Loading Loading @@ -237,107 +219,36 @@ public class CompanionTransportManager { }); } private void initializeTransport(int associationId, ParcelFileDescriptor fd) { private void initializeTransport(int associationId, ParcelFileDescriptor fd, byte[] preSharedKey) { Slog.i(TAG, "Initializing transport"); Transport transport; if (!isSecureTransportEnabled()) { Transport transport = new RawTransport(associationId, fd, mContext); addMessageListenersToTransport(transport); transport.start(); synchronized (mTransports) { mTransports.put(associationId, transport); } Slog.i(TAG, "RawTransport is created"); return; } // Exchange platform info to decide which transport should be created mTempTransport = new RawTransport(associationId, fd, mContext); addMessageListenersToTransport(mTempTransport); IOnMessageReceivedListener listener = new IOnMessageReceivedListener() { @Override public void onMessageReceived(int associationId, byte[] data) throws RemoteException { synchronized (mTransports) { onPlatformInfoReceived(associationId, data); } } @Override public IBinder asBinder() { return null; } }; mTempTransport.addListener(MESSAGE_REQUEST_PLATFORM_INFO, listener); mTempTransport.start(); int sdk = Build.VERSION.SDK_INT; String release = Build.VERSION.RELEASE; // data format: | SDK_INT (int) | release length (int) | release | final ByteBuffer data = ByteBuffer.allocate(4 + 4 + release.getBytes().length) .putInt(sdk) .putInt(release.getBytes().length) .put(release.getBytes()); // TODO: it should check if preSharedKey is given try { mTempTransport.sendMessage(MESSAGE_REQUEST_PLATFORM_INFO, data.array()); } catch (IOException e) { Slog.e(TAG, "Failed to exchange platform info"); } } /** * Depending on the remote platform info to decide which transport should be created */ private void onPlatformInfoReceived(int associationId, byte[] data) { if (mTempTransport.getAssociationId() != associationId) { return; } // TODO: it should check if preSharedKey is given ByteBuffer buffer = ByteBuffer.wrap(data); int remoteSdk = buffer.getInt(); byte[] remoteRelease = new byte[buffer.getInt()]; buffer.get(remoteRelease); Slog.i(TAG, "Remote device SDK: " + remoteSdk + ", release:" + new String(remoteRelease)); Transport transport = mTempTransport; mTempTransport.stop(); int sdk = Build.VERSION.SDK_INT; String release = Build.VERSION.RELEASE; if (sdk < SECURE_CHANNEL_AVAILABLE_SDK || remoteSdk < SECURE_CHANNEL_AVAILABLE_SDK) { // If either device is Android T or below, use raw channel // TODO: depending on the release version, either // 1) using a RawTransport for old T versions // 2) or an Ukey2 handshaked transport for UKey2 backported T versions Slog.d(TAG, "Secure channel is not supported. Using raw transport"); transport = new RawTransport(transport.getAssociationId(), transport.getFd(), mContext); // If secure transport is explicitly disabled for testing, use raw transport Slog.i(TAG, "Secure channel is disabled. Creating raw transport"); transport = new RawTransport(associationId, fd, mContext); } else if (Build.isDebuggable()) { // If device is debug build, use hardcoded test key for authentication Slog.d(TAG, "Creating an unauthenticated secure channel"); final byte[] testKey = "CDM".getBytes(StandardCharsets.UTF_8); transport = new SecureTransport(transport.getAssociationId(), transport.getFd(), mContext, testKey, null); } else if (sdk == NON_ANDROID || remoteSdk == NON_ANDROID) { transport = new SecureTransport(associationId, fd, mContext, testKey, null); } else if (preSharedKey != null) { // If either device is not Android, then use app-specific pre-shared key // TODO: pass in a real preSharedKey Slog.d(TAG, "Creating a PSK-authenticated secure channel"); transport = new SecureTransport(transport.getAssociationId(), transport.getFd(), mContext, new byte[0], null); transport = new SecureTransport(associationId, fd, mContext, preSharedKey, null); } else { // If none of the above applies, then use secure channel with attestation verification Slog.d(TAG, "Creating a secure channel"); transport = new SecureTransport(transport.getAssociationId(), transport.getFd(), mContext); transport = new SecureTransport(associationId, fd, mContext); } addMessageListenersToTransport(transport); transport.start(); synchronized (mTransports) { mTransports.put(transport.getAssociationId(), transport); mTransports.put(associationId, transport); } // Doesn't need to notifyTransportsChanged here, it'll be done in attachSystemDataTransport } public Future<?> requestPermissionRestore(int associationId, byte[] data) { Loading
services/companion/java/com/android/server/companion/transport/RawTransport.java +3 −3 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ class RawTransport extends Transport { } @Override public void start() { void start() { if (DEBUG) { Slog.d(TAG, "Starting raw transport."); } Loading @@ -54,7 +54,7 @@ class RawTransport extends Transport { } @Override public void stop() { void stop() { if (DEBUG) { Slog.d(TAG, "Stopping raw transport."); } Loading @@ -62,7 +62,7 @@ class RawTransport extends Transport { } @Override public void close() { void close() { stop(); if (DEBUG) { Loading
services/companion/java/com/android/server/companion/transport/SecureTransport.java +3 −3 Original line number Diff line number Diff line Loading @@ -51,18 +51,18 @@ class SecureTransport extends Transport implements SecureChannel.Callback { } @Override public void start() { void start() { mSecureChannel.start(); } @Override public void stop() { void stop() { mSecureChannel.stop(); mShouldProcessRequests = false; } @Override public void close() { void close() { mSecureChannel.close(); mShouldProcessRequests = false; } Loading
services/companion/java/com/android/server/companion/transport/Transport.java +3 −9 Original line number Diff line number Diff line Loading @@ -47,7 +47,6 @@ public abstract class Transport { protected static final boolean DEBUG = Build.IS_DEBUGGABLE; static final int MESSAGE_REQUEST_PING = 0x63807378; // ?PIN public static final int MESSAGE_REQUEST_PLATFORM_INFO = 0x63807073; // ?PFI public static final int MESSAGE_REQUEST_CONTEXT_SYNC = 0x63678883; // ?CXS public static final int MESSAGE_REQUEST_PERMISSION_RESTORE = 0x63826983; // ?RES Loading Loading @@ -113,17 +112,17 @@ public abstract class Transport { /** * Start listening to messages. */ public abstract void start(); abstract void start(); /** * Soft stop listening to the incoming data without closing the streams. */ public abstract void stop(); abstract void stop(); /** * Stop listening to the incoming data and close the streams. */ public abstract void close(); abstract void close(); protected abstract void sendMessage(int message, int sequence, @NonNull byte[] data) throws IOException; Loading Loading @@ -183,11 +182,6 @@ public abstract class Transport { sendMessage(MESSAGE_RESPONSE_SUCCESS, sequence, data); break; } case MESSAGE_REQUEST_PLATFORM_INFO: { callback(message, data); // DO NOT SEND A RESPONSE! break; } case MESSAGE_REQUEST_CONTEXT_SYNC: { callback(message, data); sendMessage(MESSAGE_RESPONSE_SUCCESS, sequence, EmptyArray.BYTE); Loading