Skip to content

CCCT-2596 Extract BaseCameraActivity From MicroImageActivity#3778

Open
Jignesh-dimagi wants to merge 3 commits into
masterfrom
ccct-2596-base-camera-activity
Open

CCCT-2596 Extract BaseCameraActivity From MicroImageActivity#3778
Jignesh-dimagi wants to merge 3 commits into
masterfrom
ccct-2596-base-camera-activity

Conversation

@Jignesh-dimagi

@Jignesh-dimagi Jignesh-dimagi commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

CCCT-2596

Technical Summary

The shared CameraX plumbing — CAMERA permission flow, provider acquisition, preview binding, action bar, and error exit — moves into a new abstract BaseCameraActivity, with everything mode-specific (camera selector, target resolution, capture use case, view setup) exposed as hooks. MicroImageActivity is refactored onto the base with its PersonalID face-detection flow unchanged. Both activities also relocate from org.commcare.fragments to a new org.commcare.activities.camera package, since they are activities, not fragments.

Safety Assurance

Safety story

What gives me confidence:

  • I built the app and exercised the PersonalID "Take Profile Photo" flow on a device — the camera launches, detects a face, and saves the photo as before.
  • The change is a behavior-preserving extraction plus package move; MicroImageActivity's logic is unchanged, only relocated into base hooks.
  • Existing PersonalIdPhotoCaptureFragmentTest covers the launch + result contract and passes; ktlint and a full compileCommcareDebugSources are clean, including the Kotlin↔Java interop.

…mera [AI]

Behavior-preserving extraction of the shared CameraX plumbing (CAMERA
permission flow, provider acquisition, preview binding, action bar, error
exit) into a new abstract BaseCameraActivity. MicroImageActivity keeps the
PersonalID face-detection flow unchanged and implements the camera hooks.
Both activities move to a new org.commcare.activities.camera package.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Jignesh-dimagi Jignesh-dimagi self-assigned this Jun 29, 2026
@Jignesh-dimagi

Copy link
Copy Markdown
Contributor Author

Suggested Review Order

  • app/src/org/commcare/activities/camera/BaseCameraActivity.kt — new abstract base; read first to see the shared plumbing and hook contract.
  • app/src/org/commcare/activities/camera/MicroImageActivity.java — refactored onto the base; confirm the face-detection flow is unchanged.
  • app/src/org/commcare/fragments/personalId/PersonalIdPhotoCaptureFragment.java — consumer; package/import update only.
  • app/src/org/commcare/navdrawer/BaseDrawerController.kt — consumer; import update only.
  • app/AndroidManifest.xml — activity registration moved to the new package.
  • app/unit-tests/src/org/commcare/fragments/personalId/PersonalIdPhotoCaptureFragmentTest.kt, BasePersonalIdPhotoCaptureFragmentTest.kt — import-only updates; existing coverage of the launch path.

@Jignesh-dimagi Jignesh-dimagi added the skip-integration-tests Skip android tests. label Jun 29, 2026
@Jignesh-dimagi Jignesh-dimagi marked this pull request as ready for review June 29, 2026 13:57
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

A new abstract BaseCameraActivity is introduced in org.commcare.activities.camera, centralizing CameraX permission handling, ProcessCameraProvider acquisition, Preview/UseCase binding, and a shared logErrorAndExit helper. MicroImageActivity is refactored to extend this base via template methods (getContentLayout, getTitleRes, getCameraSelector, onCameraViewReady, buildCaptureUseCase) and moved from org.commcare.fragments to org.commcare.activities.camera. The manifest declaration, PersonalIdPhotoCaptureFragment, BaseDrawerController, and two test files are updated to reference the new package.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • dimagi/commcare-android#3727: Added onOptionsItemSelected override for home/up navigation in the old org.commcare.fragments.MicroImageActivity, which this PR supersedes by moving that responsibility into BaseCameraActivity.

Suggested reviewers

  • OrangeAndGreen
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: extracting BaseCameraActivity from MicroImageActivity.
Description check ✅ Passed The description covers the ticket, technical summary, and safety/testing rationale, though the template sections are not fully explicit.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ccct-2596-base-camera-activity

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/src/org/commcare/activities/camera/MicroImageActivity.java (1)

