### Start Session Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/Session.md Demonstrates how to create and start a DeviceSession, and collect its state to add capabilities once started. ```kotlin val session = Wearables.createSession(AutoDeviceSelector()).getOrElse { error -> throw IllegalStateException(error.description) } session.start() lifecycleScope.launch { session.state.collect { state -> if (state == DeviceSessionState.STARTED) { // Ready to add capabilities addStream(session) } } } ``` -------------------------------- ### Initialization and session setup Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/dat-conventions/SKILL.md Demonstrates the basic steps for initializing the SDK, creating a session, and starting a stream. ```kotlin Wearables.initialize(context) val session = Wearables.createSession(AutoDeviceSelector()).getOrElse { error -> throw IllegalStateException(error.description) } session.start() val stream = session.addStream(StreamConfiguration()).getOrElse { error -> throw IllegalStateException(error.description) } stream.start().getOrElse { error -> throw IllegalStateException(error.description) } ``` -------------------------------- ### Add Display Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/Session.md Shows how to attach a display capability to a started session and handle its state changes. ```kotlin session.start() lifecycleScope.launch { session.state.collect { state -> if (state == DeviceSessionState.STARTED) { val display = session.addDisplay() .onSuccess { newDisplay -> lifecycleScope.launch { newDisplay.state.collect { displayState -> if (displayState == DisplayState.STARTED) { sendContentToDisplay(newDisplay) } } } } .onFailure { error, _ -> Log.e("DAT", "Failed to add display: ${error.description}") } } } } ``` -------------------------------- ### AndroidManifest.xml configuration Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/getting-started/SKILL.md Configure necessary permissions and meta-data in your AndroidManifest.xml. ```xml ``` -------------------------------- ### Maven repository configuration Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/getting-started/SKILL.md Add the Meta Wearables Maven repository to your project's settings.gradle.kts file. ```kotlin val localProperties = Properties().apply { val localPropertiesPath = rootDir.toPath() / "local.properties" if (localPropertiesPath.exists()) { load(localPropertiesPath.inputStream()) } } dependencyResolutionManagement { repositories { google() mavenCentral() maven { url = uri("https://maven.pkg.github.com/facebook/meta-wearables-dat-android") credentials { username = "" password = System.getenv("GITHUB_TOKEN") ?: localProperties.getProperty("github_token") } } } } ``` -------------------------------- ### Session Start and Failure Handling Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/AGENTS.md Example of starting a session and handling potential failures with error reporting. ```kotlin } } } } } } .onFailure { error, _ -> showError(error.description) } } } } session.start() } ``` -------------------------------- ### Starting a Display Session Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/AGENTS.md Example Kotlin code demonstrating how to create and manage a display session, including error handling and content sending. ```kotlin import com.meta.wearable.dat.core.Wearables import com.meta.wearable.dat.core.selectors.SpecificDeviceSelector import com.meta.wearable.dat.core.session.DeviceSessionState import com.meta.wearable.dat.core.types.DeviceIdentifier import com.meta.wearable.dat.core.types.DeviceSessionError import com.meta.wearable.dat.core.types.RegistrationState import com.meta.wearable.dat.display.Display import com.meta.wearable.dat.display.addDisplay import com.meta.wearable.dat.display.types.DisplayState import com.meta.wearable.dat.display.views.ButtonStyle import com.meta.wearable.dat.display.views.FlexBoxBackground import com.meta.wearable.dat.display.views.IconName import com.meta.wearable.dat.display.views.TextStyle fun startDisplaySession(selectedDeviceId: DeviceIdentifier) { if (Wearables.registrationState.value != RegistrationState.REGISTERED) { showError("Register with Meta AI before starting Display") return } val session = Wearables.createSession(SpecificDeviceSelector(selectedDeviceId)).fold( onSuccess = { it }, onFailure = { error, _ -> if (error == DeviceSessionError.DAT_APP_ON_THE_GLASSES_UPDATE_REQUIRED) { showDatAppUpdateAction() } showError(error.description) return }, ) var display: Display? = null lifecycleScope.launch { session.errors.collect { error -> if (error == DeviceSessionError.DAT_APP_ON_THE_GLASSES_UPDATE_REQUIRED) { showDatAppUpdateAction() } showError(error.description) } } lifecycleScope.launch { session.state.collect { state -> if (state == DeviceSessionState.STARTED && display == null) { session.addDisplay() .onSuccess { newDisplay -> display = newDisplay lifecycleScope.launch { newDisplay.state.collect { displayState -> setTryItEnabled(displayState == DisplayState.STARTED) if (displayState == DisplayState.STARTED) { newDisplay.sendContent { flexBox( gap = 12, padding = 24, background = FlexBoxBackground.CARD, ) { text("Bike ride", style = TextStyle.HEADING) button( label = "Done", style = ButtonStyle.PRIMARY, iconName = IconName.CHECKMARK, onClick = { showDoneState() }, ) ``` -------------------------------- ### SDK Initialization Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/getting-started/SKILL.md Initialize the DAT SDK in your Application class. ```kotlin import com.meta.wearable.dat.core.Wearables class MyApplication : Application() { override fun onCreate() { super.onCreate() Wearables.initialize(this) .onFailure { error, _ -> error("Failed to initialize DAT: ${error.description}") } } } ``` -------------------------------- ### SessionViewModel for camera session Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/sample-app-guide/SKILL.md SessionViewModel handles creating, starting, and managing camera streams. ```kotlin class SessionViewModel : ViewModel() { private var session: Session? = null private var stream: Stream? = null fun startCameraSession() { val createdSession = Wearables.createSession(AutoDeviceSelector()).getOrElse { throw IllegalStateException(error.description) } createdSession.start() session = createdSession stream = createdSession.addStream( StreamConfiguration(videoQuality = VideoQuality.MEDIUM, frameRate = 24), ).getOrElse { throw IllegalStateException(error.description) }.also { addedStream -> addedStream.start().getOrElse { throw IllegalStateException(error.description) } } } } ``` -------------------------------- ### Complete AndroidManifest.xml Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/configuration.md An example of a complete AndroidManifest.xml file demonstrating the necessary meta-data tags and permissions for the Meta Wearables DAT SDK. ```xml ``` -------------------------------- ### Codex installation using helper script Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/README.md Alternative installation for Codex using a helper script. ```bash ./install-skills.sh codex ``` -------------------------------- ### Start Stream Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/Stream.md Demonstrates how to add a stream to a session, start it, and handle success or failure callbacks. ```kotlin val stream = session.addStream( StreamConfiguration(videoQuality = VideoQuality.MEDIUM, frameRate = 24) ).getOrElse { throw IllegalStateException(it.description) } stream.start().onSuccess { Log.d("DAT", "Stream started, frames incoming") }.onFailure { Log.e("DAT", "Failed to start stream: ${it.description}") } ``` -------------------------------- ### Register and create a session Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/getting-started/SKILL.md Register the device and create a new session using AutoDeviceSelector. ```kotlin import com.meta.wearable.dat.core.Wearables import com.meta.wearable.dat.core.selectors.AutoDeviceSelector fun connect(activity: Activity) { Wearables.startRegistration(activity) } fun startSession() { val session = Wearables.createSession(AutoDeviceSelector()).getOrElse { error -> throw IllegalStateException(error.description) } session.start() } ``` -------------------------------- ### Logging Stream Start Failures Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/debugging/SKILL.md Example of how to log errors when starting a stream using Kotlin. ```kotlin private const val TAG = "DATWearables" stream.start() .onFailure { error, _ -> Log.e(TAG, "Failed to start stream: ${error.description}") } ``` -------------------------------- ### AutoDeviceSelector Examples Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/types.md Examples demonstrating how to instantiate AutoDeviceSelector with different filtering strategies. ```kotlin // Any eligible device AutoDeviceSelector() // Only display-capable devices AutoDeviceSelector(filter = { device -> device.isDisplayCapable() }) // Only compatible devices AutoDeviceSelector(filter = { device -> device.compatibility == DeviceCompatibility.COMPATIBLE }) ``` -------------------------------- ### Other tool installs using helper script Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/README.md Commands to install other AI tools like Copilot and Cursor using the helper script. ```bash ./install-skills.sh copilot # .github/copilot-instructions.md ./install-skills.sh cursor # .cursor/rules/*.mdc ./install-skills.sh agents # AGENTS.md ./install-skills.sh all # Claude/Codex when available, plus Copilot/Cursor/AGENTS.md ``` -------------------------------- ### Complete example with opt-out Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/README.md An example of AndroidManifest.xml including the application ID and analytics opt-out. ```xml ``` -------------------------------- ### MainActivity for registration Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/sample-app-guide/SKILL.md MainActivity demonstrates collecting registration state and initiating registration. ```kotlin class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) lifecycleScope.launch { Wearables.registrationState.collect { // Update registration UI } } } fun register() { Wearables.startRegistration(this) } } ``` -------------------------------- ### Observe registration and device states Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/getting-started/SKILL.md Observe the registration state and available devices using coroutines. ```kotlin lifecycleScope.launch { Wearables.registrationState.collect { state -> // Update registration UI } } lifecycleScope.launch { Wearables.devices.collect { devices -> // Update the device list } } ``` -------------------------------- ### Dependency declarations Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/getting-started/SKILL.md Declare the DAT SDK dependencies in your libs.versions.toml and app/build.gradle.kts files. ```toml [versions] mwdat = "0.7.0" [libraries] mwdat-core = { group = "com.meta.wearable", name = "mwdat-core", version.ref = "mwdat" } mwdat-camera = { group = "com.meta.wearable", name = "mwdat-camera", version.ref = "mwdat" } mwdat-mockdevice = { group = "com.meta.wearable", name = "mwdat-mockdevice", version.ref = "mwdat" } ``` ```kotlin dependencies { implementation(libs.mwdat.core) implementation(libs.mwdat.camera) implementation(libs.mwdat.mockdevice) } ``` -------------------------------- ### MockDeviceKit Setup in Tests Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/configuration.md Code snippet demonstrating how to set up and tear down the MockDeviceKit for testing purposes. ```kotlin dependencies { testImplementation(libs.mwdat.mockdevice) } ``` ```kotlin @Before fun setUp() { val mockDeviceKit = MockDeviceKit.getInstance(context) mockDeviceKit.enable( MockDeviceKitConfig(initiallyRegistered = true) ) } @After fun tearDown() { mockDeviceKit.disable() } ``` -------------------------------- ### Add Stream Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/Session.md Illustrates adding a camera stream capability to a started session and handling potential errors. ```kotlin session.start() lifecycleScope.launch { session.state.collect { state -> if (state == DeviceSessionState.STARTED) { val stream = session.addStream( StreamConfiguration( videoQuality = VideoQuality.MEDIUM, frameRate = 24, ) ).getOrElse { error -> Log.e("DAT", "Failed to add stream: ${error.description}") return@collect } stream.start() } } } ``` -------------------------------- ### Claude Code installation using helper script Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/README.md Alternative installation for Claude Code using a helper script. ```bash ./install-skills.sh claude ``` -------------------------------- ### Custom URI Scheme Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/configuration.md Example of a data tag specifying a custom URI scheme for callbacks. ```xml ``` -------------------------------- ### Suggested app structure Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/sample-app-guide/SKILL.md The suggested directory structure for the Android DAT app. ```text app/src/main/java/com/example/myapp/ ├── MyApplication.kt ├── MainActivity.kt ├── session/ │ └── SessionViewModel.kt └── ui/ ├── RegistrationScreen.kt └── CameraScreen.kt ``` -------------------------------- ### Example Test: Video Streaming Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/MockDeviceKit.md An example test case demonstrating how to test video streaming functionality with MockDeviceKit. ```kotlin @RunWith(AndroidJUnit4::class) class StreamingTest : MockDeviceKitTestCase(MainActivity::class.java) { @Test fun testVideoStreaming() { val mockDevice = mockDeviceKit.pairRaybanMeta() mockDevice.powerOn() mockDevice.unfold() mockDevice.don() // Set up mock video val videoUri = Uri.parse("file:///android_asset/test_video.h265") mockDevice.services.camera.setCameraFeed(videoUri) // Grant permission mockDeviceKit.permissions.set(Permission.CAMERA, PermissionStatus.Granted) // Test your streaming code... val scenario = scenarioRule.scenario scenario.onActivity { activity -> // Interact with activity and verify streaming works } } @Test fun testPermissionDenial() { val mockDevice = mockDeviceKit.pairRaybanMeta() mockDevice.powerOn() mockDevice.unfold() mockDevice.don() // Simulate denied permission mockDeviceKit.permissions.set(Permission.CAMERA, PermissionStatus.Denied) // Test your error handling... } } ``` -------------------------------- ### Create a session and attach a stream Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/AGENTS.md Code snippet demonstrating how to create a session, start it, add a stream with configuration, and start the stream. ```kotlin import com.meta.wearable.dat.camera.Stream import com.meta.wearable.dat.camera.addStream import com.meta.wearable.dat.camera.types.StreamConfiguration import com.meta.wearable.dat.camera.types.VideoQuality import com.meta.wearable.dat.core.Wearables import com.meta.wearable.dat.core.selectors.AutoDeviceSelector val session = Wearables.createSession(AutoDeviceSelector()).getOrElse { error -> throw IllegalStateException(error.description) } session.start() val stream: Stream = session.addStream( StreamConfiguration( videoQuality = VideoQuality.MEDIUM, frameRate = 24, ) ).getOrElse { error -> throw IllegalStateException(error.description) } stream.start().getOrElse { error -> throw IllegalStateException(error.description) } ``` -------------------------------- ### Add camera streaming Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/getting-started/SKILL.md Add camera streaming to the session with specified video quality and frame rate. ```kotlin import com.meta.wearable.dat.camera.addStream import com.meta.wearable.dat.camera.types.StreamConfiguration import com.meta.wearable.dat.camera.types.VideoQuality val stream = session.addStream( StreamConfiguration(videoQuality = VideoQuality.MEDIUM, frameRate = 24), ).getOrElse { error -> throw IllegalStateException(error.description) } stream.start().onFailure { error, _ -> throw IllegalStateException(error.description) } ``` -------------------------------- ### Start Registration Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/permissions-registration/SKILL.md Initiates the app registration process with Meta AI. ```kotlin Wearables.startRegistration(activity) ``` -------------------------------- ### Example 1: Camera App with Auto Selection Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/DeviceSelector.md A practical example showing how to create a device session for a camera app using AutoDeviceSelector to automatically select any connected device. ```kotlin fun createCameraSession(): DeviceSession? { // Auto-select any connected device val selector = AutoDeviceSelector() return Wearables.createSession(selector) .onSuccess { session -> session.start() } .onFailure { error, _ -> Log.e("DAT", "Failed to create session: ${error.description}") } .getOrNull() } ``` -------------------------------- ### Observe frames and capture photos Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/sample-app-guide/SKILL.md Code for rendering video stream previews and capturing photos. ```kotlin viewModelScope.launch { stream?.videoStream?.collect { // Render preview } } fun capturePhoto() { viewModelScope.launch { stream?.capturePhoto() ?.onSuccess { savePhoto(it.data) } ?.onFailure { showCaptureError(error.description) } } } ``` -------------------------------- ### DatResult Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/types.md Example usage of DatResult for handling session creation outcomes. ```kotlin Wearables.createSession(selector) .onSuccess { session -> session.start() } .onFailure { error, statusCode -> Log.e("DAT", "Failed: ${error.description} (code: $statusCode)") } ``` -------------------------------- ### FlexBox DSL Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/Display.md An example of using the flexBox component within the Display DSL for layout. ```kotlin flexBox(gap = 12, padding = 24, background = FlexBoxBackground.CARD) { text("Section") button(label = "Action", onClick = { handleClick() }) } ``` -------------------------------- ### Create a session and attach a stream Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/camera-streaming/SKILL.md This code snippet demonstrates how to create a session, start it, add a stream with specific video quality and frame rate, and then start the stream. ```kotlin import com.meta.wearable.dat.camera.Stream import com.meta.wearable.dat.camera.addStream import com.meta.wearable.dat.camera.types.StreamConfiguration import com.meta.wearable.dat.camera.types.VideoQuality import com.meta.wearable.dat.core.Wearables import com.meta.wearable.dat.core.selectors.AutoDeviceSelector val session = Wearables.createSession(AutoDeviceSelector()).getOrElse { error -> throw IllegalStateException(error.description) } session.start() val stream: Stream = session.addStream( StreamConfiguration( videoQuality = VideoQuality.MEDIUM, frameRate = 24, ) ).getOrElse { error -> throw IllegalStateException(error.description) } stream.start().getOrElse { error -> throw IllegalStateException(error.description) } ``` -------------------------------- ### getInstance Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/MockDeviceKit.md Gets the singleton MockDeviceKit instance for a context. ```kotlin fun getInstance(context: Context): MockDeviceKitInterface ``` ```kotlin import com.meta.wearable.dat.mockdevice.MockDeviceKit import com.meta.wearable.dat.mockdevice.api.MockDeviceKitConfig val mockDeviceKit = MockDeviceKit.getInstance(context) ``` -------------------------------- ### Observe session state Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/AGENTS.md Creates a session, starts it, and observes its state transitions, reacting to states like STARTED, PAUSED, and STOPPED. ```kotlin val session = Wearables.createSession(AutoDeviceSelector()).getOrElse { throw IllegalStateException(error.description) } session.start() lifecycleScope.launch { session.state.collect { state -> when (state) { DeviceSessionState.STARTED -> onStarted() DeviceSessionState.PAUSED -> onPaused() DeviceSessionState.STOPPED -> onStopped() else -> Unit } } } ``` -------------------------------- ### Example 2: Display App with Display-Only Devices Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/DeviceSelector.md A practical example for a display app, using AutoDeviceSelector with a filter to ensure only display-capable devices are selected. ```kotlin fun createDisplaySession(): DeviceSession? { // Auto-select display-capable device only val selector = AutoDeviceSelector(filter = { device -> device.isDisplayCapable() }) return Wearables.createSession(selector) .onSuccess { session -> session.start() } .onFailure { error, _ -> Log.e("DAT", "Failed to create display session: ${error.description}") } .getOrNull() } ``` -------------------------------- ### Codex installation Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/README.md Commands to install the Codex plugin for Meta Wearables DAT Android. ```bash git clone https://github.com/facebook/meta-wearables-dat-android.git cd meta-wearables-dat-android codex plugin install ./plugins/mwdat-android ``` -------------------------------- ### Stop Session Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/Session.md Shows how to stop a DeviceSession and clean up associated resources. ```kotlin fun cleanupSession(session: DeviceSession) { stream?.stop() session.stop() session = null } ``` -------------------------------- ### Sending Video Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/display-access/SKILL.md Example of how to send a video using VideoPlayer, including handling playback states and errors. ```kotlin import com.meta.wearable.dat.display.types.VideoCodec import com.meta.wearable.dat.display.types.VideoPlayerState import com.meta.wearable.dat.display.types.VideoSource import com.meta.wearable.dat.display.views.VideoPlayer import kotlinx.coroutines.Job private var videoStateJob: Job? = null private var videoErrorJob: Job? = null lifecycleScope.launch { val currentDisplay = display ?: return@launch val player = VideoPlayer( source = VideoSource.Url("https://example.com/tutorial.mp4"), codec = VideoCodec.MP4, ) videoStateJob?.cancel() videoErrorJob?.cancel() videoStateJob = launch { player.state.collect { if (state == VideoPlayerState.ENDED) { videoStateJob?.cancel() videoStateJob = null sendStatusCard(currentDisplay) } } } videoErrorJob = launch { player.error.collect { if (error != null) { showError(error.description) } } } currentDisplay.sendContent { video(player = player) } .onSuccess { player.play() } .onFailure { error, _ -> showError(error.description) } } ``` -------------------------------- ### Manifest Placeholders in build.gradle.kts Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/configuration.md Example of setting manifest placeholders for application ID and client token for development and production environments. ```kotlin android { productFlavors { create("dev") { dimension = "environment" manifestPlaceholders["mwdat_application_id"] = "0" manifestPlaceholders["mwdat_client_token"] = "dev-token" } create("prod") { dimension = "environment" manifestPlaceholders["mwdat_application_id"] = "YOUR_PROD_ID" manifestPlaceholders["mwdat_client_token"] = "YOUR_PROD_TOKEN" } } } ``` -------------------------------- ### Device Picker UI Logic Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/display-access/SKILL.md Example of collecting device metadata and updating the UI for a device picker. ```kotlin import com.meta.wearable.dat.core.types.Device import com.meta.wearable.dat.core.types.DeviceIdentifier import com.meta.wearable.dat.core.types.LinkState import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update private val metadataJobs = mutableMapOf() private val devicesMetadata = MutableStateFlow>(emptyMap()) lifecycleScope.launch { Wearables.devices.collect { deviceIds -> (metadataJobs.keys - deviceIds).forEach { removedId -> metadataJobs.remove(removedId)?.cancel() devicesMetadata.update { current -> current - removedId } } deviceIds.forEach { id -> metadataJobs.getOrPut(id) { launch { Wearables.devicesMetadata[id]?.collect { device -> devicesMetadata.update { current -> current + (id to device) } updateDeviceRow( id = id, name = device.name, type = device.deviceType.description, isConnected = device.linkState == LinkState.CONNECTED, isDisplayCapable = device.isDisplayCapable(), compatibility = device.compatibility, ) } } } } } } ``` -------------------------------- ### Example Handling for CaptureError Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/errors.md Demonstrates how to handle CaptureError exceptions when capturing photos. ```kotlin if (stream.state.value == StreamState.STREAMING) { viewModelScope.launch { stream?.capturePhoto() ?.onSuccess { photoData -> showCapturedPhoto(photoData) } ?.onFailure { error, _ -> when (error) { CaptureError.STREAM_NOT_ACTIVE -> { showError("Cannot capture: stream not active") } else -> { showError("Capture failed: ${error.description}") } } } } } else { showError("Stream is not streaming") } ``` -------------------------------- ### Send Video Content Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/Display.md Demonstrates how to send a video stream to the display. ```kotlin lifecycleScope.launch { val player = VideoPlayer( source = VideoSource.Url("https://example.com/video.mp4"), codec = VideoCodec.MP4, ) display.sendContent { video(player = player) } .onSuccess { player.play() } .onFailure { showError("Video send failed: ${error.description}") } // Monitor video playback player.state.collect { if (state == VideoPlayerState.ENDED) { // Send next screen sendNextContent(display) } } } ``` -------------------------------- ### Example Handling for DeviceSessionError Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/errors.md Demonstrates how to handle specific `DeviceSessionError` types when creating a session. ```kotlin Wearables.createSession(AutoDeviceSelector()) .onSuccess { session -> session.start() } .onFailure { error, _ -> when (error) { DeviceSessionError.NO_ELIGIBLE_DEVICE -> { showError("No device available. Check device is paired and connected.") } DeviceSessionError.DAT_APP_ON_THE_GLASSES_UPDATE_REQUIRED -> { showUpdatePrompt() } else -> { showError("Session creation failed: ${error.description}") } } } ``` -------------------------------- ### Handling Firmware Update Errors Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/errors.md Example of handling errors when launching a firmware update. ```kotlin if (device.compatibility == DeviceCompatibility.DEVICE_UPDATE_REQUIRED) { Wearables.openFirmwareUpdate(activity) .onFailure { error, _ -> when (error) { FirmwareUpdateError.UPDATE_LAUNCH_FAILED -> { showError("Could not launch update. Ensure Meta AI is installed.") } else -> { showError("Update failed: ${error.description}") } } } } ``` -------------------------------- ### Example Error Recovery Checklist Implementation Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/errors.md Illustrates applying the error recovery checklist to a photo capture operation. ```kotlin stream?.capturePhoto() ?.onSuccess { photo -> savePhoto(photo) } ?.onFailure { error, statusCode -> // 1. Log Log.e("DAT", "Capture failed: ${error.description} (code: $statusCode)") // 2. Identify recovery val recovery = when (error) { CaptureError.STREAM_NOT_ACTIVE -> "Ensure stream is streaming" else -> "Retry photo capture" } // 3. Update UI _uiState.update { it.copy(error = error.description, hint = recovery) } // 4. Cleanup _uiState.update { it.copy(isCapturing = false) } // 5. Retry or abort if (error == CaptureError.STREAM_NOT_ACTIVE) { // Abort this capture } else { // Could retry with delay } } ``` -------------------------------- ### Stream State Observation Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/Stream.md An example of collecting the stream's state flow to react to different stream states like STOPPED, STARTING, STREAMING, etc. ```kotlin lifecycleScope.launch { stream.state.collect { state -> when (state) { StreamState.STOPPED -> Log.d("DAT", "Stream stopped") StreamState.STARTING -> showConnectingUI() StreamState.STARTED -> Log.d("DAT", "Stream ready") StreamState.STREAMING -> { showLivePreview() enablePhotoCaptureButton() } StreamState.STOPPING -> prepareForStop() StreamState.CLOSED -> cleanupStream() } } } ``` -------------------------------- ### Example Handling for DisplayError Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/errors.md Demonstrates how to handle DisplayError exceptions when adding and sending content to a display. ```kotlin session.addDisplay() .onSuccess { display -> lifecycleScope.launch { // Wait for display to be ready display.state.collect { state -> if (state == DisplayState.STARTED) { sendInitialContent(display) } } } } .onFailure { error, _ -> when (error) { DisplayError.DEVICE_INCOMPATIBLE -> { showError("Selected device does not support display") } else -> { showError("Failed to add display: ${error.description}") } } } private suspend fun sendInitialContent(display: Display) { display.sendContent { flexBox(gap = 12, padding = 24) { text("Hello", style = TextStyle.HEADING) } }.onFailure { error, _ -> when (error) { DisplayError.INVALID_CONTENT -> { Log.e("DAT", "Content structure error: ${error.description}") } else -> { showError("Send failed: ${error.description}") } } } } ``` -------------------------------- ### MockDeviceKit Configuration for Testing Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/CHANGELOG.md Demonstrates how to configure MockDeviceKit for testing, including initial registration and permissions states. ```kotlin val config = MockDeviceKitConfig(initiallyRegistered = true, initialPermissionsGranted = false) MockDeviceKit.enable(config) ``` -------------------------------- ### Testing with MockDeviceKit Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/dat-conventions/SKILL.md Illustrates how to enable and use MockDeviceKit for testing purposes without physical hardware. ```kotlin val mockDeviceKit = MockDeviceKit.getInstance(context) mockDeviceKit.enable() val device = mockDeviceKit.pairRaybanMeta() ``` -------------------------------- ### Building the app using the exported Gradle project Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/samples/DisplayAccess/README.md Command to assemble the debug version of the application using the Gradle wrapper. ```bash ./gradlew assembleDebug ``` -------------------------------- ### Example local.properties values Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/samples/DisplayAccess/README.md Configuration properties for the sample app, including GitHub token and Meta Wearables DAT application and client tokens. ```properties github_token=YOUR_GITHUB_TOKEN mwdat_application_id=YOUR_APPLICATION_ID mwdat_client_token=YOUR_CLIENT_TOKEN ``` -------------------------------- ### Example Handling for StreamError Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/errors.md Demonstrates how to handle specific `StreamError` types when adding and starting a stream, including observing runtime errors. ```kotlin session.addStream(StreamConfiguration(videoQuality = VideoQuality.MEDIUM, frameRate = 24)) .onSuccess { stream -> stream.start() .onSuccess { lifecycleScope.launch { stream.videoStream.collect { frame -> displayFrame(frame) } } } .onFailure { error, _ -> when (error) { StreamError.PERMISSION_DENIED -> { requestCameraPermission() } else -> { showError("Stream failed: ${error.description}") } } } } .onFailure { error, _ -> showError("Failed to add stream: ${error.description}") } // Also observe error stream for runtime issues lifecycleScope.launch { stream.errorStream.collect { error -> if (error != StreamError.STREAM_ERROR) { stopStream() } } } ``` -------------------------------- ### Programmatic Initialization with Error Handling Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/configuration.md Example of initializing the Meta Wearables SDK programmatically within an Android Application class, including success and failure callbacks. ```kotlin class MyApplication : Application() { override fun onCreate() { super.onCreate() Wearables.initialize(this) .onSuccess { Log.d("DAT", "SDK initialized successfully") } .onFailure { error, statusCode -> Log.e("DAT", "SDK initialization failed: ${error.description}") // Handle initialization failure // Cannot use SDK without initialization } } } ``` -------------------------------- ### Stream Error Stream and Start Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/CHANGELOG.md Stream now exposes a typed error stream and an explicit start() method. ```kotlin Stream.errorStream ``` ```kotlin Stream.start() ``` -------------------------------- ### CLIENT_TOKEN - Using Build Variants (build.gradle.kts) Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/configuration.md Configuration for CLIENT_TOKEN using build variants in build.gradle.kts. ```kotlin android { defaultConfig { manifestPlaceholders["mwdat_client_token"] = "dev-token" } buildTypes { release { manifestPlaceholders["mwdat_client_token"] = "YOUR_PROD_TOKEN" } } } ``` -------------------------------- ### Example Initialization Error Handling Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/errors.md Demonstrates how to handle SDK initialization failures in an Android Application's onCreate method. ```kotlin class MyApplication : Application() { override fun onCreate() { super.onCreate() Wearables.initialize(this) .onFailure { error, _ -> Log.e("DAT", "SDK initialization failed: ${error.description}") // Cannot continue without SDK throw IllegalStateException("DAT SDK initialization failed") } } } ``` -------------------------------- ### Claude Code installation Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/README.md Commands to install the Claude Code plugin for Meta Wearables DAT Android. ```bash claude plugin marketplace add facebook/meta-wearables-dat-android claude plugin install mwdat-android@mwdat-android-marketplace ``` -------------------------------- ### Remote helper script execution Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/README.md Command to run the install-skills.sh helper script remotely. ```bash curl -sL https://raw.githubusercontent.com/facebook/meta-wearables-dat-android/main/install-skills.sh | bash ``` -------------------------------- ### Observe stream state Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/AGENTS.md Observes the state transitions of a stream, which include STOPPED, STARTING, STARTED, STREAMING, STOPPING, STOPPED, and CLOSED. ```kotlin lifecycleScope.launch { stream.state.collect { state -> when (state) { StreamState.STREAMING -> { // Frames are flowing } StreamState.STOPPED -> { // Streaming ended } StreamState.CLOSED -> { // Stream fully closed } else -> Unit } } } ``` -------------------------------- ### FFmpeg conversion Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/MockDeviceKit.md Convert videos to h.265 with FFmpeg. ```bash ffmpeg -hwaccel videotoolbox -i input.mp4 \ -c:v hevc_videotoolbox -c:a aac_at -tag:v hvc1 \ -vf "scale=540:960" output.mov ``` -------------------------------- ### pairRaybanMeta Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/MockDeviceKit.md Creates a simulated Ray-Ban Meta glasses device. ```kotlin fun pairRaybanMeta(): MockRaybanMeta ``` ```kotlin val mockDevice = mockDeviceKit.pairRaybanMeta() // Simulate device lifecycle mockDevice.powerOn() mockDevice.unfold() mockDevice.don() // Wearing the glasses // Later... mockDevice.doff() // Remove mockDevice.fold() mockDevice.powerOff() ``` -------------------------------- ### Display State Flow Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/Display.md Shows how to observe the display's readiness state and react accordingly. ```kotlin lifecycleScope.launch { display.state.collect { when (state) { DisplayState.INITIALIZING -> showPreparingUI() DisplayState.STARTED -> { enableContentButton() sendInitialContent(display) } DisplayState.ERROR -> showDisplayError() DisplayState.CLOSED -> cleanup() else -> Unit } } } ``` -------------------------------- ### Complete Display Flow Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/Display.md Demonstrates the complete flow for setting up, observing the state of, and sending content to a display. ```kotlin class DisplayViewModel : ViewModel() { private var display: Display? = null fun setupDisplay(session: DeviceSession) { viewModelScope.launch { session.addDisplay() .onSuccess { newDisplay -> display = newDisplay observeDisplayState(newDisplay) } .onFailure { error, _ -> showError("Display setup failed: ${error.description}") } } } private fun observeDisplayState(display: Display) { viewModelScope.launch { display.state.collect { if (state == DisplayState.STARTED) { sendMainMenu(display) } } } } private suspend fun sendMainMenu(display: Display) { display.sendContent { flexBox(gap = 16, padding = 32, background = FlexBoxBackground.CARD) { text("Main Menu", style = TextStyle.HEADING) button(label = "Start", onClick = { sendNextScreen() }) button(label = "Settings", onClick = { sendSettings() }) } } } fun stopDisplay(session: DeviceSession) { session.removeDisplay() display = null } } ``` -------------------------------- ### Remove Display Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/Session.md Demonstrates detaching the display capability from the session. ```kotlin session.removeDisplay() session.stop() ``` -------------------------------- ### Filtering by Compatibility Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/DeviceSelector.md Example of using AutoDeviceSelector to filter devices that are marked as compatible. ```kotlin val selector = AutoDeviceSelector(filter = { device -> device.compatibility == DeviceCompatibility.COMPATIBLE }) ``` -------------------------------- ### AutoDeviceSelector Observable State Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/DeviceSelector.md Example of observing the active device flow from an AutoDeviceSelector. ```kotlin lifecycleScope.launch { selector.activeDeviceFlow().collect { if (device != null) { Log.d("DAT", "Selected device: ${device.name}") } else { Log.d("DAT", "No eligible device available") } } } ``` -------------------------------- ### Setting up mock camera feeds - Video streaming Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/mockdevice-testing/SKILL.md Configure the mock camera to use a specific video feed. ```kotlin val camera = device.services.camera camera.setCameraFeed(videoUri) ``` -------------------------------- ### Remove Stream Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/Session.md Demonstrates detaching a camera stream capability from the session. ```kotlin stream?.stop() session.removeStream() stream = null ``` -------------------------------- ### Creating a mock device Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/mockdevice-testing/SKILL.md Instantiate MockDeviceKit and pair a simulated Ray-Ban Meta device. The mock device can be enabled in a registered or unregistered state. ```kotlin import com.meta.wearable.dat.mockdevice.MockDeviceKit import com.meta.wearable.dat.mockdevice.api.MockDeviceKitConfig val mockDeviceKit = MockDeviceKit.getInstance(context) // Attach fake registration and connectivity (auto-initializes Wearables if needed). // By default, Wearables.registrationState transitions to Registered. mockDeviceKit.enable() // Or start in unregistered state to test registration flows: // mockDeviceKit.enable(MockDeviceKitConfig(initiallyRegistered = false)) val device = mockDeviceKit.pairRaybanMeta() ``` -------------------------------- ### MockCameraKit Phone Camera Simulation Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/CHANGELOG.md Shows how to use the phone's camera (front or back) to simulate streaming with MockCameraKit. ```kotlin MockCameraKit.setCameraFeed(CameraFacing.FRONT) ``` -------------------------------- ### Display App build.gradle.kts Configuration Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/configuration.md Gradle build configuration for a display app, including application ID, client token, and relevant dependencies. ```kotlin android { defaultConfig { applicationId = "com.example.displayapp" manifestPlaceholders["mwdat_application_id"] = "0" manifestPlaceholders["mwdat_client_token"] = "dev-token" } buildTypes { release { manifestPlaceholders["mwdat_application_id"] = "YOUR_PROD_APP_ID" manifestPlaceholders["mwdat_client_token"] = "YOUR_PROD_TOKEN" } } } dependencies { implementation(libs.mwdat.core) implementation(libs.mwdat.display) implementation(libs.mwdat.mockdevice) // For testing } ``` -------------------------------- ### Filtering by Display Capability Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/DeviceSelector.md Example of using AutoDeviceSelector to filter devices that have display capabilities. ```kotlin val selector = AutoDeviceSelector(filter = { device -> device.isDisplayCapable() }) ``` -------------------------------- ### Filtering by Connection State Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/DeviceSelector.md Example of using AutoDeviceSelector to filter devices that are currently connected. ```kotlin import com.meta.wearable.dat.core.types.LinkState val selector = AutoDeviceSelector(filter = { device -> device.linkState == LinkState.CONNECTED }) ``` -------------------------------- ### Start Device Unregistration Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/Wearables.md Initiates the device unregistration flow. ```kotlin fun disconnectDevice(activity: Activity) { Wearables.startUnregistration(activity) } // Observe the state change lifecycleScope.launch { Wearables.registrationState.collect { if (state == RegistrationState.UNREGISTERED) { showDisconnectedUI() } } } ``` -------------------------------- ### Automatic Device Selection Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/display-access/SKILL.md Example of using AutoDeviceSelector to automatically select a display-capable device. ```kotlin import com.meta.wearable.dat.core.Wearables import com.meta.wearable.dat.core.selectors.AutoDeviceSelector val selector = AutoDeviceSelector(filter = { device -> device.isDisplayCapable() }) val sessionResult = Wearables.createSession(selector) ``` -------------------------------- ### Send UI Content Example Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/Display.md Demonstrates how to send UI content to the display using the Display DSL. ```kotlin lifecycleScope.launch { display.sendContent { flexBox( gap = 12, padding = 24, background = FlexBoxBackground.CARD, ) { text("Hello Glasses", style = TextStyle.HEADING) text("This is a test", style = TextStyle.BODY, color = TextColor.SECONDARY) button( label = "Done", style = ButtonStyle.PRIMARY, iconName = IconName.CHECKMARK, onClick = { showNextScreen() }, ) } }.onSuccess { Log.d("DAT", "Content sent successfully") }.onFailure { Log.e("DAT", "Failed to send content: ${error.description}") } } ``` -------------------------------- ### Handling Registration Errors Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/errors.md Example of how to handle registration errors by collecting from a stream. ```kotlin lifecycleScope.launch { Wearables.registrationErrorStream.collect { error -> when (error) { RegistrationError.META_AI_NOT_INSTALLED -> { showError("Please install Meta AI from Google Play Store") } RegistrationError.NETWORK_ERROR -> { showError("Network error. Check your connection and try again.") } else -> { showError("Registration error: ${error.description}") } } } } ``` -------------------------------- ### Handling Permission Errors Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/errors.md Example of how to handle permission check and request errors. ```kotlin lifecycleScope.launch { Wearables.checkPermissionStatus(Permission.CAMERA) .onSuccess { status -> when (status) { PermissionStatus.Granted -> startStreaming() PermissionStatus.Denied -> showPermissionDenied() PermissionStatus.NotRequested -> requestCameraPermission() } } .onFailure { error, _ -> when (error) { PermissionError.META_AI_APP_NOT_AVAILABLE -> { showError("Please install the Meta AI app to use this feature") } else -> { showError("Permission check failed: ${error.description}") } } } } fun requestCameraPermission() { permissionLauncher.launch(Permission.CAMERA) } private val permissionLauncher = registerForActivityResult( Wearables.RequestPermissionContract() ) { result -> result.onSuccess { status -> if (status == PermissionStatus.Granted) { startStreaming() } else { showError("Camera permission was denied") } }.onFailure { error, _ -> showError("Permission request failed: ${error.description}") } } ``` -------------------------------- ### Environment-Based Configuration using BuildConfig Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/configuration.md Example of configuring build types with BuildConfig fields for MWDat App ID and developer mode status in build.gradle.kts. ```kotlin buildTypes { debug { buildConfigField("String", "MWDAT_APP_ID", "\"0\"") buildConfigField("Boolean", "IS_DEVELOPER_MODE", "true") } release { buildConfigField("String", "MWDAT_APP_ID", "\"your_prod_id\"") buildConfigField("Boolean", "IS_DEVELOPER_MODE", "false") } } ``` -------------------------------- ### Filtering by Device Type Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/DeviceSelector.md Example of using AutoDeviceSelector to filter devices by their type, specifically for RAYBAN_META_DISPLAY. ```kotlin val selector = AutoDeviceSelector(filter = { device -> device.deviceType == DeviceType.RAYBAN_META_DISPLAY }) ``` -------------------------------- ### MockDeviceKitConfig Data Class Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/MockDeviceKit.md Configuration options for initializing MockDeviceKit. ```kotlin data class MockDeviceKitConfig( val initiallyRegistered: Boolean = true, ) ``` -------------------------------- ### AutoDeviceSelector Usage: With multiple filter conditions Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/DeviceSelector.md Example demonstrating multiple filter conditions for AutoDeviceSelector. ```kotlin val selector = AutoDeviceSelector(filter = { device -> device.linkState == LinkState.CONNECTED && device.compatibility == DeviceCompatibility.COMPATIBLE && device.isDisplayCapable() }) ``` -------------------------------- ### Stream Configuration Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/_autodocs/api-reference/Stream.md Example of configuring a stream with VideoQuality and frameRate. ```kotlin val stream = session.addStream( StreamConfiguration( videoQuality = VideoQuality.MEDIUM, // HIGH, MEDIUM, LOW frameRate = 24, // 2, 7, 15, 24, 30 FPS ) ) ``` -------------------------------- ### Shutdown camera session Source: https://github.com/facebook/meta-wearables-dat-android/blob/main/plugins/mwdat-android/skills/sample-app-guide/SKILL.md Function to stop and clean up the camera session and stream. ```kotlin fun stopCameraSession() { stream?.stop() session?.stop() stream = null session = null } ```