ラズベリーパイの起動時に全画面でブラウザを表示したい

## 要約
```shell
sudo apt update
sudo apt install unclutter
```

```conf:browser.service
[Unit]
Description=browser
Wants=display-manager.service
After=display-manager.service

[Service]
User=hoge
Environment=DISPLAY=:0
ExecStartPre=sleep 5
ExecStart=bash -c "unclutter -idle 0.5 -root -display :0 & /usr/bin/chromium-browser --noerrdialogs --disable-infobars --enable-logging --log-level=0 --start-maximized --kiosk https://google.com"

[Install]
WantedBy=multi-user.target
```

```shell
sudo cp browser.service /etc/systemd/system
sudo systemctl daemon-reload
sudo systemctl enable browser.service
```

## 概要
**RaspberryPi**というコンピュータは、いわゆるマイコンの中でも特に有名な部類でしょう。インターフェースも充実していて、最近の機種であれば**HDMIの映像出力**や**Wi-Fiへの接続**、有線LANが繋げるものもあります。それに消費電力も少ないため、常時起動しておくような形でもあまり気になることはありません。

これを使えば、**ダッシュボードや情報源などを常時ディスプレイに表示する**、いわば**デジタルサイネージ**のようなものが簡単に作れるのではないかと想いやってみることにしました。

ディスプレイでの表示方法は、独自アプリを作るとかの選択肢もあるかと思いますが、**Webページを開いておく**というのが一番シンプルで済みそうです。ネットワークに接続しておけば、ブラウザをリロードしたり背後のスクリプトで情報を更新することで、**リアルタイムに表示内容を変化させられます**。

また、データ表示系のライブラリやCSS、WebGLなどの技術で**多様なグラフィック表現**も可能です。何事もブラウザのWebサイトでというのは、今の世の中のサービスの多くを見ても感じる潮流です。

求められる要件としては、**ラズベリーパイの起動時に任意のWebページをブラウザで開く**ことです。できれば、ウィンドの枠やタブなどが見えない**全画面でブラウザを表示**したいです。

## 実装
はじめに**ラズベリーパイの起動時にブラウザを開く**ということを目指します。ブラウザを開くと言っても、要は任意のブラウザソフト（この記事では`Chromium`）をコマンドで実行できればいいです。

