android settings命令

键字: android, settings, cmd

20180822 tjy

转载请注明出处

Android 中有一个可执行文件settings,可以使得调试变得方便。
查看settings的代码,会有其他额外发现。

文件位置

 

device-name:/system/bin # ls -l settings
ls -l settings
-rwxr-xr-x 1 root shell 35 2018-08-03 04:17 settings
device-name:/system/bin #

settings用法

 

device-name:/ # settings
settings
Settings provider (settings) commands:
  help
      Print this help text.
  get [--user  | current] NAMESPACE KEY
      Retrieve the current value of KEY.
  put [--user  | current] NAMESPACE KEY VALUE [TAG] [default]
      Change the contents of KEY to VALUE.
      TAG to associate with the setting.
      {default} to set as the default, case-insensitive only for global/secure namespace
  delete NAMESPACE KEY
      Delete the entry for KEY.
  reset [--user  | current] NAMESPACE {PACKAGE_NAME | RESET_MODE}
      Reset the global/secure table for a package with mode.
      RESET_MODE is one of {untrusted_defaults, untrusted_clear, trusted_defaults}, case-insensitive
  list NAMESPACE
      Print all defined keys.
      NAMESPACE is one of {system, secure, global}, case-insensitive

settings list命令

 

device-name:/ # settings list global
settings list global
adb_enabled=1
add_users_when_locked=0
airplane_mode_on=0
airplane_mode_radios=cell,bluetooth,wifi,nfc,wimax
airplane_mode_toggleable_radios=bluetooth,wifi,nfc
assisted_gps_enabled=1
att_wifi_call_enable=0
audio_safe_volume_state=3
auto_time=1
auto_time_zone=1
bluetooth_disabled_profiles=0
bluetooth_on=0
boot_count=5
call_auto_retry=0
captive_portal_mode=1
car_dock_sound=/system/media/audio/ui/Dock.ogg
car_undock_sound=/system/media/audio/ui/Undock.ogg
cdma_cell_broadcast_sms=1
data_roaming0=1
data_roaming=1
default_install_location=0
default_restrict_background_data=0
desk_dock_sound=/system/media/audio/ui/Dock.ogg
desk_undock_sound=/system/media/audio/ui/Undock.ogg
development_settings_enabled=1
device_provisioned=1
dock_audio_media_enabled=1
dock_sounds_enabled=0
dock_sounds_enabled_when_accessbility=0
emergency_affordance_needed=0
emergency_tone=0
heads_up_notifications_enabled=1
lock_sound=/system/media/audio/ui/Lock.ogg
low_battery_sound=/system/media/audio/ui/LowBattery.ogg
low_battery_sound_timeout=0
mobile_data0=1
mobile_data=1
mobile_data_always_on=0
mode_ringer=2
netstats_enabled=1
network_recommendations_enabled=0
package_verifier_enable=1
power_sounds_enabled=1
preferred_network_mode=10
set_install_location=0
stay_on_while_plugged_in=0
subscription_mode=0
theater_mode_on=0
trusted_sound=/system/media/audio/ui/Trusted.ogg
unlock_sound=/system/media/audio/ui/Unlock.ogg
usb_mass_storage_enabled=1
verifier_verify_adb_installs=0
volte_vt_enabled=1
wfc_ims_enabled=0
wfc_ims_mode=1
wifi_display_on=0
wifi_max_dhcp_retry_count=9
wifi_networks_available_notification_on=1
wifi_on=0
wifi_scan_always_enabled=0
wifi_sleep_policy=2
wifi_wakeup_available=0
wifi_wakeup_enabled=1
wireless_charging_started_sound=/system/media/audio/ui/WirelessChargingStarted.ogg

settings put和get

 

device-name:/ # settings get global bluetooth_on
settings get global bluetooth_on
0
device-name:/ # settings put global bluetooth_on 1
settings put global bluetooth_on 1
device-name:/ #

代码位置在frameworks/base/cmds/settings/settings,打开这个文件,发现它是一个shell,调用了cmd命令,cmd命令又在哪里呢?

 

//from http://androidxref.com/8.1.0_r33/xref/frameworks/base/cmds/settings/settings
#!/system/bin/sh
cmd settings "$@"

