From a558c0169666ca070ca0e55ae13ebeb641ba3dc0 Mon Sep 17 00:00:00 2001 From: Johnson Lu Date: Wed, 28 Nov 2018 15:31:16 +0800 Subject: [PATCH] Integrate QrCode Camera with WifiDppQrCodeScannerFragment Bug: 118797380 Test: RunSettingsRoboTests Change-Id: I328bebbbcf44136df2c18ca1929a5da377a0cf6b --- .../wifi_dpp_qrcode_scanner_fragment.xml | 51 +++++++++ .../wifi_dpp_qrcode_scanner_fragment.xml | 2 +- .../wifi/dpp/WifiDppConfiguratorActivity.java | 24 +++- .../dpp/WifiDppQrCodeScannerFragment.java | 103 ++++++++++++++++-- .../settings/wifi/qrcode/QrCamera.java | 21 +++- .../dpp/WifiDppQrCodeScannerFragmentTest.java | 9 ++ 6 files changed, 189 insertions(+), 21 deletions(-) create mode 100644 res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml diff --git a/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml new file mode 100644 index 00000000000..0c938f82ede --- /dev/null +++ b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + diff --git a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml index a864f511e93..ab38ac106a0 100644 --- a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml +++ b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml @@ -32,7 +32,7 @@ android:layout_width="320dp" android:layout_height="426dp" android:layout_gravity="center"/> - { - getActivity().setResult(Activity.RESULT_CANCELED); - getActivity().finish();}); + getActivity().setResult(Activity.RESULT_CANCELED); + getActivity().finish(); + }); + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + mSurfaceView = (SurfaceView) view.findViewById(R.id.preview_view); + final SurfaceHolder surfaceHolder = mSurfaceView.getHolder(); + surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + surfaceHolder.addCallback(this); + + mDecorateView = (QrDecorateView) view.findViewById(R.id.decorate_view); + } + + @Override + public void surfaceCreated(final SurfaceHolder holder) { + initCamera(holder); + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + destroyCamera(); + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + // Do nothing + } + + @Override + public Size getViewSize() { + return new Size(mSurfaceView.getWidth(), mSurfaceView.getHeight()); + } + + @Override + public Rect getFramePosition(Size previewSize, int cameraOrientation) { + return new Rect(0, 0, previewSize.getHeight(), previewSize.getHeight()); + } + + @Override + public void handleSuccessfulResult(String qrCode) { + destroyCamera(); + mDecorateView.setFocused(true); + // TODO(b/120243131): Add a network by Wi-Fi Network config shared via QR code. + } + + @Override + public void handleCameraFailure() { + destroyCamera(); + } + + private void initCamera(SurfaceHolder holder) { + // Check if the camera has already created. + if (mCamera == null) { + mCamera = new QrCamera(getContext(), this); + mCamera.start(holder); + } + } + + private void destroyCamera() { + if (mCamera != null) { + mCamera.stop(); + mCamera = null; + } } } diff --git a/src/com/android/settings/wifi/qrcode/QrCamera.java b/src/com/android/settings/wifi/qrcode/QrCamera.java index c29236c2da4..dc650b9e067 100644 --- a/src/com/android/settings/wifi/qrcode/QrCamera.java +++ b/src/com/android/settings/wifi/qrcode/QrCamera.java @@ -43,6 +43,7 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import androidx.annotation.VisibleForTesting; @@ -85,14 +86,26 @@ public class QrCamera extends Handler { mReader.setHints(HINTS); } - void start(SurfaceHolder surfaceHolder) { + /** + * The function start camera preview and capture pictures to decode QR code continuously in a + * background task. + * + * @param surfaceHolder the Surface to be used for live preview, must already contain a surface + * when this method is called. + */ + public void start(SurfaceHolder surfaceHolder) { if (mDecodeTask == null) { mDecodeTask = new DecodingTask(surfaceHolder); - mDecodeTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + // Execute in the separate thread pool to prevent block other AsyncTask. + mDecodeTask.executeOnExecutor(Executors.newSingleThreadExecutor()); } } - void stop() { + /** + * The function stop camera preview and background decode task. Caller call this function when + * the surface is being destroyed. + */ + public void stop() { removeMessages(MSG_AUTO_FOCUS); if (mDecodeTask != null) { mDecodeTask.cancel(true); @@ -104,7 +117,7 @@ public class QrCamera extends Handler { } /** The scanner which includes this QrCamera class should implement this */ - interface ScannerCallback { + public interface ScannerCallback { /** * The function used to handle the decoding result of the QR code. diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java index 0f4bfd9e6b4..c46db2c78fa 100644 --- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java +++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java @@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertThat; import android.app.Activity; import android.content.Intent; +import android.content.pm.ActivityInfo; import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; @@ -53,4 +54,12 @@ public class WifiDppQrCodeScannerFragmentTest { assertThat(mActivityRule.getActivityResult().getResultCode()). isEqualTo(Activity.RESULT_CANCELED); } + + @Test + public void rotateScreen_shouldNotCrash() { + mActivityRule.getActivity().setRequestedOrientation( + ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + mActivityRule.getActivity().setRequestedOrientation( + ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + } }