Google I/O 2023 セッション動画を見たメモ

Google I/O 2023 のいろんなセッション動画を見たメモ。
全てのセッションではないです！


## What's new in Kotlin for Android

https://io.google/2023/program/a3250bf1-dab1-4752-82bb-4412afb94d66/

https://youtu.be/QGtB--ABiNM

Android における Kotlin に関する更新を紹介するセッション。


- K2 Compiler
    - Kotlin 1.8 よりも最大 2 倍高速
    - Kotlin 1.9 の期間で Compose Compiler と KSP で K2 を Experimental で使えるよう取り組んでいる
    - Android Studio も来年には K2 対応予定
- Kotlin DSL for Gradle builds
    - Android Studio G からデフォルトを Kotlin DSL に
    - Version catalog へのコードジャンプもサポートされる
- KSP
    - KSP は kapt に比べて stubs を作らずに Kotlin を直接解析するので高速 & Java に依存しないので Mutliplatform 対応可能
    - Room、Glide、Moshi などは既にサポート、Dagger/Hilt は対応中
    - 全てが kapt→KSP へ移行できなくてもライブラリごとやモジュールごとで徐々に移行すべき

## Jetpack Compose Debugging

https://io.google/2023/program/a3ed5302-d787-41bd-8623-54193d36caf0/

https://youtu.be/Kp-aiSU8qCU

Jetpack Compose でのデバッグをどういった場合にどのツールを使うべきかを解説しているセッション。

- Debugging Mindset
    - Define(何が問題なのか)
    - Reproduce(再現する例を用意する、テストを書くのも良い)
    - Validate Assumption(仮説をツールを用いて検証する)
    - Fix(修正してテストして他が壊れていないか確認)
- Common Compose Issues
    - Q.どうして recompose されたのか、どの引数が変更されて recompose されたのかわからない
        - recompose には以下のパターンがある
            - Direct recomposition
                - 関数内で State を直接読み取っている場合
            - Indirect recomposition
                - 引数が変更されて recompose される場合
            - Unskippable recomposition
 				- 引数が Unstable の状態で親の recompose で子も recompose される場合
        - A.Android Studio H で Composable 関数に break point を置くとどの引数が原因で recompose されたかわかるようになる
    - Q.頻繁に recompose される場合は?
        - A.break point で止めることが難しい場合は Log を使う
            - ただし、Log 自体が State を持つと必要以上に recompose されるので SideEffect で囲むなり注意する必要がある
    - Q.様々なフォームファクターでの UI を確認したい場合
        - A.Android Studio H で Visual Lint が Compose Preview に対応
    - Q.jank が表示されるのはなぜ?
        - リリースビルドで R8 を有効にしていて Baseline Profiles も有効にしている時
        - A.アニメーションやスクロールで必要以上に recompose されていないかを確認するために Layout Inspector を使用する
            - Layout Inspector で原因となりそうな箇所を探し、break point でなぜ recompose されているのかを探る
    - Q.Layout Inspector ではどこを調べるといいかわからない時は?
        - A.Trace でどこのコードが時間を費やしているのか調べる
            - System Trace
                - オーバーヘッドが少ないがトレース対象としてマークした部分しか表示できない
            - Method Trace
                - トレース中の全てのメソッドが表示できるがオーバーヘッドが高い
            - Android Studio で Composable 関数に絞ったトレースが System Trace で可能になる
                - https://developer.android.com/jetpack/compose/tooling/tracing
 		
## Building for the future of Android

https://io.google/2023/program/838fba77-a661-42fd-aebc-a1b0e5f26249/

https://youtu.be/WMMPXayjP8g

将来に向けてどのように実装すべきかを説明しているセッション。
バックグラウンドタスクを適切に処理したり、端末間をシームレスにしたり、プライバシーに気をつけましょうといった内容になっている。

