# 画面設計書 6-カメラ接続フラグメント

## 概要

本ドキュメントは、TF DemoアプリにおけるCameraConnectionFragment（カメラ接続フラグメント）の画面設計書である。Camera2 APIを使用してカメラプレビューを表示するFragmentであり、ClassifierActivityおよびDetectorActivity、StylizeActivityで利用される。

### 本画面の処理概要

**業務上の目的・背景**：Camera2 APIによるカメラプレビュー表示処理をFragmentとしてモジュール化するために本クラスが必要である。CameraActivityが生成し、Activity内のコンテナに配置することで、カメラプレビューの表示とフレームデータの提供を担う。

**画面へのアクセス方法**：直接起動されることはなく、CameraActivity.setFragment()からnewInstance()ファクトリメソッドで生成される。Camera2 API対応デバイスでのみ使用される。

**主要な操作・処理内容**：
1. Camera2 APIによるカメラデバイスのオープン・クローズ管理
2. TextureView上でのカメラプレビュー表示
3. 最適なプレビューサイズの選択（chooseOptimalSize）
4. ImageReader（YUV_420_888形式）によるフレームデータの取得・提供
5. CameraCaptureSessionの作成・管理
6. テクスチャの回転・スケール変換（configureTransform）
7. ConnectionCallbackを通じたプレビューサイズ情報の親Activityへの通知

**画面遷移**：CameraActivity.setFragment()により配置される。他の画面への遷移機能は持たない。

**権限による表示制御**：カメラ権限はCameraActivity側で管理される。本Fragment自体では権限チェックを行わない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 52 | 画像変換操作（Image Operations） | 主機能 | Camera2 APIでYUV_420_888形式のプレビューフレームを取得しImageReaderで画像データを提供 |

## 画面種別

Fragmentコンポーネント（カメラプレビュー表示）

## URL/ルーティング

Fragmentのため、URLベースのルーティングは存在しない。パッケージ: `org.tensorflow.demo`、クラス: `CameraConnectionFragment`。

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 説明 |
|--------|----------|---------|------|
| cameraId | 入力 | String | setCamera()で設定されるカメラID |
| inputSize | 入力 | Size | 希望するプレビューサイズ（TFモデルの入力サイズ） |
| layout | 入力 | int | インフレートするレイアウトリソースID |
| imageListener | コールバック | OnImageAvailableListener | フレーム利用可能時のリスナー（CameraActivity） |
| ConnectionCallback | コールバック | ConnectionCallback | プレビューサイズ確定時のコールバック |
| previewSize | 出力 | Size | 選択されたプレビューサイズ |
| sensorOrientation | 出力 | Integer | カメラセンサーの回転角度 |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|---------|------|
| カメラプレビュー | AutoFitTextureView (texture) | Camera2 APIによるリアルタイムカメラプレビュー映像 |

## イベント仕様

### 1-SurfaceTexture利用可能イベント（onSurfaceTextureAvailable）

TextureViewのSurfaceTextureが利用可能になった際に呼び出される。

処理フロー:
1. openCamera(width, height)を呼び出し
2. setUpCameraOutputs()でカメラ出力設定（プレビューサイズ決定、sensorOrientation取得、ConnectionCallbackの呼び出し）
3. configureTransform()でテクスチャの回転変換を設定
4. CameraManager.openCamera()でカメラデバイスをオープン

### 2-カメラデバイスオープンイベント（stateCallback.onOpened）

カメラデバイスが正常にオープンされた際に呼び出される。

処理フロー:
1. cameraOpenCloseLockを解放
2. createCameraPreviewSession()でプレビューセッションを作成
3. SurfaceTexture + ImageReader（YUV_420_888, maxImages=2）でプレビュー出力設定
4. CaptureRequest.Builder: AF_MODE_CONTINUOUS_PICTURE, AE_MODE_ON_AUTO_FLASH
5. setRepeatingRequest()でプレビュー開始

### 3-Fragment一時停止イベント（onPause）

Fragment停止時にcloseCamera()とstopBackgroundThread()でリソース解放。

## データベース更新仕様

### 操作別データベース影響一覧

本画面はデータベースを使用しない。

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| なし | なし | なし | データベース操作なし |

## メッセージ仕様

| メッセージID | メッセージ内容 | 種別 | 表示条件 |
|-------------|--------------|------|---------|
| MSG-01 | "Failed" | エラー | CameraCaptureSession設定失敗時（onConfigureFailed） |
| MSG-02 | camera_error文字列リソース | エラー | Camera2 API非対応でNullPointerException発生時 |

## 例外処理

