blob: 3c13c2f6a2e8ef4e8dcc5d407ff719e886fcc892 [file] [log] [blame]
// Copyright 2020 The Fuchsia 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 (
"context"
"flag"
"fmt"
"strings"
"github.com/google/subcommands"
fg "go.fuchsia.dev/fuchsia/tools/femu-control/femu-grpc"
"go.fuchsia.dev/fuchsia/tools/lib/logger"
)
type keyboardCmd struct {
eventType string
keySequence []string
}
func (*keyboardCmd) Name() string { return "keyboard" }
func (*keyboardCmd) Synopsis() string { return "Send keyboard events" }
func (*keyboardCmd) Usage() string {
return `keyboard: Send keyboard event to FEMU.
Usage:
keyboard [-type DOWN|UP|PRESS] <key_sequence>
<key_sequence> is a string of key names concatenanted by character '+'.
Order of keys represents the order they are pressed on the keyboard.
Examples:
"A"
"Enter"
"Control+Alt+F3"
"Meta+Z"
Flags:
`
}
func (c *keyboardCmd) SetFlags(f *flag.FlagSet) {
f.StringVar(&c.eventType, "event", "PRESS", "keyboard event type: DOWN, UP or PRESS")
}
func (c *keyboardCmd) ValidateArgs() error {
if len(c.keySequence) == 0 {
return fmt.Errorf("key sequence missing")
}
switch c.eventType {
case "DOWN", "UP", "PRESS":
break
default:
return fmt.Errorf("unknown event type: %s", c.eventType)
}
return nil
}
func (c *keyboardCmd) run(ctx context.Context) error {
client := ctx.Value("client").(fg.FemuGrpcClientInterface)
if client == nil {
return fmt.Errorf("FEMU gRPC client not found")
}
var err error
switch c.eventType {
case "DOWN":
err = client.KeyDown(c.keySequence)
case "UP":
err = client.KeyUp(c.keySequence)
case "PRESS":
err = client.KeyPress(c.keySequence)
}
if err != nil {
return fmt.Errorf("FEMU gRPC client error: %v", err)
}
return nil
}
func (c *keyboardCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
if f.Arg(0) != "" {
c.keySequence = strings.Split(f.Arg(0), "+")
}
if err := c.ValidateArgs(); err != nil {
logger.Errorf(ctx, err.Error())
return subcommands.ExitUsageError
}
if err := c.run(ctx); err != nil {
logger.Errorf(ctx, err.Error())
return subcommands.ExitFailure
}
return subcommands.ExitSuccess
}