- Seamless Interoperability
    - Background
        - Android 14 でのバックグラウンドの処理のフローチャート
     		![4f2ebd2266934147aee8d824e5a69b3a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/e26d07b3-54a0-59af-969c-c124f70ad8fb.png)
            - ナビゲーションやメディア再生には Foreground service
            - それ以外はほとんど WorkManager
        - Foreground service の Type
            - Android 14 以降はフォアグラウンドのパーミッションに加えてタイプの指定とパーミッションが必要
                - `shortService` はタイプのパーミッション不要で短期間で重要な何かを処理する時に使う
            - 制限付きのスケジュール可能なデータ転送の Job の仕組みが Android 14 で追加されている
        - 通話関連のバックグラウンド処理をサポートする Telecom のライブラリが Jetpack に追加
        - 正確な時間での処理が必要な場合は Alerm を使うが、バックグラウンドで何かをさせるためのものではない
        - 適切にアプリと連携することがバックグラウンドでの処理をするときに将来的にいい
    - Cross Device SDK
        - 夏頃に Preview が終了する
        - 異なるデバイスに通話を転送したり、読んでいる記事をTabletに転送して見たり、友人に位置情報を共有したり
    - Predictive Back
        - Android 14 ではアプリ内の Predictive Back が追加される
            - ユーザが間違って戻ることを防ぐ
        - Android 14 以降では `android:enableOnBackInvokedCallback="true"` の設定を Activity ごとに適用が可能になる
- Privacy & Security
    - Android 14 では選択したメディアだけ読み込む API やパーミッションがどのように使われるかの説明表示
    - Android 14 以降では targetSdk 23 未満のアプリをインストールできない
    - Privacy Sandbox でプライバシーを保護する広告を提供
    - Health Connect がプライバシーとデータを制御して健康データを共有
    - 認証情報の端末移行は重要で Jetpack Credential Manager を使って Passkey だけでなくアカウント情報の復元と新しいユーザ認証を簡素化できる
- Personalization
    - ホームに溶け込む Widget を作るために Glance 
    - Themed icon
    - Android 14 でのアプリごとの設定の改善
- Hardware
    - Phone、Tablet、Foldable、??
    - Android 14 では stylas やキーボード入力が改善されている
    - Pixel 7 などのデバイスで 64bit only に移行している
- 将来に向けて構築するということは健全性、相互運用性、セキュリティを考慮して責任を持って構築することを意味する


## Developing high quality apps for large screens and foldables

https://io.google/2023/program/4723ec46-d9f0-43fe-b82b-e769bb619f22/

https://youtu.be/5JQjk3ZqPWc

大きい画面対応で考慮した方がいい点が紹介されているセッション。

- Google の 50 を超えるアプリで大きい画面対応をおこなってきた
- Foldable は様々な向きや折りたたみの状態で使われ、それらをシームレスにすることが優れた UX の鍵になる
- Android 12 以降ではアプリの向きが固定されていたりサイズ変更できない場合はレターボックスが追加される
    - https://developer.android.com/guide/practices/enhanced-letterboxing
- 大きい画面対応でユーザを喜ばせる方法
    - レイアウトの参考
        - https://developer.android.com/large-screens/gallery
        - https://developer.android.com/guide/topics/large-screens/large-screen-canonical-layouts
    - WindowManager 1.1 で Embedded Activity が Experimental ではなくなる
    - Multitasking
        - アプリが全画面から分割状態になっても状態を失わないようにする
        - D&D を有効にしてコンテンツを共通できるようにする
        - `FLAG_ACTIVITY_LAUNCH_ADJACENT` でマルチインスタンスで起動できる
    - Input
        - キーボード、マウス、トラックパッド、スタイラスなどに互換性があることを期待している
        - アプリがタッチなしでキーボードなどで操作できるようにする必要がある
- デバッグ
    - Compose preview 
    - Resizable Emulator
    - Desktop Emulator

## What's new in Android development tools
		
https://io.google/2023/program/d94e89c5-1efa-4ab2-a13a-d61c5eb4e49c/

