diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2020-02-05 04:23:31 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2020-02-05 04:23:31 +0000 |
commit | ef85f3196bf71d43b28786ebd317b724fa8bc9e1 (patch) | |
tree | f5e7bad67e0fc27e4dfd3986148ec9782728063f | |
parent | 5a957a4d6f8b1c464ea6cab30792df4e0ff91a58 (diff) | |
parent | 5050934c425fa1c775d31a1c2ab7bbe6f8fe5bc6 (diff) | |
download | ex-android11-security-release.tar.gz |
Snap for 6182732 from 5050934c425fa1c775d31a1c2ab7bbe6f8fe5bc6 to rvc-releaseandroid-vts-11.0_r9android-vts-11.0_r8android-vts-11.0_r7android-vts-11.0_r6android-vts-11.0_r5android-vts-11.0_r4android-vts-11.0_r3android-vts-11.0_r2android-vts-11.0_r16android-vts-11.0_r15android-vts-11.0_r14android-vts-11.0_r13android-vts-11.0_r12android-vts-11.0_r11android-vts-11.0_r10android-vts-11.0_r1android-security-11.0.0_r76android-security-11.0.0_r75android-security-11.0.0_r74android-security-11.0.0_r73android-security-11.0.0_r72android-security-11.0.0_r71android-security-11.0.0_r70android-security-11.0.0_r69android-security-11.0.0_r68android-security-11.0.0_r67android-security-11.0.0_r66android-security-11.0.0_r65android-security-11.0.0_r64android-security-11.0.0_r63android-security-11.0.0_r62android-security-11.0.0_r61android-security-11.0.0_r60android-security-11.0.0_r59android-security-11.0.0_r58android-security-11.0.0_r57android-security-11.0.0_r56android-security-11.0.0_r55android-security-11.0.0_r54android-security-11.0.0_r53android-security-11.0.0_r52android-security-11.0.0_r51android-security-11.0.0_r50android-security-11.0.0_r49android-security-11.0.0_r1android-platform-11.0.0_r9android-platform-11.0.0_r8android-platform-11.0.0_r7android-platform-11.0.0_r6android-platform-11.0.0_r5android-platform-11.0.0_r40android-platform-11.0.0_r4android-platform-11.0.0_r39android-platform-11.0.0_r38android-platform-11.0.0_r37android-platform-11.0.0_r36android-platform-11.0.0_r35android-platform-11.0.0_r34android-platform-11.0.0_r33android-platform-11.0.0_r32android-platform-11.0.0_r31android-platform-11.0.0_r30android-platform-11.0.0_r3android-platform-11.0.0_r29android-platform-11.0.0_r28android-platform-11.0.0_r27android-platform-11.0.0_r26android-platform-11.0.0_r25android-platform-11.0.0_r24android-platform-11.0.0_r23android-platform-11.0.0_r22android-platform-11.0.0_r21android-platform-11.0.0_r20android-platform-11.0.0_r2android-platform-11.0.0_r19android-platform-11.0.0_r18android-platform-11.0.0_r17android-platform-11.0.0_r16android-platform-11.0.0_r15android-platform-11.0.0_r14android-platform-11.0.0_r13android-platform-11.0.0_r12android-platform-11.0.0_r11android-platform-11.0.0_r10android-platform-11.0.0_r1android-cts-11.0_r9android-cts-11.0_r8android-cts-11.0_r7android-cts-11.0_r6android-cts-11.0_r5android-cts-11.0_r4android-cts-11.0_r3android-cts-11.0_r2android-cts-11.0_r16android-cts-11.0_r15android-cts-11.0_r14android-cts-11.0_r13android-cts-11.0_r12android-cts-11.0_r11android-cts-11.0_r10android-cts-11.0_r1android-11.0.0_r6android-11.0.0_r5android-11.0.0_r4android-11.0.0_r3android-11.0.0_r25android-11.0.0_r2android-11.0.0_r17android-11.0.0_r1android11-tests-releaseandroid11-security-releaseandroid11-s1-releaseandroid11-releaseandroid11-platform-releaseandroid11-gsi
Change-Id: I0c92572448685890413a3ce998c0ce61c99e912a
-rw-r--r-- | camera2/public/src/com/android/ex/camera2/blocking/BlockingOfflineSessionCallback.java | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/camera2/public/src/com/android/ex/camera2/blocking/BlockingOfflineSessionCallback.java b/camera2/public/src/com/android/ex/camera2/blocking/BlockingOfflineSessionCallback.java new file mode 100644 index 00000000..021dcd7d --- /dev/null +++ b/camera2/public/src/com/android/ex/camera2/blocking/BlockingOfflineSessionCallback.java @@ -0,0 +1,254 @@ +/* + * Copyright 2020 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.ex.camera2.blocking; + +import android.hardware.camera2.CameraDevice; +import android.hardware.camera2.CameraOfflineSession; +import android.hardware.camera2.CameraOfflineSession.CameraOfflineSessionCallback; +import android.os.Handler; +import android.os.SystemClock; +import android.util.Log; + +import com.android.ex.camera2.exceptions.TimeoutRuntimeException; + +import java.util.Arrays; +import java.util.Collection; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * A camera offline session listener that implements blocking operations on state changes. + * + * <p>Provides wait calls that block until the next unobserved state of the + * requested type arrives. Unobserved states are states that have occurred since + * the last wait, or that will be received from the camera device in the + * future.</p> + * + * <p>Pass-through all offline callbacks to the proxy.</p> + * + */ +public class BlockingOfflineSessionCallback + extends CameraOfflineSession.CameraOfflineSessionCallback { + private static final String TAG = "BlockingOfflineSessionCallback"; + private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); + + private final CameraOfflineSession.CameraOfflineSessionCallback mProxy; + + // Guards mWaiting + private final Object mLock = new Object(); + private boolean mWaiting = false; + + private final LinkedBlockingQueue<Integer> mRecentStates = + new LinkedBlockingQueue<Integer>(); + + private void setCurrentState(int state) { + if (VERBOSE) Log.v(TAG, "Offline session state now " + stateToString(state)); + try { + mRecentStates.put(state); + } catch (InterruptedException e) { + throw new RuntimeException("Unable to set offline session state", e); + } + } + + private static final String[] mStateNames = { + "STATE_UNINITIALIZED", + "STATE_READY", + "STATE_IDLE", + "STATE_CLOSED", + "STATE_ERROR", + "STATE_SWITCH_FAILED", + }; + + /** + * Offline session has not reported any state yet + */ + public static final int STATE_UNINITIALIZED = -1; + + /** + * The offline session moves to ready state in case of successful offline switch + */ + public static final int STATE_READY = 0; + + /** + * The offline session moves to idle state once all offline capture requests complete + */ + public static final int STATE_IDLE = 1; + + /** + * The offline session is closed + */ + public static final int STATE_CLOSED = 2; + + /** + * The offline session has encountered a fatal error + */ + public static final int STATE_ERROR = 3; + + /** + * The offline session failed during the offline switch + */ + public static final int STATE_SWITCH_FAILED = 4; + + /** + * Total number of reachable states + */ + private static final int NUM_STATES = 5; + + public BlockingOfflineSessionCallback() { + mProxy = null; + } + + public BlockingOfflineSessionCallback( + CameraOfflineSession.CameraOfflineSessionCallback listener) { + mProxy = listener; + } + + @Override + public void onReady(CameraOfflineSession session) { + if (mProxy != null) { + mProxy.onReady(session); + } + setCurrentState(STATE_READY); + } + + @Override + public void onSwitchFailed(CameraOfflineSession session) { + if (mProxy != null) { + mProxy.onSwitchFailed(session); + } + setCurrentState(STATE_SWITCH_FAILED); + } + + @Override + public void onIdle(CameraOfflineSession session) { + if (mProxy != null) { + mProxy.onIdle(session); + } + setCurrentState(STATE_IDLE); + } + + @Override + public void onError(CameraOfflineSession session, int error) { + if (mProxy != null) { + mProxy.onError(session, error); + } + setCurrentState(STATE_ERROR); + } + + @Override + public void onClosed(CameraOfflineSession session) { + if (mProxy != null) { + mProxy.onClosed(session); + } + setCurrentState(STATE_CLOSED); + } + + /** + * Wait until the desired state is observed, checking all state + * transitions since the last state that was waited on. + * + * <p>Note: Only one waiter allowed at a time!</p> + * + * @param state state to observe a transition to + * @param timeout how long to wait in milliseconds + * + * @throws TimeoutRuntimeException if the desired state is not observed before timeout. + */ + public void waitForState(int state, long timeout) { + Integer[] stateArray = { state }; + + waitForAnyOfStates(Arrays.asList(stateArray), timeout); + } + + /** + * Wait until the one of the desired states is observed, checking all + * state transitions since the last state that was waited on. + * + * <p>Note: Only one waiter allowed at a time!</p> + * + * @param states Set of desired states to observe a transition to. + * @param timeout how long to wait in milliseconds + * + * @return the state reached + * @throws TimeoutRuntimeException if none of the states is observed before timeout. + * + */ + public int waitForAnyOfStates(Collection<Integer> states, final long timeout) { + synchronized (mLock) { + if (mWaiting) { + throw new IllegalStateException("Only one waiter allowed at a time"); + } + mWaiting = true; + } + if (VERBOSE) { + StringBuilder s = new StringBuilder("Waiting for state(s) "); + appendStates(s, states); + Log.v(TAG, s.toString()); + } + + Integer nextState = null; + long timeoutLeft = timeout; + long startMs = SystemClock.elapsedRealtime(); + try { + while ((nextState = mRecentStates.poll(timeoutLeft, TimeUnit.MILLISECONDS)) + != null) { + if (VERBOSE) { + Log.v(TAG, " Saw transition to " + stateToString(nextState)); + } + if (states.contains(nextState)) break; + long endMs = SystemClock.elapsedRealtime(); + timeoutLeft -= (endMs - startMs); + startMs = endMs; + } + } catch (InterruptedException e) { + throw new UnsupportedOperationException("Does not support interrupts on waits", e); + } + + synchronized (mLock) { + mWaiting = false; + } + + if (!states.contains(nextState)) { + StringBuilder s = new StringBuilder("Timed out after "); + s.append(timeout); + s.append(" ms waiting for state(s) "); + appendStates(s, states); + + throw new TimeoutRuntimeException(s.toString()); + } + + return nextState; + } + + /** + * Convert state integer to a String + */ + public static String stateToString(int state) { + return mStateNames[state + 1]; + } + + /** + * Append all states to string + */ + public static void appendStates(StringBuilder s, Collection<Integer> states) { + boolean start = true; + for (Integer state : states) { + if (!start) s.append(" "); + s.append(stateToString(state)); + start = false; + } + } +} |