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

Commit 6a649d88 authored by Janis Danisevskis's avatar Janis Danisevskis Committed by Android (Google) Code Review
Browse files

Merge "Preserve interrupted state across waiting for future"

parents ba52238c 022c8ef7
Loading
Loading
Loading
Loading
+43 −27
Original line number Diff line number Diff line
@@ -483,14 +483,14 @@ public class KeyStore {
            mBinder.asBinder().linkToDeath(promise, 0);
            int errorCode = mBinder.addRngEntropy(promise, data, flags);
            if (errorCode == NO_ERROR) {
                return promise.getFuture().get().getErrorCode() == NO_ERROR;
                return interruptedPreservingGet(promise.getFuture()).getErrorCode() == NO_ERROR;
            } else {
                return false;
            }
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            return false;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "AddRngEntropy completed with exception", e);
            return false;
        } finally {
@@ -548,7 +548,7 @@ public class KeyStore {

    private int generateKeyInternal(String alias, KeymasterArguments args, byte[] entropy, int uid,
            int flags, KeyCharacteristics outCharacteristics)
                    throws RemoteException, ExecutionException, InterruptedException {
                    throws RemoteException, ExecutionException {
        KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
        int error = NO_ERROR;
        KeyCharacteristicsCallbackResult result = null;
@@ -559,7 +559,7 @@ public class KeyStore {
                Log.e(TAG, "generateKeyInternal failed on request " + error);
                return error;
            }
            result = promise.getFuture().get();
            result = interruptedPreservingGet(promise.getFuture());
        } finally {
            mBinder.asBinder().unlinkToDeath(promise, 0);
        }
@@ -592,7 +592,7 @@ public class KeyStore {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            return SYSTEM_ERROR;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "generateKey completed with exception", e);
            return SYSTEM_ERROR;
        }
@@ -614,7 +614,7 @@ public class KeyStore {
            int error = mBinder.getKeyCharacteristics(promise, alias, clientId, appId, uid);
            if (error != NO_ERROR) return error;

            KeyCharacteristicsCallbackResult result = promise.getFuture().get();
            KeyCharacteristicsCallbackResult result = interruptedPreservingGet(promise.getFuture());
            error = result.getKeystoreResponse().getErrorCode();
            if (error != NO_ERROR) return error;

@@ -625,7 +625,7 @@ public class KeyStore {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            return SYSTEM_ERROR;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "GetKeyCharacteristics completed with exception", e);
            return SYSTEM_ERROR;
        } finally {
@@ -640,14 +640,14 @@ public class KeyStore {

    private int importKeyInternal(String alias, KeymasterArguments args, int format, byte[] keyData,
            int uid, int flags, KeyCharacteristics outCharacteristics)
                    throws RemoteException, ExecutionException, InterruptedException {
                    throws RemoteException, ExecutionException {
        KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
        mBinder.asBinder().linkToDeath(promise, 0);
        try {
            int error = mBinder.importKey(promise, alias, args, format, keyData, uid, flags);
            if (error != NO_ERROR) return error;

            KeyCharacteristicsCallbackResult result = promise.getFuture().get();
            KeyCharacteristicsCallbackResult result = interruptedPreservingGet(promise.getFuture());

            error = result.getKeystoreResponse().getErrorCode();
            if (error != NO_ERROR) return error;
@@ -675,7 +675,7 @@ public class KeyStore {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            return SYSTEM_ERROR;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "ImportKey completed with exception", e);
            return SYSTEM_ERROR;
        }
@@ -747,7 +747,7 @@ public class KeyStore {
            String wrappingKeyAlias,
            byte[] maskingKey, KeymasterArguments args, long rootSid, long fingerprintSid,
            KeyCharacteristics outCharacteristics)
                    throws RemoteException, ExecutionException, InterruptedException {
                    throws RemoteException, ExecutionException {
        KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
        mBinder.asBinder().linkToDeath(promise, 0);
        try {
@@ -755,7 +755,7 @@ public class KeyStore {
                    wrappingKeyAlias, maskingKey, args, rootSid, fingerprintSid);
            if (error != NO_ERROR) return error;

            KeyCharacteristicsCallbackResult result = promise.getFuture().get();
            KeyCharacteristicsCallbackResult result = interruptedPreservingGet(promise.getFuture());

            error = result.getKeystoreResponse().getErrorCode();
            if (error != NO_ERROR) return error;
@@ -786,7 +786,7 @@ public class KeyStore {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            return SYSTEM_ERROR;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "ImportWrappedKey completed with exception", e);
            return SYSTEM_ERROR;
        }
@@ -818,14 +818,14 @@ public class KeyStore {
            appId = appId != null ? appId : new KeymasterBlob(new byte[0]);
            int error = mBinder.exportKey(promise, alias, format, clientId, appId, uid);
            if (error == NO_ERROR) {
                return promise.getFuture().get();
                return interruptedPreservingGet(promise.getFuture());
            } else {
                return new ExportResult(error);
            }
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            return null;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "ExportKey completed with exception", e);
            return null;
        } finally {
@@ -864,14 +864,14 @@ public class KeyStore {
            int errorCode =  mBinder.begin(promise, getToken(), alias, purpose, pruneable, args,
                                           entropy, uid);
            if (errorCode == NO_ERROR) {
                return promise.getFuture().get();
                return interruptedPreservingGet(promise.getFuture());
            } else {
                return new OperationResult(errorCode);
            }
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            return null;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "Begin completed with exception", e);
            return null;
        } finally {
@@ -894,14 +894,14 @@ public class KeyStore {
            input = input != null ? input : new byte[0];
            int errorCode =  mBinder.update(promise, token, arguments, input);
            if (errorCode == NO_ERROR) {
                return promise.getFuture().get();
                return interruptedPreservingGet(promise.getFuture());
            } else {
                return new OperationResult(errorCode);
            }
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            return null;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "Update completed with exception", e);
            return null;
        } finally {
@@ -930,14 +930,14 @@ public class KeyStore {
            signature = signature != null ? signature : new byte[0];
            int errorCode = mBinder.finish(promise, token, arguments, input, signature, entropy);
            if (errorCode == NO_ERROR) {
                return promise.getFuture().get();
                return interruptedPreservingGet(promise.getFuture());
            } else {
                return new OperationResult(errorCode);
            }
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            return null;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "Finish completed with exception", e);
            return null;
        } finally {
@@ -972,14 +972,14 @@ public class KeyStore {
            mBinder.asBinder().linkToDeath(promise, 0);
            int errorCode = mBinder.abort(promise, token);
            if (errorCode == NO_ERROR) {
                return promise.getFuture().get().getErrorCode();
                return interruptedPreservingGet(promise.getFuture()).getErrorCode();
            } else {
                return errorCode;
            }
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            return SYSTEM_ERROR;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "Abort completed with exception", e);
            return SYSTEM_ERROR;
        } finally {
@@ -1135,7 +1135,7 @@ public class KeyStore {
            }
            int error = mBinder.attestKey(promise, alias, params);
            if (error != NO_ERROR) return error;
            KeyAttestationCallbackResult result = promise.getFuture().get();
            KeyAttestationCallbackResult result = interruptedPreservingGet(promise.getFuture());
            error = result.getKeystoreResponse().getErrorCode();
            if (error == NO_ERROR) {
                outChain.shallowCopyFrom(result.getCertificateChain());
@@ -1144,7 +1144,7 @@ public class KeyStore {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            return SYSTEM_ERROR;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "AttestKey completed with exception", e);
            return SYSTEM_ERROR;
        } finally {
@@ -1164,7 +1164,7 @@ public class KeyStore {
            }
            int error = mBinder.attestDeviceIds(promise, params);
            if (error != NO_ERROR) return error;
            KeyAttestationCallbackResult result = promise.getFuture().get();
            KeyAttestationCallbackResult result = interruptedPreservingGet(promise.getFuture());
            error = result.getKeystoreResponse().getErrorCode();
            if (error == NO_ERROR) {
                outChain.shallowCopyFrom(result.getCertificateChain());
@@ -1173,7 +1173,7 @@ public class KeyStore {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            return SYSTEM_ERROR;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "AttestDevicdeIds completed with exception", e);
            return SYSTEM_ERROR;
        } finally {
@@ -1387,4 +1387,20 @@ public class KeyStore {
            int errorCode) {
        return getInvalidKeyException(keystoreKeyAlias, uid, getKeyStoreException(errorCode));
    }

    private static <R> R interruptedPreservingGet(CompletableFuture<R> future)
            throws ExecutionException {
        boolean wasInterrupted = false;
        while (true) {
            try {
                R result = future.get();
                if (wasInterrupted) {
                    Thread.currentThread().interrupt();
                }
                return result;
            } catch (InterruptedException e) {
                wasInterrupted = true;
            }
        }
    }
}