98-105: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Move ImageAnalysis off the main thread. setAnalyzer(ContextCompat.getMainExecutor(...), this) runs analyze(...) on the UI thread, so the per-frame face-detection path can contend with preview rendering and input. Use a background executor here instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/org/commcare/activities/camera/MicroImageActivity.java` around lines
98 - 105, The ImageAnalysis analyzer in buildImageAnalysisUseCase is currently
scheduled with ContextCompat.getMainExecutor(getApplicationContext()), which
runs analyze(...) on the UI thread. Switch setAnalyzer(...) to use a background
executor owned by MicroImageActivity so face detection work does not block
preview rendering or input, and make sure that executor is managed with the
activity lifecycle.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/src/org/commcare/activities/camera/BaseCameraActivity.kt`:
- Around line 89-103: The async camera startup path in
BaseCameraActivity.startCamera() only guards ProcessCameraProvider acquisition,
but bindUseCases(cameraProvider) can still throw if the activity is no longer
valid or the camera config is unsupported. Add a lifecycle/state check in
startCamera before calling bindUseCases, and wrap the bindUseCases call so any
IllegalStateException or IllegalArgumentException also goes through
logErrorAndExit with the same microimage.camera.start.failed error path.

In `@app/src/org/commcare/activities/camera/MicroImageActivity.java`:
- Around line 89-95: `buildCaptureUseCase(...)` is already receiving
`targetRotation`, but the manual `ImageCapture` path still ignores it, which can
leave rotation metadata incorrect on rotated devices. Update the
`buildImageCaptureUseCase(...)` flow used by `MicroImageActivity` so the
`ImageCapture` it constructs is configured with the provided rotation, and make
sure `buildCaptureUseCase(...)` forwards `targetRotation` into that branch just
like the face-detection analysis path.

---

Outside diff comments:
In `@app/src/org/commcare/activities/camera/MicroImageActivity.java`:
- Around line 98-105: The ImageAnalysis analyzer in buildImageAnalysisUseCase is
currently scheduled with ContextCompat.getMainExecutor(getApplicationContext()),
which runs analyze(...) on the UI thread. Switch setAnalyzer(...) to use a
background executor owned by MicroImageActivity so face detection work does not
block preview rendering or input, and make sure that executor is managed with
the activity lifecycle.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ef4b7799-6036-446c-890f-0cb8bb80cb98

📥 Commits

Reviewing files that changed from the base of the PR and between 4b25464 and 24f4aaa.

📒 Files selected for processing (7)
  • app/AndroidManifest.xml
  • app/src/org/commcare/activities/camera/BaseCameraActivity.kt
  • app/src/org/commcare/activities/camera/MicroImageActivity.java
  • app/src/org/commcare/fragments/personalId/PersonalIdPhotoCaptureFragment.java
  • app/src/org/commcare/navdrawer/BaseDrawerController.kt
  • app/unit-tests/src/org/commcare/fragments/personalId/BasePersonalIdPhotoCaptureFragmentTest.kt
  • app/unit-tests/src/org/commcare/fragments/personalId/PersonalIdPhotoCaptureFragmentTest.kt

Comment on lines +89 to +103
protected fun startCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
val cameraProvider: ProcessCameraProvider
try {
cameraProvider = cameraProviderFuture.get()
} catch (e: ExecutionException) {
logErrorAndExit("Error acquiring camera provider", "microimage.camera.start.failed", e)
return@addListener
} catch (e: InterruptedException) {
logErrorAndExit("Error acquiring camera provider", "microimage.camera.start.failed", e)
return@addListener
}
bindUseCases(cameraProvider)
}, ContextCompat.getMainExecutor(this))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== File outline =="
ast-grep outline app/src/org/commcare/activities/camera/BaseCameraActivity.kt --view expanded || true

echo
echo "== Relevant slice =="
sed -n '1,220p' app/src/org/commcare/activities/camera/BaseCameraActivity.kt | cat -n

echo
echo "== Search for camera binding patterns =="
rg -n "bindToLifecycle|ProcessCameraProvider|getInstance|logErrorAndExit|cameraProviderFuture" app/src/org/commcare/activities/camera app/src | sed -n '1,200p'

Repository: dimagi/commcare-android

Length of output: 35604


🌐 Web query:

CameraX ProcessCameraProvider.bindToLifecycle throws IllegalStateException IllegalArgumentException lifecycle destroyed documentation

💡 Result:

The IllegalStateException and IllegalArgumentException errors encountered when calling ProcessCameraProvider.bindToLifecycle often relate to lifecycle state management or unsupported use case configurations. Lifecycle State Issues: If you attempt to bind use cases to a LifecycleOwner that is already in a DESTROYED state, CameraX will throw an IllegalArgumentException (e.g., "Trying to create LifecycleCamera with destroyed lifecycle") [1][2]. This often happens in asynchronous code where a camera provider is retrieved and processed after the associated Activity or Fragment has already been torn down [1]. To resolve this, always verify the state of the LifecycleOwner (e.g., check lifecycle.currentState!= Lifecycle.State.DESTROYED) before proceeding with the binding operation [1]. IllegalStateException: This exception is typically thrown when violating specific API constraints: 1. Lifecycle Conflicts: Attempting to bind a UseCase to a lifecycle when it is already bound to another, or binding to a LifecycleOwner that already has individual UseCases managed in an incompatible way [3][4]. 2. Configuration Violations: Invoking bindToLifecycle improperly, such as passing an invalid combination of UseCases or violating Singleton configuration rules [5][3]. 3. Camera Support: If the CameraSelector cannot resolve a camera that supports the requested UseCase combination, an IllegalArgumentException is thrown [5][6]. Best Practices: - Use a single call: Bind all necessary UseCases in one call to bindToLifecycle [7][8]. CameraX will automatically manage the lifecycle transitions and resource allocation [7]. - Check for DESTROYED state: Especially in async listeners (like those used with ListenableFuture), ensure the lifecycle is still valid before binding [1]. - Use the latest version: Google frequently patches these crashes in newer releases. For instance, specific crashes related to lifecycle binding and dynamic range profiles have been addressed in recent versions of the CameraX library [2][6]. - Manage View/Fragment Lifecycle: If you are using custom lifecycle owners or complex navigation, ensure that you are consistently using the correct lifecycle owner (e.g., viewLifecycleOwner in Fragments) [9][7]. If necessary, use unbindAll to clear existing bindings before re-binding if your application logic requires switching camera configurations dynamically [9][10].

Citations:


Guard the async CameraX bind path. bindUseCases(...) can still throw IllegalStateException/IllegalArgumentException if this activity is already torn down or the camera config is unsupported, and that bypasses logErrorAndExit(...) on the main thread. Add a lifecycle check before binding and route binding failures through the same exit path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/org/commcare/activities/camera/BaseCameraActivity.kt` around lines 89
- 103, The async camera startup path in BaseCameraActivity.startCamera() only
guards ProcessCameraProvider acquisition, but bindUseCases(cameraProvider) can
still throw if the activity is no longer valid or the camera config is
unsupported. Add a lifecycle/state check in startCamera before calling
bindUseCases, and wrap the bindUseCases call so any IllegalStateException or
IllegalArgumentException also goes through logErrorAndExit with the same
microimage.camera.start.failed error path.

Comment on lines 89 to 95
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
getOnBackPressedDispatcher().onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}

private void checkForCameraPermission() {
if (Permissions.missingAppPermission(this, Manifest.permission.CAMERA)) {
if (Permissions.shouldShowPermissionRationale(this, Manifest.permission.CAMERA)) {
CommCareAlertDialog dialog =
DialogCreationHelpers.buildPermissionRequestDialog(this, this,
-1, // actually not required due to launcher activity
getString(R.string.personalid_camera_permission_title),
getString(R.string.personalid_camera_permission_msg));
dialog.showNonPersistentDialog(this);
} else {
requestNeededPermissions(-1);
}
} else {
startCamera();
}
}

@Override
public void requestNeededPermissions(int requestCode) {
cameraPermissionRequestLauncher.launch(Manifest.permission.CAMERA);
}

private void startCamera() {
ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);

cameraProviderFuture.addListener(() -> {
ProcessCameraProvider cameraProvider;
try {
cameraProvider = cameraProviderFuture.get();
} catch (ExecutionException | InterruptedException e) {
logErrorAndExit("Error acquiring camera provider", "microimage.camera.start.failed", e);
return;
}
bindUseCases(cameraProvider);
}, ContextCompat.getMainExecutor(this));
}

private void bindUseCases(ProcessCameraProvider cameraProvider) {
int targetRotation = getWindowManager().getDefaultDisplay().getRotation();
Size targetResolution = new Size(faceCaptureView.getImageWidth(), faceCaptureView.getImageHeight());

// Preview use case
Preview preview = new Preview.Builder()
.setTargetResolution(targetResolution)
.setTargetRotation(targetRotation)
.build();
preview.setSurfaceProvider(cameraView.getSurfaceProvider());

UseCase imageAnalyzerOrCapture;
protected UseCase buildCaptureUseCase(Size targetResolution, int targetRotation) {
if (faceCaptureView.getCaptureMode() == FaceCaptureView.CaptureMode.FaceDetectionMode) {
imageAnalyzerOrCapture = buildImageAnalysisUseCase(targetResolution, targetRotation);
return buildImageAnalysisUseCase(targetResolution, targetRotation);
} else {
imageAnalyzerOrCapture = buildImageCaptureUseCase(targetResolution);
return buildImageCaptureUseCase(targetResolution);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- MicroImageActivity outline ---'
ast-grep outline app/src/org/commcare/activities/camera/MicroImageActivity.java --view expanded || true

echo '--- BaseCameraActivity outline ---'
ast-grep outline app/src/org/commcare/activities/camera/BaseCameraActivity.java --view expanded || true

echo '--- Relevant lines in MicroImageActivity ---'
nl -ba app/src/org/commcare/activities/camera/MicroImageActivity.java | sed -n '1,240p'

echo '--- Relevant lines in BaseCameraActivity ---'
nl -ba app/src/org/commcare/activities/camera/BaseCameraActivity.java | sed -n '1,260p'

Repository: dimagi/commcare-android

Length of output: 1847


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for f in app/src/org/commcare/activities/camera/MicroImageActivity.java app/src/org/commcare/activities/camera/BaseCameraActivity.java; do
  echo "### $f"
  rg -n "buildCaptureUseCase|buildImageCaptureUseCase|setTargetRotation|setAnalyzer|ImageAnalysis|ImageCapture" "$f" || true
done

Repository: dimagi/commcare-android

Length of output: 1789


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- locate BaseCameraActivity ---'
fd -a 'BaseCameraActivity.java' app src . 2>/dev/null || true

echo '--- search for relevant methods/usages ---'
rg -n "class BaseCameraActivity|buildImageCaptureUseCase|finalizeImageCapture|calcPreviewCaptureArea|setAnalyzer\\(|ImageAnalysis|ImageCapture" app src . --glob '*.java' --glob '*.kt' || true

Repository: dimagi/commcare-android

Length of output: 11976


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# locate the actual BaseCameraActivity file and inspect the relevant slice
fd -a 'BaseCameraActivity.java' . 2>/dev/null || true

# show only the Java files that mention the camera helpers
rg -n "buildImageCaptureUseCase|finalizeImageCapture|calcPreviewCaptureArea|setAnalyzer\\(" . --glob '*.java' || true

Repository: dimagi/commcare-android

Length of output: 1088


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- locate BaseCameraActivity ---'
fd -a 'BaseCameraActivity.java' . 2>/dev/null || true

echo '--- locate MicroImageActivity references ---'
rg -n "class MicroImageActivity|extends BaseCameraActivity|buildImageCaptureUseCase|finalizeImageCapture|calcPreviewCaptureArea|setAnalyzer\\(" app . --glob '*.java' || true

Repository: dimagi/commcare-android

Length of output: 2486


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- BaseCameraActivity.kt outline ---'
ast-grep outline app/src/org/commcare/activities/camera/BaseCameraActivity.kt --view expanded || true

echo '--- MicroImageActivity.java relevant slice ---'
sed -n '84,220p' app/src/org/commcare/activities/camera/MicroImageActivity.java

echo '--- BaseCameraActivity.kt relevant slice ---'
sed -n '1,260p' app/src/org/commcare/activities/camera/BaseCameraActivity.kt

Repository: dimagi/commcare-android

Length of output: 13265


🌐 Web query:

CameraX ImageCapture setTargetRotation rotationDegrees imageProxy rotation metadata documentation analyzer setAnalyzer executor main thread

💡 Result:

In CameraX, managing image rotation and thread execution for analysis involves several key components: Target Rotation The setTargetRotation method (available on both ImageCapture and ImageAnalysis) is used to tell CameraX the orientation of the output image relative to the sensor [1][2]. You should update this value dynamically as the device orientation changes, typically using an OrientationEventListener to match the display's rotation [3][1]. This ensures that EXIF metadata in captured JPEGs and the rotationDegrees value in ImageProxy are correctly calibrated to reflect the desired output [1][4][2]. ImageProxy Rotation Metadata When you receive an ImageProxy (in ImageCapture or ImageAnalysis), you can retrieve the necessary rotation using imageProxy.imageInfo.rotationDegrees [3][5][6]. This value represents the clockwise rotation needed to align the image buffer with the target rotation [3][5]. For JPEG images, this value is already baked into the EXIF data [5]. Analyzer Execution The ImageAnalysis.setAnalyzer method requires an executor to define the thread on which the analysis runs [7][8]. Main Thread Execution: While you can provide a main thread executor (via CameraXExecutors.mainThreadExecutor [9]), it is generally discouraged to perform heavy image processing on the main thread, as this can block the UI and lead to dropped frames or performance issues. Recommended Approach: Use a dedicated background thread or a thread pool to ensure smooth performance [6][7]. If you do not provide a background executor, CameraX handles image processing internally, but when providing your own via setAnalyzer, ensure it is capable of handling the workload quickly to maintain frame rates and avoid backpressure issues [7]. To implement a simple analyzer, you provide the executor and the analyzer instance: imageAnalysis.setAnalyzer(myExecutor, { imageProxy -> val rotation = imageProxy.imageInfo.rotationDegrees // Perform processing... imageProxy.close // Important: Always close the ImageProxy })

Citations:


Pass targetRotation into the manual ImageCapture branch. buildCaptureUseCase(...) now receives rotation from BaseCameraActivity, but buildImageCaptureUseCase(...) still builds ImageCapture without it. On rotated devices that can leave imageProxy.getImageInfo().getRotationDegrees() wrong and break the upright conversion/crop path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/org/commcare/activities/camera/MicroImageActivity.java` around lines
89 - 95, `buildCaptureUseCase(...)` is already receiving `targetRotation`, but
the manual `ImageCapture` path still ignores it, which can leave rotation
metadata incorrect on rotated devices. Update the
`buildImageCaptureUseCase(...)` flow used by `MicroImageActivity` so the
`ImageCapture` it constructs is configured with the provided rotation, and make
sure `buildCaptureUseCase(...)` forwards `targetRotation` into that branch just
like the face-detection analysis path.