https://youtu.be/7lubRrkxagk

Android Studio 等の開発ツールの最近の更新や、今後更新される機能の紹介とデモのセッション。

- Updates
    - Studio Bot
        - エラーログを問う、実装してもらう、テストを書いてもらう
        - 実行したり、任意の場所に break point をおいてもらったり
    - App Quarity Insights + Android Vitals
    - App Actions のために Google Assistant Plugin を更新
        - アプリを Play Store に送信せずに App Actions のプレビューを生成したり、App Actions がパラメータを処理するのをテストできる
    - Power profiler
        - バックグラウンドやフォアグラウンドでの消費電力の視覚化
    - Device Explorer
        - 旧 Device File Explorer 
        - プロセスの強制停止とかもできるように
    - Watch Face Format
        - エミュレータで新しいウォッチフェイスの形式を実行できる
    - Gradle Managed Device on Firebase
        - Firebase Test Lab にテストをデプロイできる
    - Gradle Configration Caching
        - ビルド時間の短縮
    - Baseline Profile Gradle Plugin

## Scalable UI testing solutions

https://io.google/2023/program/6d34f5ed-60c1-4a92-9ff9-5aa4fd561af4/

https://youtu.be/L6CSaH0kDnI

UI テストや実機の状態の仕方について解説されるセッション。

- Configuration change のテスト
    - デバイスの回転や Foldable の展開などの Configuration change のテストをしておかないと安定性やデータの永続化の問題が起きうる
    - Esspresso Device API を使う
        - AGP 8.2-alpha と Emulator 33.1.10 が必要
            ```build.gradle
            testOption {
                emulatorAccess {
                    enabled true
                }
            } 
            dependencies {
                androidTestImplementation "androidx.test.espresso:espresso-device:1.0.0-alpha05"
            }
            ```
    - 画面回転のテスト
        - `@Rule` で最初の開始向きを設定
            ```kotlin
            @get:Rule
            val screenOrientationRule = ScreenOrientationRule(ScreenOrientation.PORTRAIT)
            ```
        - テストで回転させる
            ```kotlin
            @Test
            fun rotationTest() {
                ...
                onDevice().setScreenOrientation(ScreenOrientation.LANDSCAPE)
            }
            ```
        - 折りたたみのテスト
            ```kotlin
            @Test
            fun unfoldedTest() {
                onDevice().setClosedMode()
                ...
                onDevice().setFlatMode()
            }
            ```
        - テスト時にどのデバイスが必要か指定でき、一致しなければスキップされる(折りたたみのテストをPhoneでするのを防げる)
            ```kotlin
            @Test
            @RequireDeviceMode(mode = FLAT)
            fun unfoldedTest() {
            ```				
- テストを実行するために物理デバイスに素早くアクセスする必要があるときは Gradle Managed Device + Firebase Test Lab
    - Firebase アカウントで Gradle を認証する必要もある
    - 将来的には複数のデバイスを使えるように拡張したい
- スクリーンショットによる VRT 
    - AGP 8.2 の Experimental な機能としてプレビューをスクリーンショットテストに変換できるようになる
        - アプリモジュールにディレクトリを追加
            - `/MyProject/app/src/screenshotTest`
        - Compose のプレビューを設定して `gradlew debugScreenshotTest --record-reference-images` で参照画像の生成
        - `gradlew debugScreenshotTest` で差分確認


## Best practices for saving UI state on Android

https://io.google/2023/program/86439875-e3a1-4ca7-92de-79cb079a111c/

https://youtu.be/V-s4z7B_Gnc

アプリの状態をどのように保存　&　復元するのがいいのか、ViewModel なしに SavedState を使うにはどうするといいのかについて解説されるセッション。

