LoginSignup
30
30

More than 3 years have passed since last update.

[Android] 開発者向けオプションをadbから使いこなせ

Last updated at Posted at 2019-10-16

※本記事は「開発者向けオプションを使いこなせ」をとても参考にさせてもらっています。
執筆者の@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アプリをどう実装するかで、設定項目の保存先はいかようにもできてしまいます。

  1. 2. 3.を見ても変化が見つからない場合は、さっさと実装を見たほうが早いです。 デバッグ機能を有効にしているだけなので、そんなに複雑な実装ではないはずです。

「最小幅」の場合は、Settingsアプリのレイアウトで対応する要素がDensityPreferenceという独自実装になっており、
その中でWindowManagerに処理を委譲していました。

packages/apps/Settings/res/xml/development_settings.xml
        <com.android.settings.display.DensityPreference
            android:key="density"
            android:title="@string/developer_smallest_width" />
packages/apps/Settings/src/com/android/settings/display/DensityPreference.java
    @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);
            }
    }
    }
frameworks/base/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
    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");
            }
        });
    }

参考

30
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
30