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

Commit faa8d920 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Preserve interrupted state across waiting for future" am: 3a91c751 am: f6574a21

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1340128

Change-Id: Ica523ae5269ba5e2a339653024870fefa581ad64
parents 0b235515 f6574a21
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;
            }
        }
    }
}