| 例外状態 | 処理内容 |
|---------|---------|
| カメラオープンタイムアウト | 2500msでSemaphore取得失敗時にRuntimeExceptionをスロー |
| CameraAccessException | Logger.e()でエラーログ出力 |
| NullPointerException（Camera2非対応） | ErrorDialogを表示し、RuntimeExceptionをスロー |
| カメラデバイスエラー（onError） | カメラをクローズし、Activityをfinish() |
| InterruptedException（closeCamera） | RuntimeExceptionをスロー |

## 備考

- MINIMUM_PREVIEW_SIZE: 320px
- ImageReader: YUV_420_888形式、maxImages=2
- AutoFocus: CONTROL_AF_MODE_CONTINUOUS_PICTURE
- AutoExposure: CONTROL_AE_MODE_ON_AUTO_FLASH
- BackgroundThread名: "ImageListener"
- レイアウト: コンストラクタ引数で指定（camera_connection_fragment.xml等）

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | CameraConnectionFragment.java | `tensorflow/tools/android/test/src/org/tensorflow/demo/CameraConnectionFragment.java` | ConnectionCallbackインターフェース（117-119行目）、フィールド変数（124-228行目） |

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CameraConnectionFragment.java | 同上 | newInstance()（309-315行目）、onCreateView/onViewCreated（318-326行目）、onResume（334-347行目） |

**主要処理フロー**:
1. **309-315行目**: ファクトリメソッドで4引数（callback, imageListener, layout, inputSize）を受け取り生成
2. **320行目**: レイアウトのインフレート
3. **325行目**: AutoFitTextureViewの取得
4. **336-346行目**: onResumeでバックグラウンドスレッド開始→TextureView準備完了ならopenCamera

#### Step 3: カメラセットアップを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CameraConnectionFragment.java | 同上 | setUpCameraOutputs()（363-408行目）: プレビューサイズ選択、sensorOrientation取得、ConnectionCallback呼び出し |
| 3-2 | CameraConnectionFragment.java | 同上 | chooseOptimalSize()（268-307行目）: 最適プレビューサイズの選択アルゴリズム |
| 3-3 | CameraConnectionFragment.java | 同上 | createCameraPreviewSession()（496-562行目）: Surface+ImageReaderによるプレビュー設定 |

### プログラム呼び出し階層図

```
CameraConnectionFragment
    |
    +-- newInstance(callback, imageListener, layout, inputSize)
    |
    +-- onResume()
    |       +-- startBackgroundThread()
    |       +-- openCamera() / setSurfaceTextureListener()
    |
    +-- openCamera()
    |       +-- setUpCameraOutputs()
    |       |       +-- chooseOptimalSize()
    |       |       +-- cameraConnectionCallback.onPreviewSizeChosen()
    |       +-- configureTransform()
    |       +-- manager.openCamera(cameraId, stateCallback)
    |
    +-- stateCallback.onOpened()
    |       +-- createCameraPreviewSession()
    |               +-- Surface(textureView)
    |               +-- ImageReader.newInstance(YUV_420_888)
    |               +-- previewReader.setOnImageAvailableListener(imageListener)
    |               +-- captureSession.setRepeatingRequest()
    |
    +-- onPause()
            +-- closeCamera()
            +-- stopBackgroundThread()
```

### データフロー図

```
[入力]                        [処理]                              [出力]

CameraDevice -----> CaptureSession -----> ImageReader ---------> OnImageAvailableListener
                   (TEMPLATE_PREVIEW)    (YUV_420_888, 2枚)      (CameraActivity)
                         |                                              |
                         v                                              v
                   Surface(TextureView)                          フレームデータ
                   (プレビュー表示)                              (Image → YUVバイト)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CameraConnectionFragment.java | `tensorflow/tools/android/test/src/org/tensorflow/demo/CameraConnectionFragment.java` | ソース | Camera2 APIプレビューFragment |
| AutoFitTextureView.java | `tensorflow/tools/android/test/src/org/tensorflow/demo/AutoFitTextureView.java` | ソース | アスペクト比を自動調整するTextureView |
| CameraActivity.java | `tensorflow/tools/android/test/src/org/tensorflow/demo/CameraActivity.java` | ソース | 親Activity（imageListener提供元） |
| camera_connection_fragment.xml | `tensorflow/tools/android/test/res/layout/camera_connection_fragment.xml` | レイアウト | 標準カメラプレビューレイアウト |
| camera_connection_fragment_tracking.xml | `tensorflow/tools/android/test/res/layout/camera_connection_fragment_tracking.xml` | レイアウト | 追跡用レイアウト |
| camera_connection_fragment_stylize.xml | `tensorflow/tools/android/test/res/layout/camera_connection_fragment_stylize.xml` | レイアウト | スタイル変換用レイアウト |
