Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Unified Diff: ios/chrome/browser/ui/qr_scanner/README.md

Issue 2589803002: Upstream Chrome on iOS source code [6/11]. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/ui/qr_scanner/README.md
diff --git a/ios/chrome/browser/ui/qr_scanner/README.md b/ios/chrome/browser/ui/qr_scanner/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..91c3f2c4a9b45a2adc7652adf34e1c1d1951f497
--- /dev/null
+++ b/ios/chrome/browser/ui/qr_scanner/README.md
@@ -0,0 +1,280 @@
+# QR Scanner
+
+The QR Scanner provides a way of scanning QR codes and bar codes directly from
+Chrome. It is developed behind the `EnableQRCodeReader` experimental flag.
+
+[TOC]
+
+## Usage
+
+1. Create a delegate implementing the `QRScannerViewControllerDelegate`
+ protocol.
+2. Initialize `QRScannerViewController` with this delegate.
+3. Present the view controller returned by `getViewControllerToPresent`.
+
+## Behavior
+
+The QR Scanner is presented as a full-screen view controller displaying a video
+preview, a control for the camera's torch, and a control for closing the QR
+scanner.
+
+### Presentation
+
+The QR Scanner is presented using a custom transition animation which makes it
+appear to be originally positioned under the presenting view controller.
+
+### Scanning
+
+* Codes are only recognized inside the viewport.
+* A flash animation is played when a code is recognized.
+* If VoiceOver is enabled, an announcement is played instead of the animation.
+* Scanning a QR code or any other code type which can contain alphanumeric
+ strings places the scanned result in the Omnibox, and the user has to press
+ the "Go" button on the keyboard to load the result. Non-URL strings will be
+ loaded in search.
+* Scanning a bar code type which can only contain numbers will load search
+ results containing the bar code immediately without waiting for user
+ confirmation.
+
+### Torch
+
+* Torch is switched off every time the QR scanner is opened, closed, or the
+ camera session is interrupted.
+* The torch button always reflects the current torch state.
+* The torch button is in a disabled state if the camera does not have torch,
+ the torch is unavailable, or the camera is not yet loaded.
+
+### Errors
+
+* A dialog is displayed if the camera is unavailable, camera permissions are
+ not granted, the camera is in use by another application, or the application
+ is in Split View on iPad.
+* Pressing the "Cancel" button of any error dialog dismisses the QR Scanner
+ view controller.
+* If the camera becomes available when a dialog is presented, the dialog is
+ automatically dismissed.
+
+## Entry points
+
+The QR scanner can be accessed from the 3D Touch application shortcuts on
+supported devices. The `SpotlightActions` experiment allows the QR scanner to be
+accessed from Spotlight search. More info about Spotlight actions can be found
+at go/chrome-ios-spotlight and crbug.com/608733. Planned and rejected entry
+points are described in the design doc at go/chrome-ios-qr-code.
+
+Tests for QR Scanner are a part of `ios_chrome_ui_egtests`.
+
+## Controller architecture
+
+* **QRScannerViewController** is the entry point for the feature. It connects
+ the `CameraController` and the `QRScannerView` and is responsible for
+ displaying alerts from `QRScannerAlerts`.
+* **CameraController** manages the `AVCaptureSession` for the camera. It is
+ responsible for loading the camera, listening for camera notifications,
+ receiving the scanned result and informing the `QRScannerViewController`
+ about changes to the state of the camera or the torch.
+
+Operations performed by `CameraController` are done on a separate dispatch
+queue, as recommended by the [documentation][avcapturesession] for
+`AVCaptureSession`.
+
+[avcapturesession]: https://developer.apple.com/reference/avfoundation/avcapturesession
+
+### Initialization
+
+`QRScannerViewController` owns an instance of `CameraController` and
+`QRScannerView` and is their delegate.
+
+1. The `getViewControllerToPresent` method checks if camera permission is
+ granted by calling `checkPermissionsAndLoadCamera` of the
+ `CameraController`.
+2. If the camera permission is denied, an error dialog will be returned from
+ `getViewControllerToPresent`. If the user has not previously granted camera
+ permission to the application, the `QRScannerViewController` instance will
+ be returned, and an error will be displayed by the QR scanner if the user
+ denies the permission in the system dialog. The error dialog prompts the
+ user to change this setting and includes a link to the Settings app, if
+ available.
+3. If the camera permission is granted, the `QRScannerViewController` will be
+ returned as the view controller to present, and the `CameraController` will
+ start loading the camera on a separate dispatch queue.
+
+#### Camera
+
+Camera initialization is handled by the `loadCaptureSession` method of the
+`CameraController`.
+
+1. Camera state is set to `CAMERA_UNAVAILABLE` and an error dialog is
+ displayed if:
+ * The back camera of the device is not found,
+ * There was an error initializing the camera input,
+ * The video input cannot be attached to the `AVCaptureSession`,
+ * The metadata output cannot be attached to the `AVCaptureSession`,
+ * The metadata output does not support QR code recognition.
+2. After a successful initialization, camera state is set to
+ `CAMERA_AVAILABLE`, which is reported asynchronously to
+ `QRScannerViewController`, and `CameraController` starts listening for
+ camera notifications.
+3. Camera starts recording on `viewWillAppear`.
+
+#### Torch
+
+* Torch availability is checked when the camera initialization completes.
+* Torch is considered available, if the properties `hasTorch` and
+ `isTorchAvailable` of the `AVCaptureDevice` are both `YES`.
+* During initialization, it is also checked if the torch supports the torch
+ modes `AVCaptureTorchModeOn` and `AVCaptureTorchModeOff`.
+* Torch mode is set to off on initialization.
+
+#### Camera preview
+
+The `AVCaptureVideoPreviewLayer` is created by the `QRScannerView`:
+
+1. The `QRScannerView` is initialized by the `QRScannerViewController`.
+2. On `viewDidLoad`, `QRScannerViewController` calls `loadVideoPreviewLayer:`
+ with the loaded preview. If the camera is already loaded,
+ `CameraController` attaches the preview to the `AVCaptureSession`. Otherwise
+ the preview is attached immediately after the `AVCaptureSession` is
+ initialized.
+
+#### Viewport
+
+The rectangle of interest for the metadata output of the capture session is
+calculated to lie exactly inside the viewport drawn by the `QRScannerView`.
+Resetting the viewport causes the video preview to freeze for a short while,
+that is why the viewport is only set when the preview is hidden.
+
+1. `QRScannerViewController` sets the viewport on `viewDidAppear`, to make sure
+ that the preview layer is of the correct size and position when the viewport
+ is calculated.
+2. If the capture session is loaded, the viewport is set immediately. Otherwise
+ the viewport is set after the capture session is loaded.
+3. `CameraController` calls the `cameraIsReady` method of its delegate to
+ notify the `QRScannerViewController` that the viewport was successfully set
+ and the camera preview can be displayed.
+
+### Camera state and notifications
+
+`CameraController` is listening for the following notifications:
+
+1. `AVCaptureSessionRuntimeErrorNotification`, handled by setting the camera
+ state to `CAMERA_UNAVAILABLE`,
+2. `AVCaptureSessionWasInterruptedNotification`, handled by setting the camera
+ state to one of:
+ * `APPLICATION_IN_BACKGROUND`,
+ * `CAMERA_IN_USE_BY_ANOTHER_APPLICATION`,
+ * `MULTIPLE_FOREGROUND_APPS`,
+ based on the value of `AVCaptureSessionInterruptionReasonKey` in the
+ notification's user info.
+3. `AVCaptureSessionInterruptionEndedNotification`, handled by setting the
+ camera state to `CAMERA_AVAILABLE`.
+4. `AVCaptureDeviceWasDisconnected`, handled by setting the camera state to
+ `CAMERA_UNAVAILABLE`.
+
+### Torch state
+
+The current state of the torch is obtained using key-value observing of the
+`AVCaptureDevice` object.
+
+* Torch state is set based on the value of the `torchActive` property, and
+ the delegate is informed using `torchStateChanged:`.
+* Torch availability is set based on the values of `hasTorch` and
+ `torchAvailable`. Torch is only considered available if both properties are
+ `YES` and the delegate is informed using `torchAvailabilityChanged:`.
+
+The delegate sets the value of the torch using `setTorchMode:` and is informed
+of the outcome asynchronously.
+
+### Scanning
+
+`CameraController` implements the `AVCaptureMetadataOutputObjectsDelegate` and
+receives the scanned result on the main queue.
+
+* The scanned result must be an `AVMetadataMachineReadableCodeObject`.
+* Only results which are non-empty strings are passed on to the
+ `QRScannerViewController`.
+* `CameraController` checks the type of the scanned code, and if the code can
+ only contain numbers, sets the `loadImmediately` argument to `YES`.
+* If a valid code was scanned, the `CameraController` stops the capture
+ session.
+
+Supported codes (from [Machine Readable Object Types][machinereadableobjects]):
+
+* Numeric-only bar codes: UPC-E, EAN-8, EAN-13, Interleaved 2 of 5, ITF-14
+* Alphanumeric bar codes: Code 39, Code 39 Mod 43, Code 93, Code 128
+* 2D alphanumeric codes: PDF417, AztecCode, DataMatrix, QR Code
+
+[machinereadableobjects]: https://developer.apple.com/reference/avfoundation/avmetadatamachinereadablecodeobject/1668878-machine_readable_object_types?language=objc
+
+## Views
+
+The QR scanner consists of three views:
+
+* **VideoPreviewView** holds the camera preview.
+* **PreviewOverlayView** holds layers drawing the darker preview overlay and
+ the viewport border.
+* **QRScannerView** contains the `VideoPreviewView`, `PreviewOverlayView` and
+ controls as subviews.
+
+### Transition animation
+
+`QRScannerTransitioningDelegate` implements a custom transition animation:
+the `QRScannerViewController` appears to be positioned below its presenting view
+controller. The presenting view controller slides up for presentation and down
+for dismissal.
+
+### Screen rotation
+
+* `QRScannerView` and `PreviewOverlayView` rotate normally.
+ `VideoPreviewView` does not rotate: on `viewWillTransitionToSize:` the view
+ is animated to rotate in the opposite direction. This avoids resetting the
+ viewport rectangle of interest on every screen rotation, because resetting
+ it causes the video to pause for a while. The view is not positioned using
+ AutoLayout.
+* `PreviewOverlayView` is a square that is `sqrt(2)`-times bigger than
+ max(width, height) of the `QRScannerView`, to avoid redrawing the
+ viewport. This also makes the viewport rotate in place. The view is
+ positioned using AutoLayout.
+
+### Split View
+
+* Camera is unavailable in Split View.
+* When the camera becomes available, the viewport rectangle is reset,
+ otherwise the viewport would be in the wrong place when Split View is
+ cancelled.
+
+## Accessibility
+
+* Standard UI elements have accessibility labels and identifiers.
+* The value of the torch button is communicated using its accessibility value.
+* If VoiceOver is on, an accessibility announcement is played when a code is
+ scanned, and the result is loaded after the announcement finishes.
+* If the result is loaded immediately, no additional accessibility notifications are
+ posted.
+* If the result is placed in Omnibox for the user to review, the Omnibox
+ should be focused afterwards.
+
+## Metrics
+
+The following metrics are collected:
+
+* `ApplicationShortcut.ScanQRCodePressed` when the user opens the QR scanner
+ from 3D Touch application shortcuts.
+* `MobileQRScannerClose` when the user closes the QR scanner without scanning
+ a code.
+* `MobileQRScannerError` when the user closes the QR scanner from an error
+ dialog.
+* `MobileQRScannerScannedCode` when the user scans a code.
+* `MobileQRScannerTorchOn` when the user switches on the torch.
+
+## Known issues
+
+Screen rotation on iPad is not handled the same way as on iPhone, as of iOS 9.
+The counter-rotation animation is not played at the same time as the screen
+rotation animation, and the camera preview appears to be rotating. This effect
+is most visible when rotating the screen by 180 degrees, which results in an
+apparent double-rotation by 360 degrees.
+
+## See also
+
+* go/chrome-ios-qr-code for the original design doc.

Powered by Google App Engine
This is Rietveld 408576698