Skip to content

add in projected permissions and hardware access snippets#821

Open
trambui09 wants to merge 2 commits intoandroid:mainfrom
trambui09:tb/ai-glasses-permissions
Open

add in projected permissions and hardware access snippets#821
trambui09 wants to merge 2 commits intoandroid:mainfrom
trambui09:tb/ai-glasses-permissions

Conversation

@trambui09
Copy link
Contributor

Projected Snippets:

  • Updated GlassesMainActivity.kt to include hardware permission handling using the new ProjectedPermissionsResultContract.

Created ProjectedHardware.kt covering:

  • Obtaining ProjectedContext for both glasses and host (phone) devices.
  • High-fidelity image capture using CameraX with Camera2 Interop for FPS and resolution control.

@trambui09 trambui09 requested review from a team, kkuan2011 and yrezgui as code owners February 27, 2026 19:14
@snippet-bot
Copy link

snippet-bot bot commented Feb 27, 2026

Here is the summary of changes.

You are about to add 7 region tags.

This comment is generated by snippet-bot.
If you find problems with this result, please file an issue at:
https://github.com/googleapis/repo-automation-bots/issues.
To update this comment, add snippet-bot:force-run label or use the checkbox below:

  • Refresh this comment

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the XR projected samples by incorporating robust permission handling for projected devices and showcasing advanced hardware access capabilities. It enables applications running on projected devices, such as AI glasses, to request and manage camera permissions, and demonstrates how to capture high-fidelity images using CameraX with fine-grained control over resolution and frame rates, bridging the gap between projected and host device interactions.

Highlights

  • CameraX Integration: Integrated CameraX dependencies to support advanced camera functionalities for projected devices.
  • Projected Permission Handling: Implemented a new projected permission handling mechanism in GlassesMainActivity.kt for camera access using ProjectedPermissionsResultContract.
  • Projected Hardware Access Snippets: Introduced ProjectedHardware.kt to demonstrate obtaining projected and host device contexts and high-fidelity image capture using CameraX with Camera2 Interop.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • gradle/libs.versions.toml
    • Added cameraLifecycle and cameraCamera2 version references.
    • Defined androidx-camera-lifecycle and androidx-camera-camera2 libraries.
  • xr/build.gradle.kts
    • Added androidx.camera.lifecycle and androidx.camera.camera2 implementation dependencies.
  • xr/src/main/java/com/example/xr/projected/GlassesMainActivity.kt
    • Imported necessary classes for permissions, including Manifest, PackageManager, ActivityResultLauncher, ContextCompat, ProjectedPermissionsRequestParams, and ProjectedPermissionsResultContract.
    • Registered an ActivityResultLauncher for projected permissions, handling camera permission results.
    • Added logic in onCreate to check for camera permission and request it if not granted, calling initializeGlassesFeatures upon permission grant.
    • Moved the lifecycleScope.launch block into a new initializeGlassesFeatures private function.
    • Added hasCameraPermission() and requestHardwarePermissions() helper methods for permission management.
  • xr/src/main/java/com/example/xr/projected/ProjectedHardware.kt
    • New file created to house projected hardware examples.
    • Contains getGlassesContext to demonstrate obtaining a context for the projected device.
    • Contains getPhoneContext to demonstrate obtaining a context for the host device from the projected device.
    • Contains startCameraOnGlasses demonstrating high-fidelity image capture using CameraX with Camera2 Interop, including resolution and FPS control.
Activity
  • No specific activity (comments, reviews, or progress updates) was provided in the context for this pull request.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request adds code snippets for handling projected permissions and accessing hardware like the camera in an XR context. The changes include updating dependencies, modifying GlassesMainActivity to handle camera permissions, and adding a new ProjectedHardware.kt file with example functions. My review focuses on improving the robustness and maintainability of the new code. I've suggested consolidating dependency versions, adding better error handling for context creation and permission requests, and cleaning up some minor code style issues.

// Permission granted, initialize the session/features.
initializeGlassesFeatures()
} else {
// Handle permission denial.
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The permission denial case is not handled. It's important to provide feedback to the user when a required permission is denied. You should consider showing a message explaining why the camera permission is necessary for the app's functionality and guide them on how to grant it in the app settings.

Comment on lines 262 to 263
androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "cameraLifecycle" }
androidx-camera-camera2 = { group = "androidx.camera", name = "camera-camera2", version.ref = "cameraCamera2" }
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

To align with the practice of using a consolidated version for the CameraX library group, please update these library definitions to reference the cameraX version variable.

Suggested change
androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "cameraLifecycle" }
androidx-camera-camera2 = { group = "androidx.camera", name = "camera-camera2", version.ref = "cameraCamera2" }
androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "cameraX" }
androidx-camera-camera2 = { group = "androidx.camera", name = "camera-camera2", version.ref = "cameraX" }

Comment on lines +99 to +101
val cameraCharacteristics = camera2CameraInfo.getCameraCharacteristic(
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP
)
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The cameraCharacteristics variable is assigned but never used. If it's not needed for any logic, it should be removed to avoid confusion and improve code clarity.

// [START androidxr_projected_permissions_launcher]
// Register the permissions launcher using the ProjectedPermissionsResultContract.
private val requestPermissionLauncher: ActivityResultLauncher<List<ProjectedPermissionsRequestParams>> =
registerForActivityResult(ProjectedPermissionsResultContract()) { results ->
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we use rememberLauncherForActivityResult() instead?
https://developer.android.com/develop/ui/compose/libraries#requesting-runtime-permissions

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think rememberLauncherForActivityResult cannot be used in onCreate; it can only be used inside a @composable function. The registerForActivityResult ensures the launcher is registered before the Activity starts.

// 1. Get the CameraProvider using the projected context.
// When using the projected context, DEFAULT_BACK_CAMERA maps to the AI glasses' camera.
val projectedContext = ProjectedContext.createProjectedDeviceContext(activity)
val cameraProviderFuture = ProcessCameraProvider.getInstance(projectedContext)
Copy link
Contributor

Choose a reason for hiding this comment

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

Just wanted to make sure we're handling the null case in the code here.

If projectedContext is null, will this always return a non-null object? could cameraProviderFuture be null?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

createProjectedDeviceContext() throws an IllegalStateException if the projected device isn't found. I'll edit the snippets to catch this. I don't think cameraProviderFuture can be null.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants