1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
//
// ubuntu-emu - Tool to download and run Ubuntu Touch emulator instances
//
// Copyright (c) 2013 Canonical Ltd.
//
// Written by Sergio Schvezov <sergio.schvezov@canonical.com>
//
package main
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License version 3, as published
// by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranties of
// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. If not, see <http://www.gnu.org/licenses/>.
import (
"errors"
"fmt"
"os"
"os/exec"
"path"
"path/filepath"
)
type RunCmd struct {
Skin string `long:"skin" description:"Select skin/emulator type"`
KernelCmd string `long:"kernel-cmdline" description:"Replace kernel cmdline"`
Memory string `long:"memory" description:"Set the device memory"`
Scale string `long:"scale" description:"Scale the emulator size"`
Recovery bool `long:"recovery" description:"Boot into recovery"`
}
var runCmd RunCmd
const (
defaultMemory = "512"
defaultScale = "1.0"
defaultSkin = "EDGE"
installPath = "/usr/share/android/emulator"
subpathEmulatorCmd = "out/host/linux-x86/bin/emulator"
)
var skinDirs = []string{
"skins",
"/usr/share/ubuntu-emulator/skins",
"/usr/share/android/emulator/development/tools/emulator/skins",
}
var extendedRunHelp string = "Runs a new emulator instance name 'name' which " +
"was previously created. If the ANDROID_BUILD_TOP envionment variable is " +
"found, used during Android side development, the emulator runtime will " +
"be executed from there if possible. ANDROID_BUILT_TOP is set after an " +
"android 'lunch' target is selected."
func init() {
runCmd.Skin = defaultSkin
runCmd.Scale = defaultScale
runCmd.Memory = defaultMemory
parser.AddCommand("run",
"Run emulator instance named 'name'",
extendedRunHelp,
&runCmd)
}
func (runCmd *RunCmd) Execute(args []string) error {
if len(args) != 1 {
return errors.New("Instance name 'name' is required")
}
instanceName := args[0]
dataDir := getInstanceDataDir(instanceName)
if instanceExists(dataDir) != true {
return errors.New(fmt.Sprintf("This instance does not exist, use 'create %s' to create it", instanceName))
}
skinDir, err := getSkinDir(runCmd.Skin)
if err != nil {
return err
}
device, err := readDeviceStamp(dataDir)
if err != nil {
return err
}
var deviceInfo map[string]string
if d, ok := devices[device]; ok {
deviceInfo = d
} else {
return errors.New("Cannot run specified emulator environment")
}
ramdisk := bootRamdisk
if runCmd.Recovery {
ramdisk = recoveryRamdisk
}
cmdOpts := []string{
"-memory", runCmd.Memory,
"-skindir", skinDir, "-skin", runCmd.Skin,
"-sysdir", dataDir,
"-kernel", filepath.Join(dataDir, kernelName),
"-ramdisk", filepath.Join(dataDir, ramdisk),
"-data", filepath.Join(dataDir, dataImage),
"-system", filepath.Join(dataDir, systemImage),
"-sdcard", filepath.Join(dataDir, sdcardImage),
"-cache", filepath.Join(dataDir, cacheImage),
"-force-32bit", "-no-snapstorage",
"-gpu", "on",
"-scale", runCmd.Scale,
"-no-jni", "-show-kernel", "-verbose",
"-qemu",
}
if cpu, ok := deviceInfo["cpu"]; ok {
cmdOpts = append(cmdOpts, []string{"-cpu", cpu}...)
}
if runCmd.KernelCmd != "" {
cmdOpts = append(cmdOpts, []string{"-append", runCmd.KernelCmd}...)
}
//we need to export ANDROID_PRODUCT_OUT so the emulator command can create the
//correct hardware-qemu.ini
if err := os.Setenv("ANDROID_PRODUCT_OUT", dataDir); err != nil {
return err
}
emulatorCmd := getEmulatorCmd()
cmd := exec.Command(emulatorCmd, cmdOpts...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func getEmulatorCmd() string {
androidTree := os.Getenv("ANDROID_BUILD_TOP")
cmd := path.Join(androidTree, subpathEmulatorCmd)
if fInfo, err := os.Stat(cmd); err == nil && fInfo.Mode()&0111 != 0 {
fmt.Println("Using", cmd, "for the emulator runtime")
return cmd
}
return path.Join(installPath, subpathEmulatorCmd)
}
func getSkinDir(skin string) (string, error) {
for _, skinDir := range skinDirs {
if dir, err := os.Stat(skinDir); err != nil || !dir.IsDir() {
continue
}
skinPath := filepath.Join(skinDir, skin)
if dir, err := os.Stat(skinPath); err != nil || !dir.IsDir() {
continue
}
return skinDir, nil
}
return "", errors.New(fmt.Sprintf("Cannot find skin %s in any directory from path %s", skin, skinDirs))
}
|