Skip to content

Commit

Permalink
docs(thymio-suite-mobile): add documentation to TDM discovery services
Browse files Browse the repository at this point in the history
  • Loading branch information
andresvcc committed May 10, 2024
1 parent 05e5338 commit 77abc6e
Show file tree
Hide file tree
Showing 4 changed files with 1,151 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Meta, Description } from '@storybook/addon-docs'

<Meta
title="Mobile app/Android/Web resources"
parameters={{
viewMode: 'docs',
previewTabs: {
canvas: { hidden: true }
},
}}
/>

# Accessing and Storing Web Resources
This documentation provides a concise overview of how to store and access web resources in a React Native application for Android, using the `file:///android_asset/` URL scheme. We will cover the internal workings of Android in this context, the method for using this feature in a high-level approach, and the mechanics of loading these files into a WebView.

In Android, the `file:///android_asset/` URL provides a way to access files bundled within an app's APK. These files are placed in the `assets/` directory during app development, and they are read-only at runtime. The asset mechanism is used to bundle raw resources, such as HTML files, scripts, and images, which are not compiled into the application.

### Internal Workflow

#### 1. File Placement
During the development of an Android application, specifically when preparing to use React Native or native Android components that require local resources, developers need to manage their file organization meticulously. Here's how the file placement process typically unfolds:

- **Directory Structure:** The `assets/` directory is a special folder in the Android project structure. It is located at `src/main/assets/` in the standard Android project hierarchy. This directory is not subjected to any processing by the Android build system, such as file compression, which preserves the original file format and structure.

- **Types of Files:** Any file type can be placed in this directory, including HTML, JavaScript, CSS, images, and plain text files. It’s essential for developers to ensure that these files are organized in a way that mirrors how they will be referenced in the app, as the structure of folders and subfolders within the `assets/` directory will be maintained in the APK.

- **Development Practices:** While developing, it's a common practice to regularly update and manage the files in the `assets/` directory as the application evolves. Changes to these files during development are reflected in the APK each time the application is built and packaged.

#### 2. APK Packaging
When the application is built—either for testing or for release—the contents of the `assets/` directory are bundled into the APK without modification. The APK (Android Package) is essentially a ZIP file that Android devices use to install the application. Here’s what happens during this phase:

- **Build Process:** During the build process, tools like Android Studio or the Gradle build system (used in Android development) take the files from the `assets/` directory and package them into the APK under a specific path that directly mirrors the original `assets/` directory's structure.

- **Compression and Storage:** Unlike the `res/` directory, where resources are processed and optimized by the Android build system, files in the `assets/` directory are not compressed; they are stored in their original form. This is crucial for certain types of files that need to be read exactly as they are, such as custom fonts or script files.

- **Accessibility:** Once packaged, these files become part of the application's APK and are accessible to the Android operating system and apps installed on the device, albeit in a read-only format.

#### 3. Runtime Access
At runtime, when the application is running on an Android device, the assets packaged in the APK can be accessed via the `file:///android_asset/` URL. This phase involves the following aspects:

- **URL Scheme:** The `file:///android_asset/` URL scheme is a special file path used in Android to refer to the contents of the `assets/` directory. This path is recognized by the Android system and allows applications to load content directly from the APK.

- **WebView and Other Components:** Components like WebView, which can display web content, use this URL scheme to reference web resources (HTML, CSS, JavaScript) stored within the `assets/` directory. For example, loading an HTML file into a WebView component would involve setting the source to `file:///android_asset/path/to/file.html`.

- **Security and Performance:** Accessing files from the APK is secure and efficient. Files are read directly from the device's storage and not over the internet, which not only enhances the app's performance by reducing load times but also increases security by minimizing exposure to remote exploits.

## Interfacing with Native Android Code
Native Modules: React Native uses native modules to perform tasks that require direct interaction with the device's API, such as accessing the file:///android_asset/ directory. These modules are written in Java (or Kotlin) and are registered with React Native's native module system.
Bridging: The React Native bridge is responsible for communicating between the JavaScript environment and the native environment. When a React Native application needs to load an asset through the file:///android_asset/ URL, it invokes a native module method that handles this request. This method executes on the native side, interacting directly with Android's APIs.
Method Invocation: To access assets, a native module method is defined in Java, which uses Android's AssetManager to fetch the file from the assets/ directory. This method can be exposed to JavaScript using React Native's @ReactMethod annotation, allowing it to be called from your JavaScript code.


### Steps to Use:
- **Prepare Assets:** Place your HTML files, JavaScript, CSS, and images in the `assets/` directory of your Android project.
- **Load in WebView:** Use the WebView component from `react-native-webview` to load the URL pointing to an asset, e.g., `file:///android_asset/myfile.html`.

## Loading Files in WebView
The WebView component in React Native is used to embed web pages inside your app. To load local assets in the WebView, follow these steps:

### Example Code
```javascript
import React from 'react';
import { WebView } from 'react-native-webview';

const LocalWebContent = () => {
return (
<WebView
source={{ uri: 'file:///android_asset/index.html' }}
style={{ marginTop: 20 }}
/>
);
};

export default LocalWebContent;
```

### Considerations
- **Relative Pathing:** Ensure that any resources linked from your HTML file (like images or scripts) use correct relative paths that reference the `assets/` directory.
- **MIME Types:** Android WebView may require correct MIME types to be set for certain file types to load properly.

## Implications in React Native
Using `file:///android_asset/` in React Native has several implications:

- **Performance:** Loading files from local assets can be faster than over the network, improving the performance of the WebView component.
- **Security:** It isolates web content from the network, enhancing security by preventing external attacks through web content.
- **Offline Access:** Enables your application to function offline, as the assets are packaged within the APK.
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { Meta, Description } from '@storybook/addon-docs'

<Meta
title="Mobile app/TDM discovery"
parameters={{
viewMode: 'docs',
previewTabs: {
canvas: { hidden: true }
},
}}
/>

# Documentation for the TDM Discovery Module

This documentation provides a detailed explanation of the TDM Discovery module, which is utilized in the discovery and communication of Thymio devices with iOS and Android tablets via network services.

## Overview

The TDM Discovery module leverages Zeroconf (also known as Bonjour) network technology to discover, resolve, and manage network services advertised by Thymio devices. This enables seamless communication between Thymio robots and controlling tablets without requiring manual network configuration.

## Key Objects and Methods

### `TdmDiscovery`

This class encapsulates the logic for discovering Thymio devices using Zeroconf technology. It provides methods to start and stop discovery, manage service updates, and handle network statuses.

#### Methods

| Method | Parameters | Description | Return Type |
|-------------------|-------------------------------------------|--------------------------------------------------------------|--------------------|
| `constructor` | `nativeZeroConf: Zeroconf \| any` | Initializes a new TdmDiscovery instance with Zeroconf. | None |
| `onChange` | `fun: (services: {[key: string]: MobsyaService}) => void` | Sets a callback to receive updates when new services are found or updated. | None |
| `onStatusChange` | `fun: (status: StatusZeroConf) => void` | Sets a callback to receive updates on the discovery status. | None |
| `close` | None | Stops the ongoing discovery process and cleans up resources. | None |
| `scan` | None | Initiates the discovery process to find Thymio devices. | None |

### `Zeroconf`

This class provides the foundational network capabilities required for the discovery and management of network services in a local area network.

#### Methods

| Method | Parameters | Description | Return Type |
|-------------------|---------------------------------------------------------------|--------------------------------------------------------------|--------------------|
| `constructor` | `props: any` | Initializes a new Zeroconf instance. | None |
| `addDeviceListeners` | None | Registers event listeners for Zeroconf network events. | None |
| `removeDeviceListeners` | None | Removes all registered event listeners. | None |
| `scan` | `type: string, protocol: string, domain: string, implType: string` | Starts scanning for Zeroconf services based on specified parameters. | None |
| `stop` | `implType: string` | Stops the current scanning operation. | None |
| `publishService` | `type, protocol, domain, name, port, txt, implType` | Publishes a service that can be discovered by others. | None |
| `unpublishService`| `name, implType` | Stops publishing a previously registered service. | None |
| `getServices` | None | Retrieves a list of all resolved services. | `Array of services`|

## Integration in the Context of Thymio and Tablet Communication

In the context of Thymio robots and tablet communication, the TDM Discovery module serves as a crucial component for auto-discovery and connectivity. Here’s how it integrates:

1. **Device Discovery:** When the TdmDiscovery's `scan` method is initiated from a tablet, it uses the underlying Zeroconf technology to listen for Thymio devices broadcasting their availability on the network.

2. **Service Handling:** As Thymio devices are found and their services resolved, the `TdmDiscovery` class updates its internal state with these services, accessible via callbacks set through `onChange`.

3. **Status Monitoring:** The discovery process's status is monitored through `onStatusChange`, enabling the tablet application to provide user feedback (e.g., scanning, connected, or errors).

4. **Service Resolution:** The `Zeroconf` class processes and resolves the details of each Thymio service, ensuring that the tablet can establish a robust communication link with correct network parameters (IP address, port, etc.).

## Event-Driven Communication and State Management in Zeroconf

Zeroconf, a protocol designed to enable automatic discovery of computers, devices, and services on IP networks, employs an event-driven architecture. This approach simplifies the process of integrating devices into networks without requiring manual network configuration. Here’s a detailed exploration of how Zeroconf manages its state and data through event-oriented communication, particularly in the context of the TDM Discovery module which uses Zeroconf for discovering Thymio devices.

### Core Concepts

**Event-Driven Architecture**: In Zeroconf, operations are primarily reactive; they respond to network events such as the appearance of new services, changes in the network status, or errors. This model is highly effective for network communication where state changes are frequent and unpredictable.

**State Management**: Zeroconf maintains a dynamic representation of the network state, tracking available services and their statuses. This state is updated based on the events triggered by the network environment.

### Key Events and States in Zeroconf

Zeroconf revolves around several key events that trigger state changes:

1. **Start**: The discovery process begins, indicating that the system is actively scanning the network for services.
2. **Found**: A service is detected on the network. This event triggers an update in the internal state to include the new service.
3. **Resolved**: Additional details of a found service are resolved, such as its network address and port. This step is crucial for enabling actual communication with the service.
4. **Update**: The state or details of a service change, necessitating an update in the internal representation.
5. **Stop**: The discovery process is halted, either due to manual intervention or network conditions.
6. **Error**: An error occurs during the discovery process, affecting the current operation or the overall network state.

### Mechanism of Event Handling and State Updates

**Event Listeners**: Zeroconf employs listeners for each event type. These listeners are functions that execute in response to their respective events. For example:
- When the `found` event is triggered, the listener function updates the internal service registry with the new service.
- The `resolved` event's listener adds resolved details to the already registered service, such as IP addresses and ports.

**State Transitions**: The transition between different states in Zeroconf is governed by the outcomes of these event responses. For instance:
- On receiving the `start` event, the state transitions to "scanning".
- On a `stop` event, the state changes to "stopped".
- An `error` event may move the system into an "error" state, prompting either a retry or a halt, depending on the error's nature.

**Callback Functions**: Developers can hook into these events by registering callbacks. These callbacks allow external modules, like the TDM Discovery module, to react appropriately to changes in the network state. For example, updating a UI element to reflect the discovery status or handling the connectivity logic to communicate with a Thymio device.

### Practical Implementation in TDM Discovery

In the TDM Discovery module, the Zeroconf mechanism is encapsulated within a class that manages both the discovery and the communication setup with Thymio devices. Here’s how it integrates Zeroconf:
- **Initialization**: Upon instantiation, the `TdmDiscovery` class configures Zeroconf with necessary listeners for all relevant events.
- **Discovery Process**: When the `scan` method is called, it triggers Zeroconf to start the network scan, handling the `start`, `found`, and `resolved` events as they occur.
- **State Management**: The internal state of `TdmDiscovery` is updated based on these events, maintaining a current view of all Thymio devices available and their connectivity details.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ To integrate the VPL3 web interface into the Android mobile application, an unde
To construct this URL, necessary data must first be acquired from the 'scanner' page, which can be accessed using the following URL pattern:

```javascript
http://127.0.0.1:3000/scanner/index.html?data=${
file:///android_asset/scanner/index.html?data=${
JSON.stringify({
...LTServices
})}&gl=${JSON.stringify(
Expand Down
Loading

0 comments on commit 77abc6e

Please sign in to comment.