blob: 5e06541ccb9da3cc73d67f4d7c9a1d5cbde88221 [file] [log] [blame]
// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"fmt"
"os"
"sort"
"strconv"
"github.com/olekukonko/tablewriter"
"v.io/x/lib/cmdline"
)
// TODO(youngseokyoon): add a helper command that wraps "madb exec shell pm list users" to show all available users.
var cmdMadbUser = &cmdline.Command{
Children: []*cmdline.Command{cmdMadbUserSet, cmdMadbUserUnset, cmdMadbUserList, cmdMadbUserClearAll},
Name: "user",
DontInheritFlags: true,
Short: "Manage default user settings for each device",
Long: `
Manages default user settings for each device.
An Android device can have multiple user accounts, and each user account has a numeric ID associated
with it. Certain adb commands accept '--user <user_id>' as a parameter to allow specifying which of
the Android user account should be used when running the command. The default behavior when the
user ID is not provided varies by the adb command being run.
Some madb commands internally run these adb commands which accept the '--user' flag. You can let
madb use different user IDs for different devices by storing the default user ID for each device
using 'madb user set' command. If the default user ID is not set for a particular device, madb will
not provide the '--user' flag to the underlying adb command, and the current user will be used for
that device as a result.
Below is the list of madb commands which are affected by the default user ID settings:
madb clear-data
madb install
madb start
madb stop
madb uninstall
For more details on how to obtain the user ID from an Android device, see 'madb user help set'.
`,
}
var cmdMadbUserSet = &cmdline.Command{
Runner: subCommandRunnerWithFilepath{runMadbUserSet, getDefaultConfigFilePath},
Name: "set",
Short: "Set a default user ID to be used for the given device.",
Long: `
Sets a default user ID to be used for the specified device, when there are multiple user accounts on
a single device.
The user IDs can be obtained using the 'adb [<device_serial>] shell pm list users' command.
Alternatively, you can use 'madb exec' if you want to specify the device with a nickname.
For example, running the following command:
madb -n=MyPhone exec shell pm list users
will list the available users and their IDs on the MyPhone device.
Consider the following example output:
[MyPhone] Users:
[MyPhone] UserInfo{0:John Doe:13} running
[MyPhone] UserInfo{10:Work profile:30} running
There are two available users, "John Doe" and "Work profile". Each user is assigned a "user ID",
which appears on the left of the user name. In this case, the user ID of "John Doe" is "0", and the
user ID of the "Work profile" is "10".
To use the "Work profile" as the default user when running madb commands on this device, run the
following command:
madb user set MyPhone 10
and then madb will use "Work profile" as the default user for device "MyPhone" in any of the
subsequence madb commands.
`,
ArgsName: "<device_serial> <user_id>",
ArgsLong: `
<device_serial> is the unique serial number for the device, which can be obtained from 'adb devices'.
<user_id> is one of the user IDs obtained from 'adb shell pm list users' command.
`,
}
func runMadbUserSet(env *cmdline.Env, args []string, filename string) error {
// Check if the arguments are valid.
if len(args) != 2 {
return fmt.Errorf("There must be exactly two arguments.")
}
// TODO(youngseokyoon): make it possible to specify the device using its nickname or index.
// Validate the device serial
serial := args[0]
if !isValidSerial(serial) {
return fmt.Errorf("Not a valid device serial: %v", serial)
}
// Validate the user ID.
userID := args[1]
if id, err := strconv.Atoi(userID); err != nil || id < 0 {
return fmt.Errorf("Not a valid user ID: %v", userID)
}
cfg, err := readConfig(filename)
if err != nil {
return err
}
// Add the <device_serial, user_id> mapping for the specified device.
cfg.UserIDs[serial] = userID
return writeConfig(cfg, filename)
}
var cmdMadbUserUnset = &cmdline.Command{
Runner: subCommandRunnerWithFilepath{runMadbUserUnset, getDefaultConfigFilePath},
Name: "unset",
Short: "Unset the default user ID set by the 'madb user set' command.",
Long: `
Unsets the default user ID assigned by the 'madb user set' command for the specified device.
Running this command without any device specifiers will unset the default users only for the
currently available devices and emulators, while keeping the default user IDs for the other devices.
`,
ArgsName: "<device_serial>",
ArgsLong: `
<device_serial> is the unique serial number for the device, which can be obtained from 'adb devices'.
`,
}
func runMadbUserUnset(env *cmdline.Env, args []string, filename string) error {
// Check if the arguments are valid.
if len(args) != 1 {
return fmt.Errorf("There must be exactly one argument.")
}
// TODO(youngseokyoon): make it possible to specify the device using its nickname or index.
// Validate the device serial
serial := args[0]
if !isValidSerial(serial) {
return fmt.Errorf("Not a valid device serial: %v", serial)
}
cfg, err := readConfig(filename)
if err != nil {
return err
}
delete(cfg.UserIDs, serial)
return writeConfig(cfg, filename)
}
var cmdMadbUserList = &cmdline.Command{
Runner: subCommandRunnerWithFilepath{runMadbUserList, getDefaultConfigFilePath},
Name: "list",
Short: "List all the existing default user IDs.",
Long: `
Lists all the currently stored default user IDs for devices.
`,
}
func runMadbUserList(env *cmdline.Env, args []string, filename string) error {
cfg, err := readConfig(filename)
if err != nil {
return err
}
tw := tablewriter.NewWriter(os.Stdout)
tw.SetHeader([]string{"Serial", "User ID"})
tw.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
tw.SetAutoFormatHeaders(false)
tw.SetAlignment(tablewriter.ALIGN_LEFT)
data := make([][]string, 0, len(cfg.UserIDs))
for serial, userID := range cfg.UserIDs {
data = append(data, []string{serial, userID})
}
sort.Sort(byFirstElement(data))
for _, row := range data {
tw.Append(row)
}
tw.Render()
return nil
}
var cmdMadbUserClearAll = &cmdline.Command{
Runner: subCommandRunnerWithFilepath{runMadbUserClearAll, getDefaultConfigFilePath},
Name: "clear-all",
Short: "Clear all the existing default user settings.",
Long: `
Clears all the currently stored default user IDs for devices.
This command clears the default user IDs regardless of whether the device is currently connected or not.
`,
}
func runMadbUserClearAll(env *cmdline.Env, args []string, filename string) error {
cfg, err := readConfig(filename)
if err != nil {
return err
}
cfg.UserIDs = make(map[string]string)
return writeConfig(cfg, filename)
}