※本記事は「開発者向けオプションを使いこなせ」をとても参考にさせてもらっています。
執筆者の@NUmeroDevさん、ありがとうございます。
本記事では、「開発者向けオプションを使いこなせ」で紹介されている開発者オプションを、adb経由から使う方法を紹介します。
各項目の説明については、元記事をご参照ください。
標準設定アプリが閉じられてしまっている環境や、自動テストなどのために使って貰えればと思います。
本記事の動作確認およびソースコードの確認は、Android 10で行っています。
スリープモードにしない
# ON
$ adb shell settings put global stay_on_while_plugged_in 7
# OFF
$ adb shell settings put global stay_on_while_plugged_in 0
ちなみにONのときの7は、BATTERY_PLUGGED_AC(1)
とBATTERY_PLUGGED_USB(2)
とBATTERY_PLUGGED_WIRELESS(4)
のORで、
「何らかの方法で充電しているとき」という意味です。
実行中のサービス
そのものズバリではないですが、
メモリ使用量の概要は、dumpsys meminfo
で、
processとserviceの関係はdumpsys activity processes
で確認することができます。
システム UI デモモード
システムUIデモモードを有効・表示するときは、adb経由だと少し複雑で、下記の流れになります。
# 「デモモードを有効にする」ON
adb shell settings put global sysui_demo_allowed 1
# systemuiにデモモード開始を通知
adb shell am broadcast -a com.android.systemui.demo --es command enter
# 時計の表示内容を設定
adb shell am broadcast -a com.android.systemui.demo --es command clock --es hhmm 1000
# ネットワーク状態の表示内容を設定
adb shell am broadcast -a com.android.systemui.demo --es command network \
--es wifi show --es mobile show --es sims 1 \
--es nosim false --es level 4 --es datatype lte
adb shell am broadcast -a com.android.systemui.demo --es command network --es fully true
# 電源状態の表示内容を設定
adb shell am broadcast -a com.android.systemui.demo --es command battery --es level 100 --es plugged false
# 各種アイコンを非表示に設定
adb shell am broadcast -a com.android.systemui.demo --es command status \
--es volue hide --es bluetooth hide --es location hide --es alarm hide \
--es zen hide --es sync hide --es tty hide --es eri hide --es mute hide \
--es speakerphone hide --es managed_profile hide
# 通知アイコンを非表示に設定
adb shell am broadcast -a com.android.systemui.demo --es command notifications --es visible false
# 「デモモードを表示」ON
adb shell settings put global sysui_tuner_demo_on 1
システムUIデモモードを終了し、もとの表示に戻すときは、下記の流れです。
# systemuiにデモモード終了を通知
adb shell am broadcast -a com.android.systemui.demo --es command exit
# 「デモモードを表示」OFF
adb shell settings put global sysui_tuner_demo_on 0
# 「デモモードを有効にする」OFF
$ adb shell settings put global sysui_demo_allowed 0
デモモードの開始終了時の実装は、frameworks/base/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
にあります。
実装を読んでみると、実はデモモードで表示される時刻が、Android Version % 24
だということがわかったりします。
※「開発者向けオプションを使いこなせ」のスクリーンショットでは10時になっているので、Android O、ということですね。
intentのextra fieldに何を渡すかで、何を表示するかを変えることもできます。
クイック設定開発者用タイル
# 「レイアウト境界を表示」をクイック設定タイルに表示
adb shell pm enable 'com.android.settings/.development.qstile.DevelopmentTiles\$ShowLayout'
adb shell cmd statusbar add-tile 'com.android.settings/.development.qstile.DevelopmentTiles\$ShowLayout'
# 「レイアウト境界を表示」をON
adb shell cmd statusbar click-tile 'com.android.settings/.development.qstile.DevelopmentTiles\$ShowLayout'
# 「レイアウト境界を表示」をクイック設定タイルから削除表示
adb shell cmd statusbar add-tile 'com.android.settings/.development.qstile.DevelopmentTiles\$ShowLayout'
adb shell pm enable 'com.android.settings/.development.qstile.DevelopmentTiles\$ShowLayout'
その他の項目に対応するComponentNameは以下の通りです。
Settings項目 | ComponentName |
---|---|
レイアウト境界を表示 | ShowLayout |
HWUIレンダリングのプロファイル作成 | GPUProfiling |
RTLレイアウト方向を使用 | ForceRTL |
ウィンドウアニメスケール | AnimationSpeed |
ウィンスコープトレース | WinscopeTrace |
センサーOFF | SensorsOff |
タップを表示
# ON
adb shell settings put system show_touches 1
# OFF
adb shell settings put system show_touches 0
レイアウトの境界を表示
# ON
adb shell setprop debug.layout true
adb shell am restart
# OFF
adb shell setprop debug.layout false
adb shell am restart
setpropしたあとで立ち上げたactivityに対して、レイアウトの境界が表示されます。
そのため、system UIなども含めて設定が反映されるよう、am restart
を呼んでいます。
開発者メニューから変更した場合は、ViewRootImpl#invalidateWorld()
を呼び出すことで即時反映しているようですが、
同等の処理をCUIから呼び出す方法は見つかりませんでした。
クイック設定パネルが使える環境であれば、前述のcmd statusbar click-tile
でも同じことがam restart
なしで実現できます。
最小幅
# 最小幅を320dpにする
adb shell wm size 320dpx640dp
# 最小幅をデフォルトに戻す
adb shell wm size reset
端末の最小幅は、wm size
コマンドで変更ができます。
GUIとは違い、幅だけでなく高さも指定する必要があります。
wm size
を引数なしで実行することで、縦横のピクセル数がわかるので、縦横比を合わせて高さも指定してあげましょう。
また、GUIとは違って320dp以上といった制約もないので、極端に小さな値を試すことも可能です。
(そのような端末はないことになっているので、試す必要もないはずですが)
ディスプレイ カットアウト
# 右上ノッチ
adb shell cmd overlay enable-exclusive com.android.internal.display.cutout.emulation.corner
# 上下中央ノッチ
adb shell cmd overlay enable-exclusive com.android.internal.display.cutout.emulation.double
# 上部中央ノッチ
adb shell cmd overlay enable-exclusive com.android.internal.display.cutout.emulation.tall
# デフォルトに戻す
# adb shell cmd listで有効になっているpackage名を確認し、無効にする
adb shell cmd disable com.android.internal.display.cutout.emulation.tall
GPUオーバードローをデバッグ
# オーバードロー領域を表示
adb shell setprop debug.hwui.overdraw show
# 非表示
adb shell getprop debug.hwui.overdraw false
フォースダークのオーバーライド
# ON
adb shell setprop debug.hwui.force_dark true
# OFF
adb shell setprop debug.hwui.force_dark false
色空間シミュレート
# 色空間シミュレートを有効にする
adb shell settings put secure accessibility_display_daltonizer_enabled 1
# Monochromacy (1色覚)
adb shell settings put secure accessibility_display_daltonizer 0
# Protanomaly (1型3色覚)
adb shell settings put secure accessibility_display_daltonizer 1
# Deuteranomaly (2型3色覚)
adb shell settings put secure accessibility_display_daltonizer 2
# Tritanomaly (3型3色覚)
adb shell settings put secure accessibility_display_daltonizer 3
# 色空間シミュレートを無効にする
adb shell settings put secure accessibility_display_daltonizer_enabled 0
アクティビティを保持しない
# ON
adb shell settings put global always_finish_activities 1
adb shell am restart
# OFF
adb shell settings put global always_finish_activities 0
adb shell am restart
adbからの実行方法の調べ方
上記以外の開発者オプションをadbから変更したくなったときのために、上記を調べた方法も記載しておきます。
1. SettingsService
dumpsys settings
にて、SettingsServiceが保持する現時点の全項目の設定値と、変更履歴を確認できます。
Settingsアプリによって変更される設定値は、ここに保存されることが多いです。
一度実際に変えてみて、変更履歴を確認することで、簡単に対応するkeyの名前を確認できます。
また、このとき対象の設定項目のNAMESPACEも確認することができます。
例えば、下記の出力例でいうと、stay_on_while_plugged_in
は"GLOBAL SETTINGS"の中にあるので、
NAMESPACEが"GLOBAL"だとわかります。
$ adb shell dumpsys settings | grep -v '^_id'
CONFIG SETTINGS (user 0)
Historical operations
1970-01-01 04:02:37 persist
1970-01-01 04:02:37 update intelligence_bubbles/intelligence_bubbles_webref_superpacks_manifest_version
GLOBAL SETTINGS (user 0)
Historical operations
1970-01-01 05:53:17 persist
1970-01-01 05:53:16 update stay_on_while_plugged_in
SECURE SETTINGS (user 0)
Historical operations
1970-01-01 02:23:07 persist
1970-01-01 02:23:07 update zen_settings_updated
SYSTEM SETTINGS (user 0)
Historical operations
1970-01-01 00:53:40 persist
1970-01-01 00:53:39 update screen_off_timeout
keyがわかれば、実際に設定を変化させて、dumpsys settings
で値を確認することができます。
value:
に表示されているのが、設定値です。
# 「スリープモードにしない」を無効にしているとき
$ adb shell dumpsys settings | grep '^_id' | grep stay_on_while_plugged_in
_id:210 name:stay_on_while_plugged_in pkg:com.android.settings value:0 default:0 defaultSystemSet:true
# 「スリープモードにしない」を有効にしているとき
$ adb shell dumpsys settings | grep '^_id' | grep stay_on_while_plugged_in
_id:211 name:stay_on_while_plugged_in pkg:com.android.settings value:7 default:7 defaultSystemSet:true
NAMESPACE, key, valueがわかれば、adbから設定値を更新してみましょう。
$ adb shell settings put global stay_on_while_plugged_in 7
$ adb shell settings put global stay_on_while_plugged_in 0
2. Intent
設定アプリは設定値の変更だけでなくIntentを投げている可能性があります。(例:「システムUIデモモード」)
dumpsys activity broadcasts
で送出されるIntentのactionを確認して、実装を確認するとよいです。
3. System Property
System Propertyを変更している場合もあります。(例:「レイアウトの境界を表示」)
4. 実装を確認する
こう言っては元も子もないですが、結局Settingsアプリをどう実装するかで、設定項目の保存先はいかようにもできてしまいます。
-
- 3.を見ても変化が見つからない場合は、さっさと実装を見たほうが早いです。
デバッグ機能を有効にしているだけなので、そんなに複雑な実装ではないはずです。
- 3.を見ても変化が見つからない場合は、さっさと実装を見たほうが早いです。
「最小幅」の場合は、Settingsアプリのレイアウトで対応する要素がDensityPreference
という独自実装になっており、
その中でWindowManager
に処理を委譲していました。
<com.android.settings.display.DensityPreference
android:key="density"
android:title="@string/developer_smallest_width" />
@Override
protected void onDialogClosed(boolean positiveResult) {
if (positiveResult) {
try {
final Resources res = getContext().getResources();
final DisplayMetrics metrics = res.getDisplayMetrics();
final int newSwDp = Math.max(Integer.parseInt(getText()), 320);
final int minDimensionPx = Math.min(metrics.widthPixels, metrics.heightPixels);
final int newDensity = DisplayMetrics.DENSITY_MEDIUM * minDimensionPx / newSwDp;
final int densityDpi = Math.max(newDensity, 120);
DisplayDensityUtils.setForcedDisplayDensity(Display.DEFAULT_DISPLAY, densityDpi);
} catch (Exception e) {
// TODO: display a message instead of silently failing.
Slog.e(TAG, "Couldn't save density", e);
}
}
}
public static void setForcedDisplayDensity(final int displayId, final int density) {
final int userId = UserHandle.myUserId();
AsyncTask.execute(() -> {
try {
final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
wm.setForcedDisplayDensityForUser(displayId, density, userId);
} catch (RemoteException exc) {
Log.w(LOG_TAG, "Unable to save forced display density setting");
}
});
}