- Best practice for saving UI state
    - ViewModel
        - In Memory
        - Configuration changes では保持される
        - Read / Write が高速
        - Navigation でバックスタックの VM も保持される
    - Persistent Storage(DataStore & Room)
        - I/O操作で遅い
        - ビジネスの要件次第ではあるが基本は UI の状態ではなくてアプリのデータを保存する
    - Saved State
        - Configuration changes やアプリの一時的な開放から復帰可能
        - 50KB の Bundle のサイズ制限がある
        - Read / Write は Serialize 化するときは遅い
        - スクロール位置やユーザの入力内容の保持がよくあるユースケース
        - UI logic の保存
            - `rememberSaveable` や `onSaveInstanceState`
            - `StateRestorationTester` や `ActivityScenario.recreate()` でテスト可能
        - Business logic の保存
            - ViewModel の `SavedStateHandle`
            - Activity が stop した時に書き込まれる
            - アプリが BG にいる時に更新されたものは復元されない
- Under the hoood and advanced use cases
    - 独自のクラスから SavedState を使う場合
        - Compose
            - `rememberSavable`
                - Saver を実装して初期値として保存している状態を復元させる
        - View
            - 保存させるクラスに `SavedStateRegistry.SavedStateProvider` を実装する
            - 保存させるクラスに `SavedStateRegistryOwner` を渡してライフサイクルで復元処理を実装する
            - そのクラスを Fragment などで初期化(`State(this@Fragment)`)する
    - `rememberSaveableValues` のライフサイクルを制御する
        - デフォルトでは保存イベントが発生する前に UI がコンポジションにあれば復元される
        - Compose の場合は `SavableStateRegistry` + `SaveableStateHolder` & `SaveableStateProvider`
            - `SavableStateRegistry` は Android 固有のものではない
            - Android の時は `DisposableSavableStateRegistry` を介して `SavedStateRegistry` に接続される
        - `rememberSaveableStateHolder()` で `SaveableStateHolder` & `SaveableStateProvider` のインスタンスを取得でき、コンポジションの中で制御したい時に使用する
        - `rememberSavable` の中では `LocalSaveableStateRegistry` を使って復元しているので、Registry を任意のタイミングで差し替えることで保存期間を制御できる
        - navigation-compose はこの仕組みを使って `rememberSaveable` のライフサイクルをコントロールしている
    - https://developer.android.com/topic/libraries/architecture/saving-states
		
	
## What’s new in Material Design

https://io.google/2023/program/630ffaa3-9b3d-4e30-a89f-91ef3e8052cf/

https://youtu.be/vnDhq8W98O4

Material Design 3 の今後の更新内容や、Material 3 はどのようなコンセプトでできたのかを解説しているセッション。
Material 3 で影がなくなり、これまでの紙とペンはどこへいったのかについても軽く触れられています。


- Material Design は美しく使いやすいプロダクトを構築するための Design Language
- Android のエコシステムは基盤として Material Design を使う
- Compose material 3 1.1 が Stable
    - Date / Time Picker の追加などフィードバックをもらって対応進めている
- 新しく Carousel のコンポーネントが登場
- Predictive back の改善
- Material 3 の背景
    - 紙はたくさん重なりすぎるので違う素材を探した
    - デバイスと体験を真にパーソナルなものに感じられるようにした
    - Color や Typography を変革した
    - Shape は常に同じ形である必要がなくモーションされる
    - 全てはスケーラブルでパーソナライズ
- Material3 では Easing 等の動きが Material 2 比較でスムーズになる
- Dynamic Color のアップデート
    - Color Fidelity
        - 再度が高い色を使用しても一致しやすいSchemeを生成できる
        - ![9a92f575a45244a1a65e2942cb2e3fa2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/02d0e182-6665-f772-a9ac-5543e515a9dd.png)
    - Content-based Dynamic Color
        - コンテンツごとの Dynamic color
        - ![52574239ec2741669c8c55413128eaca.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/16d3877f-f02d-0651-1362-f7e7ce3abc2a.png)
    - Contrast Schemes 
        - A11y とパーソナライゼーション
        - ![274a7a1888a042e48c57f3a176d3ca8c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/163aaac9-e053-c142-989e-81968350ea30.png)
    - Monochrome
        - モノクロのバリアントでColor Schemeをカスタマイズできる機能
        - ![136f67e7dbaf4ef38d77028215cc8657.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/71ad366b-676e-caac-edb6-4f135501627b.png)
