Android14の「写真と動画を選択」
Android14で端末中への画像アクセスが「OS側でユーザに画像を選ばせてアプリはその範囲しかアクセスできない」件、
他アプリはどうなのだろうと思って調べてみたらTwitter(X)はまだtargetSdkVersion33で未対応だった。
ThreadsはtargetSdkVersion34で一応対応してるが、古い作りの「アプリ内でギャラリーを表示する」から脱却していなかった。よって権限ダイアログで「写真と動画を選択」を選んだ場合(選択肢のトップなので、多くのユーザがこれを選んでしまうだろう)、その後にOSが提供するダイアログで「アプリがどの画像にアクセスできるか」を選び、さらにアプリ内ギャラリーでもう一度画像を選択する形になる。2回選択するというのが非常にわかりにくい。
その後画像をさらに追加したい場合どうするかというと、投稿作成画面のサムネイルをタップすると再度アプリ内ギャラリーが開くが、この時点ではOSから許可されていないので追加の画像はギャラリーには存在しない。アプリ内ギャラリーに「一部の写真と動画に対して、Threadsによるアクセスを許可しました。」という注意書きがうっすら見えて、その右の管理するボタンを押すと「さらに写真を選択」「設定を変更」の選択肢がある。
「さらに写真を選択」はOSによる画像選択画面からやり直してOSがアプリにアクセス許可する画像を増やして、その後にアプリ内ギャラリーに候補が追加されて、ユーザは再度画像を選ぶ。2回選択するというのが非常にわかりにくい。
「設定を変更」はアプリの権限設定への導線で、「写真と動画へのアクセス」を「常に全て許可」にさせたいのだろう。これを行うとアプリ内ギャラリーには端末中の画像が全て表示され、Android 13までと同様の操作感になる。
権限を一度取得したらアプリから端末上の画像を全部読める、という時代は終わるのだと思う。それはそうだ、公開したい写真を選ぶためだけに、公開したくない写真にまでアプリがアクセスできるのは危険だろう。悪意のあるアプリがウラでどこかにアップロードしていてもユーザは気が付かない。
過去のアプリのUXは、端末上の全てにアクセスできる前提で、端末上の画像を選ぶ画面をアプリ側で作り込んでいた。その画面に、投稿中の画像の順序を変更する機能も持たせていた。
おそらく今後は端末上の画像を選ぶ画面はセキュリティのためにOSに任せるべきで、投稿中の画像の順序を変更する機能は別の場所に設ける必要がある。
あと、OSで選択した画像のUriは権限の種別によりpickなんとかという内容になってしまい、過去のMediaStoreのUriとは異なる。過去のMediaStoreのUriでクエリしても空カーソルが返る。例えば過去のアプリではSAFのDocument Uri をMediaStoreのUriに変換したりしていたが、そういう芸当はもう出来なくなる。
rsync のmanual の"Include/Exclude Pattern Rules" の日本語訳
原文: "Include/Exclude Pattern Rules" section in https://linux.die.net/man/1/rsync
+
、-
などのフィルター・ルールを使ってパターンを指定することで、ファイルをインクルードしたり、除外したりすることができます(上記の「フィルター・ルール」のセクションで紹介されています)。
include/excludeルールはそれぞれ、転送されるファイル名とマッチするパターンを指定します。
これらのパターンにはいくつかの形式があります:
- パターンが/で始まる場合は、ファイル階層の特定の場所に固定され、そうでない場合はパス名の末尾にマッチする。
これは正規表現における先頭の^に似ている。したがって、
/foo
は、トランスファーのroot(グローバルルールの場合)、またはマージファイルのディレクトリ(ディレクトリごとのルールの場合) のいずれかにあるfoo
の名前にマッチします。非限定foo
は、ツリー内のどこでもfoo
の名前にマッチする。これは、アルゴリズムがトップダウンで再帰的に適用されるためである。(訳注:パターン先頭の/
で)アンカーされていないsub/foo
であっても、foo
がsub
という名前のディレクトリの中で見つかった場合、階層内のどのポイントでもマッチする。 転送のルートでマッチするパターンを指定する方法の詳細については、ANCHORING INCLUDE/EXCLUDE PATTERNSのセクションを参照のこと。 - パターンが/で終わっている場合は、ディレクトリにのみマッチし、通常のファイル、シンボリックリンク、デバイスにはマッチしない。
- rsyncは単純な文字列マッチングを行うかワイルドカードマッチングを行うかを、パターンに
*
、?
、[
の3つのワイルドカード文字のいずれかが含まれているかどうかチェックして選択します。 - 単一の
*
はany path componentにマッチするが、スラッシュにマッチしない。 **
を使うとスラッシュを含むanythingにマッチする。?
はスラッシュ以外のany character (1文字) にマッチする。[
は文字クラス指定を開始する。[a-z]
や[[:alpha:]]
のような。- ワイルドカード・パターンでは、バックスラッシュはワイルドカード文字をエスケープするために使うことができるが、ワイルドカードが存在しない場合は文字通りにマッチする。
- パターンが / (末尾の / はカウントしない) または
**
を含む場合、先頭のディレクトリを含む完全なパス名に対してマッチされる。パターンに/
や**
が含まれていない場合は、ファイル名の最後のコンポーネントに対してのみマッチする。(このアルゴリズムは再帰的に適用されるので、full filename
は実際には開始ディレクトリから下のパスのどの部分にもなりうることを思い出してください)。 - 末尾に
dir_name/***
を指定すると、ディレクトリ(dir_name/
が指定されたかのように)とディレクトリ内のすべて(dir_name/**
が指定されたかのように)の両方にマッチします。この動作はバージョン2.6.7で追加された。
element-matrix.juggler.jpの見た目を軽く変えてみる
Matrixの Element-web を動かしている element-matrix.juggler.jpの見た目を軽く変えてみる。 別におしゃれにしたい訳ではなく、Google Safe Browsing の フィッシングサイト誤検知にひっかかってしまったから。 とりあえず素のElement-webと区別できるようにしたい。
config.json
以下のような内容を追加/変更する。
{ (snip…) "defaultCountryCode": "JP", "brand": "juggler.jp Matrix サービス", "branding" :{ "welcome_background_url": "https://matrix-element.juggler.jp/x/bg.jpg", "auth_header_logo_url": "https://matrix-element.juggler.jp/x/logo.png", "auth_footer_links" : [ { "text":"Juggler.jp Matrix サービスについて", "url":"https://tateisu.hatenablog.com/entry/2023/01/20/164203" } ] }, "embedded_pages": { "welcome_url": "https://matrix-element.juggler.jp/x/welcome.html" } }
項目の説明は element-web高s機器にある。 github.com
welcome_url
embedded_pages.welcome_url
にはHTML断片が入ったURLを指定できる。
今回は超シンプルに以下のようなもの。
<br/> <div style="background-color:#fff;padding: 1em;"> <h1>Juggler.jp Matrix サービス<br/>"Element" Web UI</h1> <H3>matrix.juggler.jp を Element Web UI で使う</h3> <ul> <li><a href="https://matrix-element.juggler.jp/#/register">ユーザ登録</a></li> <li><a href="https://matrix-element.juggler.jp/#/login">ログイン</a></li> </ul> <H3>このサイトの説明</h3> <ul> <li><a href="https://tateisu.hatenablog.com/entry/2023/01/20/164203">Juggler.jp Matrix サービスについて</a></li> <li><a href="https://matrix.org/">Powered by Matrix</a></li> </ul> </div>
PostgreSQL 15 で pg_basebackup したデータの復旧テスト
pg_basebackupしたデータからの復旧テスト
バックアップしたデータ
base.tar.gz backup_manifest pg_wal.tar.gz package_versions
- package_versions は
dpkg -l |grep postgres
を記録したもの。 - 残り3つは pg_basebackup が出力したファイル。
package_versionsの内容
rc pgdg-keyring 2018.2 all keyring for apt.postgresql.org ii postgresql-15 15.1-1.pgdg22.04+1 amd64 The World's Most Advanced Open Source Relational Database ii postgresql-client 15+246.pgdg22.04+1 all front-end programs for PostgreSQL (supported version) ii postgresql-client-15 15.1-1.pgdg22.04+1 amd64 front-end programs for PostgreSQL 15 ii postgresql-client-common 246.pgdg22.04+1 all manager for multiple PostgreSQL client versions ii postgresql-common 246.pgdg22.04+1 all PostgreSQL database-cluster manager ii postgresql-contrib 15+246.pgdg22.04+1 all additional facilities for PostgreSQL (supported version) ii postgresql-doc 15+246.pgdg22.04+1 all documentation for the PostgreSQL database management system ii postgresql-doc-15 15.1-1.pgdg22.04+1 all documentation for the PostgreSQL database management system
- postgreSQLは 15.1-1.pgdg22.04+1
- OSバージョンは22.04(ubuntu)
dockerコンテナで復旧テスト
コンテナの起動
$ docker run -v /x/backup/postgres/20230121-050015:/backup:ro --rm -it ubuntu:22.04 bash
OSバージョンの確認
# cat /etc/os-release PRETTY_NAME="Ubuntu 22.04.1 LTS" NAME="Ubuntu" VERSION_ID="22.04" VERSION="22.04.1 LTS (Jammy Jellyfish)" VERSION_CODENAME=jammy ID=ubuntu ID_LIKE=debian HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" UBUNTU_CODENAME=jammy
必要そうなパッケージのインストール
apt update apt install whiptail locales lv nano sudo curl ca-certificates gnupg lsb-release
ロケールの作成
apt update && apt install whiptail locales dpkg-reconfigure locales
バックアップデータの確認とWALアーカイブの展開
# export BACKUP_DIR=/backup # find $BACKUP_DIR -ls # mkdir /walArchive # cd /walArchive # tar xzf $BACKUP_DIR/pg_wal.tar.gz # chmod -R a+rw . # find . -ls
Postgres リポジトリの導入
# curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg # echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list # cat /etc/apt/sources.list.d/pgdg.list
バージョンを指定してインストール
apt update apt-get install postgresql-15=15.1-1.pgdg22.04+1 postgresql-client-15=15.1-1.pgdg22.04+1
インストール中にタイムゾーンを尋ねられる。今回は Asia/Tokyo を指定した。
DB起動/接続のテスト
# service --status-all # service postgresql start # service --status-all (postgresサービスが起動していること) # ps auxwf (プロセス一覧にpostgresが見えること) # lv /var/log/postgresql/postgresql-15-main.log 2023-01-21 10:49:52.237 JST [6265] LOG: starting PostgreSQL 15.1 (Ubuntu 15.1-1.pgdg22.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0, 64-bit 2023-01-21 10:49:52.237 JST [6265] LOG: listening on IPv4 address "127.0.0.1", port 5432 2023-01-21 10:49:52.237 JST [6265] LOG: could not bind IPv6 address "::1": Cannot assign requested address 2023-01-21 10:49:52.242 JST [6265] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" 2023-01-21 10:49:52.249 JST [6268] LOG: database system was shut down at 2023-01-21 10:49:23 JST 2023-01-21 10:49:52.254 JST [6265] LOG: database system is ready to accept connections
接続テスト
# sudo -u postgres psql -c "\\l" List of databases Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges -----------+----------+----------+-------------+-------------+------------+-----------------+----------------------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres + | | | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres + | | | | | | | postgres=CTc/postgres (3 rows)
- OSのデフォルトロケールになっている
DBを止める
# service postgresql stop # ps auxwf (postgresのプロセスが存在しないこと) # lv /var/log/postgresql/postgresql-15-main.log 2023-01-21 10:53:47.786 JST [6265] LOG: received fast shutdown request 2023-01-21 10:53:47.796 JST [6265] LOG: aborting any active transactions 2023-01-21 10:53:47.798 JST [6265] LOG: background worker "logical replication launcher" (PID 6271) exited with exit code 1 2023-01-21 10:53:47.798 JST [6266] LOG: shutting down 2023-01-21 10:53:47.801 JST [6266] LOG: checkpoint starting: shutdown immediate 2023-01-21 10:53:47.830 JST [6266] LOG: checkpoint complete: wrote 43 buffers (0.3%); 0 WAL file(s) added, 0 removed , 0 recycled; write=0.006 s, sync=0.012 s, total=0.033 s; sync files=11, longest=0.003 s, average=0.002 s; distance=2 52 kB, estimate=252 kB 2023-01-21 10:53:47.834 JST [6265] LOG: database system is shut down
データ破損
- DBは止めておく
cd /var/lib/postgresql/15/main/ rm -fr ./*
データの復旧
cd /var/lib/postgresql/15/main/ tar xvfz $BACKUP_DIR/base.tar.gz
restore_command の確認と設定
# grep -rin restore /etc/postgresql/15/main/ ./postgresql.conf:268:#restore_command = '' # command to use to restore an archived logfile segment ./postgresql.conf:269: # placeholders: %p = path of file to restore ./postgresql.conf:282:#recovery_target_name = '' # the named restore point to which recovery will proceed
設定されてないので設定する。
nano /etc/postgresql/15/main/postgresql.conf
CTRL-W を押して restore_command を入力してEnter。 既存の行は変えず、次の行を挿入。
restore_command = 'cp /walArchive/%f %p' archive_cleanup_command = 'pg_archivecleanup /walArchive %r'
CTRL-Oを押してファイル名をかえずにEnterして保存。 CTRL-Xで終了。
起動
service postgresql start
ログの確認
lv /var/log/postgresql/postgresql-15-main.log (snip) 2023-01-21 10:57:04.170 JST [6401] LOG: restored log file "00000001000000770000003B" from archive 2023-01-21 10:57:04.211 JST [6401] LOG: redo starts at 77/3B000028 (snip)
データを読めているか
# sudo -u postgres psql -c "\\l" List of databases Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges -----------+-----------+----------+-------------+-------------+------------+-----------------+----------------------- lemmy | lemmy | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | mastodon2 | mastodon2 | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | mastodon3 | mastodon3 | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | matrix1 | matrix1 | UTF8 | C | C | | libc | misskey11 | misskey11 | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | misskey12 | misskey12 | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres + | | | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres + | | | | | | | postgres=CTc/postgres (9 rows)
この記事に含まれないもの
- /etc/postgresql/15/main/ の復旧。 多分 /etc まるごとバックアップしてると思うので…
matrix.juggler.jp
Juggler.jp Matrix サービスについて
MatrixはOSSのメッセージサービスです。
- 分散型、非中央集権型
- 強力な暗号化機能があります。
Juggler.jp Matrix サービスは以下の2つを提供しています。
- matrix.juggler.jp でMatrixサーバが動いてます。
- https://matrix-element.juggler.jp/ でWebUIを利用できます。
メモ:
導入手順
- ガイド:ElementのPCデスクトップ版をインストールしてアカウントを作って部屋に入るまで https://lemmy.juggler.jp/post/786
matrix.juggler.jp の告知やメンテナンスは?
- 「matrix.juggler.jpのお知らせ」ルーム https://matrix.to/#/#mjj:matrix.juggler.jp
- アクセスできないときはMastodonに何か書くかも https://mastodon.juggler.jp/@tateisu
2023/02/17 フィッシングサイトと偽検出されてしまった件
Google Safe Browsingさんにフィッシングサイトと偽検出されてしまい、各種ブラウザでもページを開くと警告が出るようになってしまいました。
また、警告をスキップした後でもFirefoxだとプラウザの設定を変えないと Element-web と matrix.juggler.jp の間の通信ができません。
Googleへサイトの再審査要求を出して改善を待っている状態です。
2023/01/19 DBロストのお知らせ
matrix.juggler.jp というサービスのDBをロストさせてしまいました…。
DB完全初期化なので、ユーザは新規登録からやりなおしです。
今後はDBバックアップに不備がないよう努めてまいります。
Huawei端末の「デフォルトの保存場所」と externalCacheDir と FileProvider.parsePathStrategy
Huawei端末はデフォルトの保存先をSDカードにすることができる。
私の手元では以下の2機種にその設定があった。
その設定により、context.externalCacheDir は SDカードのパスを返す。
しかし ContextCompat.getExternalCacheDirs(context)[0] はプライマリストレージのパスを返す。
FileProvider#parsePathStrategy が参照するのは後者であり、よってFileProvider経由で外部アプリに公開したいならアプリでも ContextCompat.getExternalCacheDirs(context)[0] を使ってファイル保存を行うべきだ。
結果としてキャッシュデータはプライマリストレージに保存されてユーザの意向は反映されなくなるが、動作しないよりはマシ。
Android Emoji Policy と DefaultEmojiCompatConfig と Playサービス依存の罠
PlayストアでAndroid Emoji Policy なるものが要求されるようになりました。
Developer Program Policy: October 27, 2021 announcement - Play Console Help
「Apps running on Android 12 and above must comply with the latest Unicode version within 4 months of public availability.」
だそうで、Android 12 以上の端末で動作するアプリは最新の絵文字に4ヶ月以内に対応しなければならないそうです。
それに伴い AndroidX AppCompat 1.4.0 と AndroidX Emoji2 1.0.0 がリリースされました。
https://developer.android.com/jetpack/androidx/releases/emoji2 の下の方を見ると以下のようなことが書いてあります。
- appcompat は androidx.emoji2 を依存関係に持つよ。
- androidx.startup を使って EmojiCompatInitializer による自動設定を粉うよ。
- DefaultEmojiCompatConfig を使ってデフォルトのフォントプロバイダーを探すよ。
- 自動初期化を無効にするにはうんぬんかんぬん。
しかし試しにアプリを書いてみると古い端末では13.1の絵文字は表示されません。
コードを読んで原因をみてみましょう。
- androidx.emoji2.text.DefaultEmojiCompatConfigは queryIntentContentProviders(Intent(action="androidx.content.action.LOAD_EMOJI_FONT")) で端末中のContentProviderを探す。
- (providerInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM を満たさないものを除外する。
- com.google.android.gms.fonts だけが残る。
- そのContentProviderと連携して何かする。
バリバリにPlayサービスに依存してますね。当然それなりに新しいPlayサービスが入ってないと自動ロードは働きません。
手元の端末だとXperia 10 III はオッケー、Xperia Z3 Compact はダメでした。
絵文字プロバイダがない場合は EmojiCompat.Config 相当のオブジェクトが生成されず、EmojiCompat.init はまだ呼び出されていない状態になります。
このままだとEmojiTextViewはインスタンス生成時に例外を出します。AppCompatTextViewは端末OSに入ってる絵文字を表示します。
ユーザ体験的には残念ですね。
古い端末向けのワークアラウンド。
- 依存関係にimplementation "androidx.emoji2:emoji2-bundled:$emojiVersion"を追加。
- アプリ初期化や画面初期化の際に EmojiCompat.init(BundledEmojiCompatConfig(applicationContext)) を呼び出す。
すると「まだEmojiCompatが初期化されていなければ」アプリにバンドルした絵文字データが使われるようになります。