summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java4
-rw-r--r--services/companion/java/com/android/server/companion/securechannel/AttestationVerifier.java2
-rw-r--r--services/companion/java/com/android/server/companion/securechannel/SecureChannel.java7
-rw-r--r--services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java117
-rw-r--r--services/companion/java/com/android/server/companion/transport/CryptoManager.java103
-rw-r--r--services/companion/java/com/android/server/companion/transport/RawTransport.java8
-rw-r--r--services/companion/java/com/android/server/companion/transport/SecureTransport.java15
-rw-r--r--services/companion/java/com/android/server/companion/transport/Transport.java74
8 files changed, 116 insertions, 214 deletions
diff --git a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
index 3fffdbecd0de..9f27f721ea83 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
@@ -23,7 +23,6 @@ import static android.companion.CompanionDeviceManager.COMPANION_DEVICE_DISCOVER
import static android.content.ComponentName.createRelative;
import static com.android.server.companion.Utils.prepareForIpc;
-import static com.android.server.companion.transport.Transport.MESSAGE_REQUEST_PERMISSION_RESTORE;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -92,8 +91,7 @@ public class SystemDataTransferProcessor {
mAssociationStore = associationStore;
mSystemDataTransferRequestStore = systemDataTransferRequestStore;
mTransportManager = transportManager;
- mTransportManager.addListener(MESSAGE_REQUEST_PERMISSION_RESTORE,
- this::onReceivePermissionRestore);
+ mTransportManager.setListener(this::onReceivePermissionRestore);
mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
mExecutor = Executors.newSingleThreadExecutor();
}
diff --git a/services/companion/java/com/android/server/companion/securechannel/AttestationVerifier.java b/services/companion/java/com/android/server/companion/securechannel/AttestationVerifier.java
index 1559a3f8fdf8..adaee757b96a 100644
--- a/services/companion/java/com/android/server/companion/securechannel/AttestationVerifier.java
+++ b/services/companion/java/com/android/server/companion/securechannel/AttestationVerifier.java
@@ -35,7 +35,7 @@ import java.util.function.BiConsumer;
/**
* Helper class to perform attestation verification synchronously.
*/
-public class AttestationVerifier {
+class AttestationVerifier {
private static final long ATTESTATION_VERIFICATION_TIMEOUT_SECONDS = 10; // 10 seconds
private static final String PARAM_OWNED_BY_SYSTEM = "android.key_owned_by_system";
diff --git a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
index 05b6022ce569..13dba84487e3 100644
--- a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
+++ b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
@@ -110,7 +110,7 @@ public class SecureChannel {
this(in, out, callback, null, new AttestationVerifier(context));
}
- public SecureChannel(
+ private SecureChannel(
final InputStream in,
final OutputStream out,
Callback callback,
@@ -381,10 +381,9 @@ public class SecureChannel {
private void exchangeAuthentication()
throws IOException, GeneralSecurityException, BadHandleException, CryptoException {
- if (mPreSharedKey != null) {
+ if (mVerifier == null) {
exchangePreSharedKey();
- }
- if (mVerifier != null) {
+ } else {
exchangeAttestation();
}
}
diff --git a/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java b/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java
index 2abdcb172965..6a53adfeea9d 100644
--- a/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java
+++ b/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java
@@ -19,9 +19,9 @@ 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.content.Context;
@@ -30,17 +30,12 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Binder;
import android.os.Build;
import android.os.ParcelFileDescriptor;
-import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.server.LocalServices;
-import com.android.server.companion.transport.Transport.Listener;
import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
@@ -49,8 +44,6 @@ public class CompanionTransportManager {
private static final String TAG = "CDM_CompanionTransportManager";
private static final boolean DEBUG = false;
- private static final int NON_ANDROID = -1;
-
private boolean mSecureTransportEnabled = true;
private static boolean isRequest(int message) {
@@ -61,29 +54,24 @@ public class CompanionTransportManager {
return (message & 0xFF000000) == 0x33000000;
}
+ public interface Listener {
+ void onRequestPermissionRestore(byte[] data);
+ }
+
private final Context mContext;
@GuardedBy("mTransports")
private final SparseArray<Transport> mTransports = new SparseArray<>();
- @NonNull
- private final Map<Integer, Listener> mListeners = new HashMap<>();
-
- private Transport mTempTransport;
+ @Nullable
+ private Listener mListener;
public CompanionTransportManager(Context context) {
mContext = context;
}
- /**
- * Add a message listener when a message is received for the message type
- */
- @GuardedBy("mTransports")
- public void addListener(int message, @NonNull Listener listener) {
- mListeners.put(message, listener);
- for (int i = 0; i < mTransports.size(); i++) {
- mTransports.valueAt(i).addListener(message, listener);
- }
+ public void setListener(@NonNull Listener listener) {
+ mListener = listener;
}
/**
@@ -117,7 +105,15 @@ public class CompanionTransportManager {
detachSystemDataTransport(packageName, userId, associationId);
}
- initializeTransport(associationId, fd);
+ final Transport transport;
+ if (isSecureTransportEnabled(associationId)) {
+ transport = new SecureTransport(associationId, fd, mContext, mListener);
+ } else {
+ transport = new RawTransport(associationId, fd, mContext, mListener);
+ }
+
+ transport.start();
+ mTransports.put(associationId, transport);
}
}
@@ -132,85 +128,13 @@ public class CompanionTransportManager {
}
}
- @GuardedBy("mTransports")
- private void initializeTransport(int associationId, ParcelFileDescriptor fd) {
- if (!isSecureTransportEnabled()) {
- Transport transport = new RawTransport(associationId, fd, mContext);
- for (Map.Entry<Integer, Listener> entry : mListeners.entrySet()) {
- transport.addListener(entry.getKey(), entry.getValue());
- }
- transport.start();
- 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);
- for (Map.Entry<Integer, Listener> entry : mListeners.entrySet()) {
- mTempTransport.addListener(entry.getKey(), entry.getValue());
- }
- mTempTransport.addListener(MESSAGE_REQUEST_PLATFORM_INFO, this::onPlatformInfoReceived);
- 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
- mTempTransport.requestForResponse(MESSAGE_REQUEST_PLATFORM_INFO, data.array());
- }
-
- /**
- * Depending on the remote platform info to decide which transport should be created
- */
- @GuardedBy("mTransports")
- private void onPlatformInfoReceived(byte[] data) {
- // 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 = null;
-
- int sdk = Build.VERSION.SDK_INT;
- String release = Build.VERSION.RELEASE;
- if (remoteSdk == NON_ANDROID) {
- // TODO: pass in a real preSharedKey
- transport = new SecureTransport(transport.getAssociationId(), transport.getFd(),
- mContext, null, null);
- } else if (sdk < Build.VERSION_CODES.UPSIDE_DOWN_CAKE
- || remoteSdk < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
- // 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
- } else {
- Slog.i(TAG, "Creating a secure channel");
- transport = new SecureTransport(transport.getAssociationId(), transport.getFd(),
- mContext);
- for (Map.Entry<Integer, Listener> entry : mListeners.entrySet()) {
- transport.addListener(entry.getKey(), entry.getValue());
- }
- transport.start();
- }
- mTransports.put(transport.getAssociationId(), transport);
- }
-
public Future<?> requestPermissionRestore(int associationId, byte[] data) {
synchronized (mTransports) {
final Transport transport = mTransports.get(associationId);
if (transport == null) {
return CompletableFuture.failedFuture(new IOException("Missing transport"));
}
+
return transport.requestForResponse(MESSAGE_REQUEST_PERMISSION_RESTORE, data);
}
}
@@ -222,9 +146,10 @@ public class CompanionTransportManager {
this.mSecureTransportEnabled = enabled;
}
- private boolean isSecureTransportEnabled() {
+ private boolean isSecureTransportEnabled(int associationId) {
boolean enabled = !Build.IS_DEBUGGABLE || mSecureTransportEnabled;
+ // TODO: version comparison logic
return enabled;
}
}
diff --git a/services/companion/java/com/android/server/companion/transport/CryptoManager.java b/services/companion/java/com/android/server/companion/transport/CryptoManager.java
index a15939e52936..b08354afc8ad 100644
--- a/services/companion/java/com/android/server/companion/transport/CryptoManager.java
+++ b/services/companion/java/com/android/server/companion/transport/CryptoManager.java
@@ -16,51 +16,51 @@
package com.android.server.companion.transport;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
import android.util.Slog;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
+import java.security.UnrecoverableEntryException;
+import java.security.cert.CertificateException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
/**
- * This class uses Java Cryptography to encrypt and decrypt messages
+ * This class can be used to encrypt and decrypt bytes using Android Cryptography
*/
public class CryptoManager {
private static final String TAG = "CDM_CryptoManager";
- private static final int SECRET_KEY_LENGTH = 32;
- private static final String ALGORITHM = "AES";
- private static final String TRANSFORMATION = "AES/CBC/PKCS7Padding";
- private final byte[] mPreSharedKey;
- private Cipher mEncryptCipher;
- private Cipher mDecryptCipher;
+ private static final String KEY_STORE_ALIAS = "cdm_secret";
+ private static final String ALGORITHM = KeyProperties.KEY_ALGORITHM_AES;
+ private static final String BLOCK_MODE = KeyProperties.BLOCK_MODE_CBC;
+ private static final String PADDING = KeyProperties.ENCRYPTION_PADDING_PKCS7;
+ private static final String TRANSFORMATION = ALGORITHM + "/" + BLOCK_MODE + "/" + PADDING;
- private SecretKey mSecretKey;
+ private final KeyStore mKeyStore;
- public CryptoManager(byte[] preSharedKey) {
- if (preSharedKey == null) {
- mPreSharedKey = Arrays.copyOf(new byte[0], SECRET_KEY_LENGTH);
- } else {
- mPreSharedKey = Arrays.copyOf(preSharedKey, SECRET_KEY_LENGTH);
- }
- mSecretKey = new SecretKeySpec(mPreSharedKey, ALGORITHM);
+ public CryptoManager() {
+ // Initialize KeyStore
try {
- mEncryptCipher = Cipher.getInstance(TRANSFORMATION);
- mEncryptCipher.init(Cipher.ENCRYPT_MODE, mSecretKey);
- mDecryptCipher = Cipher.getInstance(TRANSFORMATION);
- } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
- Slog.e(TAG, e.getMessage());
+ mKeyStore = KeyStore.getInstance("AndroidKeyStore");
+ mKeyStore.load(null);
+ } catch (KeyStoreException | IOException | NoSuchAlgorithmException
+ | CertificateException e) {
+ throw new RuntimeException(e);
}
}
@@ -69,19 +69,21 @@ public class CryptoManager {
*/
public byte[] encrypt(byte[] input) {
try {
- if (mEncryptCipher == null) {
- return null;
- }
+ // Encrypt using Cipher
+ Cipher encryptCipher = Cipher.getInstance(TRANSFORMATION);
+ encryptCipher.init(Cipher.ENCRYPT_MODE, getKey());
+ byte[] encryptedBytes = encryptCipher.doFinal(input);
- byte[] encryptedBytes = mEncryptCipher.doFinal(input);
+ // Write to bytes
ByteBuffer buffer = ByteBuffer.allocate(
- 4 + mEncryptCipher.getIV().length + 4 + encryptedBytes.length)
- .putInt(mEncryptCipher.getIV().length)
- .put(mEncryptCipher.getIV())
+ 4 + encryptCipher.getIV().length + 4 + encryptedBytes.length)
+ .putInt(encryptCipher.getIV().length)
+ .put(encryptCipher.getIV())
.putInt(encryptedBytes.length)
.put(encryptedBytes);
return buffer.array();
- } catch (IllegalBlockSizeException | BadPaddingException e) {
+ } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
+ | IllegalBlockSizeException | BadPaddingException e) {
Slog.e(TAG, e.getMessage());
return null;
}
@@ -97,20 +99,45 @@ public class CryptoManager {
byte[] encryptedBytes = new byte[buffer.getInt()];
buffer.get(encryptedBytes);
try {
- mDecryptCipher.init(Cipher.DECRYPT_MODE, getKey(), new IvParameterSpec(iv));
- return mDecryptCipher.doFinal(encryptedBytes);
- } catch (InvalidKeyException | InvalidAlgorithmParameterException
- | IllegalBlockSizeException | BadPaddingException e) {
+ Cipher decryptCipher = Cipher.getInstance(TRANSFORMATION);
+ decryptCipher.init(Cipher.DECRYPT_MODE, getKey(), new IvParameterSpec(iv));
+ return decryptCipher.doFinal(encryptedBytes);
+ } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
+ | InvalidAlgorithmParameterException | IllegalBlockSizeException
+ | BadPaddingException e) {
Slog.e(TAG, e.getMessage());
return null;
}
}
private SecretKey getKey() {
- if (mSecretKey != null) {
- return mSecretKey;
+ try {
+ KeyStore.Entry keyEntry = mKeyStore.getEntry(KEY_STORE_ALIAS, null);
+ if (keyEntry instanceof KeyStore.SecretKeyEntry
+ && ((KeyStore.SecretKeyEntry) keyEntry).getSecretKey() != null) {
+ return ((KeyStore.SecretKeyEntry) keyEntry).getSecretKey();
+ } else {
+ return createKey();
+ }
+ } catch (NoSuchAlgorithmException | UnrecoverableEntryException | KeyStoreException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private SecretKey createKey() {
+ try {
+ KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
+ keyGenerator.init(
+ new KeyGenParameterSpec.Builder(KEY_STORE_ALIAS,
+ KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
+ .setBlockModes(BLOCK_MODE)
+ .setEncryptionPaddings(PADDING)
+ .setUserAuthenticationRequired(false)
+ .setRandomizedEncryptionRequired(true)
+ .build());
+ return keyGenerator.generateKey();
+ } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException e) {
+ throw new RuntimeException(e);
}
- mSecretKey = new SecretKeySpec(mPreSharedKey, ALGORITHM);
- return mSecretKey;
}
}
diff --git a/services/companion/java/com/android/server/companion/transport/RawTransport.java b/services/companion/java/com/android/server/companion/transport/RawTransport.java
index 4060f6efe0ca..7c0c7cf7ac68 100644
--- a/services/companion/java/com/android/server/companion/transport/RawTransport.java
+++ b/services/companion/java/com/android/server/companion/transport/RawTransport.java
@@ -21,6 +21,8 @@ import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.util.Slog;
+import com.android.server.companion.transport.CompanionTransportManager.Listener;
+
import libcore.io.IoUtils;
import libcore.io.Streams;
@@ -30,8 +32,8 @@ import java.nio.ByteBuffer;
class RawTransport extends Transport {
private volatile boolean mStopped;
- RawTransport(int associationId, ParcelFileDescriptor fd, Context context) {
- super(associationId, fd, context);
+ RawTransport(int associationId, ParcelFileDescriptor fd, Context context, Listener listener) {
+ super(associationId, fd, context, listener);
}
@Override
@@ -62,7 +64,7 @@ class RawTransport extends Transport {
protected void sendMessage(int message, int sequence, @NonNull byte[] data)
throws IOException {
if (DEBUG) {
- Slog.e(TAG, "Sending message 0x" + Integer.toHexString(message)
+ Slog.d(TAG, "Sending message 0x" + Integer.toHexString(message)
+ " sequence " + sequence + " length " + data.length
+ " to association " + mAssociationId);
}
diff --git a/services/companion/java/com/android/server/companion/transport/SecureTransport.java b/services/companion/java/com/android/server/companion/transport/SecureTransport.java
index cca08435c0a5..4194130f7e84 100644
--- a/services/companion/java/com/android/server/companion/transport/SecureTransport.java
+++ b/services/companion/java/com/android/server/companion/transport/SecureTransport.java
@@ -21,8 +21,8 @@ import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.util.Slog;
-import com.android.server.companion.securechannel.AttestationVerifier;
import com.android.server.companion.securechannel.SecureChannel;
+import com.android.server.companion.transport.CompanionTransportManager.Listener;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -37,17 +37,14 @@ class SecureTransport extends Transport implements SecureChannel.Callback {
private final BlockingQueue<byte[]> mRequestQueue = new ArrayBlockingQueue<>(100);
- SecureTransport(int associationId, ParcelFileDescriptor fd, Context context) {
- super(associationId, fd, context);
+ SecureTransport(int associationId,
+ ParcelFileDescriptor fd,
+ Context context,
+ Listener listener) {
+ super(associationId, fd, context, listener);
mSecureChannel = new SecureChannel(mRemoteIn, mRemoteOut, this, context);
}
- SecureTransport(int associationId, ParcelFileDescriptor fd, Context context,
- byte[] preSharedKey, AttestationVerifier verifier) {
- super(associationId, fd, context);
- mSecureChannel = new SecureChannel(mRemoteIn, mRemoteOut, this, preSharedKey, verifier);
- }
-
@Override
public void start() {
mSecureChannel.start();
diff --git a/services/companion/java/com/android/server/companion/transport/Transport.java b/services/companion/java/com/android/server/companion/transport/Transport.java
index e984c637b44c..923d4243a34c 100644
--- a/services/companion/java/com/android/server/companion/transport/Transport.java
+++ b/services/companion/java/com/android/server/companion/transport/Transport.java
@@ -25,28 +25,23 @@ import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.server.companion.transport.CompanionTransportManager.Listener;
import libcore.util.EmptyArray;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.util.HashMap;
-import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
-/**
- * This class represents the channel established between two devices.
- */
-public abstract class Transport {
+abstract class Transport {
protected static final String TAG = "CDM_CompanionTransport";
protected static final boolean DEBUG = Build.IS_DEBUGGABLE;
static final int MESSAGE_REQUEST_PING = 0x63807378; // ?PIN
- public static final int MESSAGE_REQUEST_PLATFORM_INFO = 0x63807086; // ?PFV
- public static final int MESSAGE_REQUEST_PERMISSION_RESTORE = 0x63826983; // ?RES
+ static final int MESSAGE_REQUEST_PERMISSION_RESTORE = 0x63826983; // ?RES
static final int MESSAGE_RESPONSE_SUCCESS = 0x33838567; // !SUC
static final int MESSAGE_RESPONSE_FAILURE = 0x33706573; // !FAI
@@ -54,24 +49,11 @@ public abstract class Transport {
protected static final int HEADER_LENGTH = 12;
protected final int mAssociationId;
- protected final ParcelFileDescriptor mFd;
protected final InputStream mRemoteIn;
protected final OutputStream mRemoteOut;
protected final Context mContext;
- /** Message type -> Listener */
- private final Map<Integer, Listener> mListeners;
-
- /**
- * Message listener
- */
- public interface Listener {
- /**
- * Called when a message is received
- * @param data data content in the message
- */
- void onDataReceived(byte[] data);
- }
+ private final Listener mListener;
private static boolean isRequest(int message) {
return (message & 0xFF000000) == 0x63000000;
@@ -86,36 +68,16 @@ public abstract class Transport {
new SparseArray<>();
protected final AtomicInteger mNextSequence = new AtomicInteger();
- Transport(int associationId, ParcelFileDescriptor fd, Context context) {
- mAssociationId = associationId;
- mFd = fd;
- mRemoteIn = new ParcelFileDescriptor.AutoCloseInputStream(fd);
- mRemoteOut = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
- mContext = context;
- mListeners = new HashMap<>();
- }
-
- /**
- * Add a listener when a message is received for the message type
- * @param message Message type
- * @param listener Execute when a message with the type is received
- */
- public void addListener(int message, Listener listener) {
- mListeners.put(message, listener);
- }
-
- public int getAssociationId() {
- return mAssociationId;
- }
-
- protected ParcelFileDescriptor getFd() {
- return mFd;
+ Transport(int associationId, ParcelFileDescriptor fd, Context context, Listener listener) {
+ this.mAssociationId = associationId;
+ this.mRemoteIn = new ParcelFileDescriptor.AutoCloseInputStream(fd);
+ this.mRemoteOut = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
+ this.mContext = context;
+ this.mListener = listener;
}
public abstract void start();
public abstract void stop();
- protected abstract void sendMessage(int message, int sequence, @NonNull byte[] data)
- throws IOException;
public Future<byte[]> requestForResponse(int message, byte[] data) {
if (DEBUG) Slog.d(TAG, "Requesting for response");
@@ -137,6 +99,9 @@ public abstract class Transport {
return pending;
}
+ protected abstract void sendMessage(int message, int sequence, @NonNull byte[] data)
+ throws IOException;
+
protected final void handleMessage(int message, int sequence, @NonNull byte[] data)
throws IOException {
if (DEBUG) {
@@ -165,11 +130,6 @@ public abstract class Transport {
sendMessage(MESSAGE_RESPONSE_SUCCESS, sequence, data);
break;
}
- case MESSAGE_REQUEST_PLATFORM_INFO: {
- callback(message, data);
- sendMessage(MESSAGE_RESPONSE_SUCCESS, sequence, EmptyArray.BYTE);
- break;
- }
case MESSAGE_REQUEST_PERMISSION_RESTORE: {
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)
&& !Build.isDebuggable()) {
@@ -178,7 +138,7 @@ public abstract class Transport {
break;
}
try {
- callback(message, data);
+ mListener.onRequestPermissionRestore(data);
sendMessage(MESSAGE_RESPONSE_SUCCESS, sequence, EmptyArray.BYTE);
} catch (Exception e) {
Slog.w(TAG, "Failed to restore permissions");
@@ -194,12 +154,6 @@ public abstract class Transport {
}
}
- private void callback(int message, byte[] data) {
- if (mListeners.containsKey(message)) {
- mListeners.get(message).onDataReceived(data);
- }
- }
-
private void processResponse(int message, int sequence, byte[] data) {
final CompletableFuture<byte[]> future;
synchronized (mPendingRequests) {