起動時のコマンドの実行については、[参考](#参考)に挙げた記事などをもとに、最終的には`systemd`を用いた方法で実装をしました。はじめは`autostart`を使おうと考えていましたが、バージョンの都合かどうもうまく動作しませんでした。

この実装をしていたのが2024年の3月ごろで、その前の2023年10月にRaspberryPi OSの大きめなアップデートがあったようです。それが故でしょうか…。

https://raspida.com/release-rpios-bookworm/

なお、`systemd`自体私はこの開発で初めて実際に設定したもので、まだ稚拙な点もあるのかと思います。より良い形があればぜひコメントなどで教えてください。

### `unclutter`のインストール
実際に`systemd`を設定する前に、使用するツールとして`unclutter`のインストールを行いました。`unclutter`は**マウスカーソルを非表示にするツール**です。全画面表示の際にマウスカーソルが表示されたままだと見栄えが悪いので、このツールで消えるように設定します。

インストールは一般的なツールと同様に`apt`で実行しました。

```shell
sudo apt update
sudo apt install unclutter
```

### `systemd`の設定
本題の`systemd`については、Unitファイルを以下のように記述しました。ここではUnit名を`browser`としてファイル名も`browser.service`にしていますが、この名称は任意です。必要に応じて他のUnit名にし、コマンドも読み替えてください。

```conf:browser.service
[Unit]
Description=browser
Wants=display-manager.service
After=display-manager.service

[Service]
User=hoge
Environment=DISPLAY=:0
ExecStartPre=sleep 5
ExecStart=bash -c "unclutter -idle 0.5 -root -display :0 & /usr/bin/chromium-browser --noerrdialogs --disable-infobars --enable-logging --log-level=0 --start-maximized --kiosk https://google.com"

[Install]
WantedBy=multi-user.target
```

記述内容は私自身も自信を持って理解できている部分が少なかったり、ChatGPTとの問答の末の記述だったりするので、**間違いや無駄な記述もある可能性にご留意ください**。

`Wants=display-manager.service`と`After=display-manager.service`の箇所では、このUnitが依存するUnitを指定しています。今回はGUIでブラウザのウィンドウを開くという処理ですので、先にGUIの環境をセットアップする`display-manager.service`が実行されるのを待っています。

ただそれでもその他のGUI関係のセットアップ処理とのずれが生じてしまうのか、displayが見つからないというようなエラーで起動が失敗してしまいました。そこで、力技ですが**セットアップを待つために`ExecStartPre=sleep 5`というのを設定**しました。ブラウザの起動前に5秒待ち、セットアップの処理と思われるものを待機しています。

そして実際にブラウザを起動するコマンドが`ExecStart=bash -c "unclutter -idle 0.5 -root -display :0 & /usr/bin/chromium-browser --noerrdialogs --disable-infobars --enable-logging --log-level=0 --start-maximized --kiosk https://google.com"`にあたります。

まず、先にインストールした`unclutter`を用い、**一定時間(ここでは0.5秒)マウスが動かなかった場合にカーソルを非表示とする**ようにしています。それが`unclutter -idle 0.5 -root -display :0 &`の部分です。

そしてその後のコマンドでブラウザとして`chromium-browser`を起動しています。開かれるWebページは、最後に指定している`https://google.com`の部分です。ここのURLを書き換えれば任意のサイトを開くことが可能になります。

オプションとして色々指定していますが、特に大事そうなものはChromiumをKioskモードで起動する`--kiosk`、全画面で表示する`--start-maximized`のあたりかと思います。このオプションについても、私自信まだあまり理解できていないところも多くあります。[参考](#参考)にオプションの一覧ページのリンクも載せましたので、こちらも合わせてご参照ください。

### `systemd`への登録と有効化
上記でUnitの定義ファイルが書けたので、これを`systemd`に登録します。以下の手順でファイルを`/etc/systemd/system`以下におき、対象のUnitを有効化させます。

```shell
sudo cp browser.service /etc/systemd/system
sudo systemctl daemon-reload
sudo systemctl enable browser.service
```

これでブラウザの起動が有効化されたので、一度ラズパイを再起動してみます。そうすると、ラズパイの起動後デスクトップが表示されて少しして、ブラウザが表示されるかと思います。

### 実際の動作
実際に動作したものをTwitterの方に動画でアップロードしています。なお、この動画を撮影したタイミングでは、マウスカーソルの非表示が設定できていませんでした🙇

<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">ラズパイ起動時にブラウザを全画面で表示する <a href="https://t.co/S8xJT0qDUh">pic.twitter.com/S8xJT0qDUh</a></p>&mdash; もっちー (@mochi_2225) <a href="https://twitter.com/mochi_2225/status/1811086195449073993?ref_src=twsrc%5Etfw">July 10, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

おそらく`sleep`を設定しているためですが、ブラウザの起動までラグがあるなど、まだまだ改善が必要な箇所もあるのかなと思っています。ただ、最低限、ブラウザを起動し任意のホームページを全画面で表示するといったことはできたのかなと思っています。

## おわりに
主に`systemd`の部分ですが、まだまだ私自身も自信を持って説明の出来かなった内容も多くありました。それらは今後も治してみて、その都度記事の方でも修正・補足していけたらなと思っています。

より良い設定方法がありましたら、ぜひコメントなどでいただければ幸いです。

## 参考

https://qiita.com/karaage0703/items/ed18f318a1775b28eab4

https://qiita.com/flmil/items/d43c6bbeef2ba02aadd0

https://keiaruesu.hatenablog.com/entry/2021/04/21/203648

https://enakai00.hatenablog.com/entry/20130917/1379374797

https://qiita.com/bluesDD/items/eaf14408d635ffd55a18

https://github.com/GoogleChrome/chrome-launcher/blob/main/docs/chrome-flags-for-tools.md

https://peter.sh/experiments/chromium-command-line-switches/