在frameworks/native/cmds/cmd/cmd.cpp中,代码如下。
cmd通过IServiceManager去实现操作。

通过看代码,cmd -l可以把service都列出来。
cmd settings是通过调用 service settings中的方法来完成的。

 

//from http://androidxref.com/8.1.0_r33/xref/frameworks/native/cmds/cmd/cmd.cpp

int main(int argc, char* const argv[])
{
    signal(SIGPIPE, SIG_IGN);
    sp proc = ProcessState::self();
    // setThreadPoolMaxThreadCount(0) actually tells the kernel it's
    // not allowed to spawn any additional threads, but we still spawn
    // a binder thread from userspace when we call startThreadPool().
    // This is safe because we only have 2 callbacks, neither of which
    // block.
    // See b/36066697 for rationale
    proc->setThreadPoolMaxThreadCount(0);
    proc->startThreadPool();

    sp sm = defaultServiceManager();
    fflush(stdout);
    if (sm == NULL) {
        ALOGW("Unable to get default service manager!");
        aerr << "cmd: Unable to get default service manager!" << endl;
        return 20;
    }

    if (argc == 1) {
        aerr << "cmd: No service specified; use -l to list all services" << endl;
        return 20;
    }

    if ((argc == 2) && (strcmp(argv[1], "-l") == 0)) {
        Vector services = sm->listServices();
        services.sort(sort_func);
        aout << "Currently running services:" << endl;

        for (size_t i=0; i service = sm->checkService(services[i]);
            if (service != NULL) {
                aout << "  " << services[i] << endl;
            }
        }
        return 0;
    }

    Vector args;
    for (int i=2; i service = sm->checkService(cmd);
    if (service == NULL) {
        ALOGW("Can't find service %s", argv[1]);
        aerr << "cmd: Can't find service: " << argv[1] << endl;
        return 20;
    }

    sp cb = new MyShellCallback();
    sp result = new MyResultReceiver();

#if DEBUG
    ALOGD("cmd: Invoking %s in=%d, out=%d, err=%d", argv[1], STDIN_FILENO, STDOUT_FILENO,
            STDERR_FILENO);
#endif

    // TODO: block until a result is returned to MyResultReceiver.
    status_t err = IBinder::shellCommand(service, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, args,
            cb, result);
    if (err < 0) {
        const char* errstr;
        switch (err) {
            case BAD_TYPE: errstr = "Bad type"; break;
            case FAILED_TRANSACTION: errstr = "Failed transaction"; break;
            case FDS_NOT_ALLOWED: errstr = "File descriptors not allowed"; break;
            case UNEXPECTED_NULL: errstr = "Unexpected null"; break;
            default: errstr = strerror(-err); break;
        }
        ALOGW("Failure calling service %s: %s (%d)", argv[1], errstr, -err);
        aout << "cmd: Failure calling service " << argv[1] << ": " << errstr << " ("
                << (-err) << ")" << endl;
        return err;
    }

    cb->mActive = false;
    status_t res = result->waitForResult();
#if DEBUG
    ALOGD("result=%d", (int)res);
#endif
    return res;
}

继续追一下IBinder::shellCommand代码,定义在frameworks/native/libs/binder/Binder.cpp。
后续补充Binder的逻辑。

 

//from http://androidxref.com/8.1.0_r33/xref/frameworks/native/libs/binder/Binder.cpp#65

status_t IBinder::shellCommand(const sp& target, int in, int out, int err,
    Vector& args, const sp& callback,
    const sp& resultReceiver)
{
    Parcel send;
    Parcel reply;
    send.writeFileDescriptor(in);
    send.writeFileDescriptor(out);
    send.writeFileDescriptor(err);
    const size_t numArgs = args.size();
    send.writeInt32(numArgs);
    for (size_t i = 0; i < numArgs; i++) {
        send.writeString16(args[i]);
    }
    send.writeStrongBinder(callback != NULL ? IInterface::asBinder(callback) : NULL);
    send.writeStrongBinder(resultReceiver != NULL ? IInterface::asBinder(resultReceiver) : NULL);
    return target->transact(SHELL_COMMAND_TRANSACTION, send, &reply);
}



作者:tjy_2011
链接:https://www.jianshu.com/p/409bd28ce8b4
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:(Android基础)