- Relay は Figma のコンポーネントを Composable にハンドオフできる一例
- Material Design を使うことで優れているのはトークンを操作して Semantic にデザインできる
	

## What's new in Android Accessibility

https://io.google/2023/program/dc29f421-2842-4838-bd87-1ac50f1ac00a/

https://youtu.be/w1Fqx_2SRro

ここ最近の Accessibility に関する更新や実装時のベストプラクティスが紹介されているセッション。

- Talkback
    - 読み上げコントロールにアクションが追加
        - Talkback 13.1 以降
        - 入力欄にフォーカスしているときにアクションによるコピーやペーストや、Gmailでのメールのアーカイブや削除
    - 分割タップ入力
        - Talkback 13.1 ＆Android 13 以降
        - 画面から指を離さずにソフトウェアキーボードを使用しての入力
    - Spell check
        - Talkback 13.1 以降
        - アクションから提案されているスペルの修正を適用できる
    - 点字ディスプレイの対応言語の追加
        - +38 言語
        - Talkback 14 で NLS eReader 対応や点字コマンドでコピーやペーストなどのアクションを行えるようになる
    - スクリーン点字キーボード
        - Talkback 14 以降
        - タッチスクリーンを利用して点字を入力できる
- Reading Mode
    - 読書体験を改善できるモードで Theme や Font の調整が可能
- Hearing
    - Android 14 で補聴機能に改良を加えている
    - Hearing aids experiences
        - 補聴器の操作や接続がより直感的になる
    - Notification on system
        - 振動や音で通知する以外にフラッシュや画面点灯で通知する
    - Live Caption
        - オフラインでデバイス上でリアルタイムにキャプション音声を再生する
        - 電話の応対をテキストで行う機能
- Android 14 の Accessibility の改善点
    - Non-scaling font scale
        - テキストサイズの変更が反映されることと、テキストが切れたり非表示にならないことを確認する
- 新しい Accessibility の API
    - `accessibilityDataSensitive`
        - API 34~
        - パスワードなどの機密データを保護する API
        - 送金ボタンに使うことで不当なアクションを防ぐこともできる
            - 例えば送金の金額入力欄と送信ボタンに適用することで Talkback 時には隠すことができる
    - `setRequestInitialAccessibilityFocus`
        - ウィンドウが最初に表示される時のフォーカスを要求できる API
            - リストと FAB がある時に FAB を先にフォーカスを当てることができる
            - 一般的にはフォーカスの順序はアプリ間での一貫性の面から変えない方がいい
    - `setMinDurationBetweenContentChangesMillis`
        - Talkback のアナウンス頻度の調整をする API
        - 例えばタイマーの時間の読み上げを 10 秒おきにできる
        - 動画のバーや頻繁に更新される View に使うことを検討できる
        - Talkback 14 以降でサポートされる
    - これらの API の Compose 対応は今後進めていく
- ATF (Accessibility Test Framework)の Compose 対応
- Compose
    - UnitTest で `AccessibilityChecks.enable()` で A11y のテストを有効にできるようにする予定
        - `.setRunChecksFromRootView(true)`で全体のチェックも可能
    - Compose 1.4 でフォーカス順序のアルゴリズムを改善した
        - ツリー構造ではなくサイズと位置で行うようになった
- Resource
    - Wear OS での A11y のガイドを公開
        - https://developer.android.com/training/wearables/accessibility
    - Accessibility の API のベストプラクティスのコードサンプル
        - https://github.com/android/platform-samples/tree/main/samples/accessibility