@codecov

codecov Bot commented Jun 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 25.91%. Comparing base (00da1d5) to head (2580811).
⚠️ Report is 138 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #3778      +/-   ##
============================================
+ Coverage     25.84%   25.91%   +0.07%     
- Complexity     4387     4431      +44     
============================================
  Files           951      964      +13     
  Lines         57199    57706     +507     
  Branches       6812     6871      +59     
============================================
+ Hits          14782    14954     +172     
- Misses        40590    40915     +325     
- Partials       1827     1837      +10     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@OrangeAndGreen OrangeAndGreen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All looks good to me, noting those two items from CodeRabbit that seem easy to address though

}

private fun bindUseCases(cameraProvider: ProcessCameraProvider) {
val targetRotation = windowManager.defaultDisplay.rotation

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use Context.getDisplay() instead since defaultDisplay is deprecated

Comment on lines +95 to +101
} catch (e: ExecutionException) {
logErrorAndExit("Error acquiring camera provider", "microimage.camera.start.failed", e)
return@addListener
} catch (e: InterruptedException) {
logErrorAndExit("Error acquiring camera provider", "microimage.camera.start.failed", e)
return@addListener
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use one catch branch with an if statement here to check for these two exceptions and avoid repeating code

val targetResolution = getTargetResolution()

val previewBuilder = Preview.Builder().setTargetRotation(targetRotation)
targetResolution?.let { previewBuilder.setTargetResolution(it) }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on making abstract fun getTargetResolution() non-null and removing this null check?

Suggested change
targetResolution?.let { previewBuilder.setTargetResolution(it) }
targetResolution.let { previewBuilder.setTargetResolution(it) }

val targetResolution = getTargetResolution()

val previewBuilder = Preview.Builder().setTargetRotation(targetRotation)
targetResolution?.let { previewBuilder.setTargetResolution(it) }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setTargetResolution() is deprecated. We can use ResolutionSelector with ResolutionStrategy instead

val previewBuilder = Preview.Builder().setTargetRotation(targetRotation)
targetResolution?.let { previewBuilder.setTargetResolution(it) }
val preview = previewBuilder.build()
preview.setSurfaceProvider(cameraView!!.surfaceProvider)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: can treat this like a var

Suggested change
preview.setSurfaceProvider(cameraView!!.surfaceProvider)
preview.surfaceProvider = cameraView!!.surfaceProvider

Logger.exception(logMessage, e)
}
Toast.makeText(this, Localization.get(userMessageKey), Toast.LENGTH_LONG).show()
setResult(AppCompatActivity.RESULT_CANCELED)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: can simplify this because it's imported

Suggested change
setResult(AppCompatActivity.RESULT_CANCELED)
setResult(RESULT_CANCELED)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-integration-tests Skip android tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants