Update sdk/platform-tools to version 26.0.0.
[android_tools.git] / sdk / platform-tools / systrace / catapult / devil / devil / android / sdk / gce_adb_wrapper.py
blob71600f40a615a70d913795bbb785321f48b26302
1 # Copyright 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 """Provides a work around for various adb commands on android gce instances.
7 Some adb commands don't work well when the device is a cloud vm, namely
8 'push' and 'pull'. With gce instances, moving files through adb can be
9 painfully slow and hit timeouts, so the methods here just use scp instead.
10 """
11 # pylint: disable=unused-argument
13 import logging
14 import os
15 import subprocess
17 from devil.android import device_errors
18 from devil.android.sdk import adb_wrapper
19 from devil.utils import cmd_helper
21 logger = logging.getLogger(__name__)
24 class GceAdbWrapper(adb_wrapper.AdbWrapper):
26 def __init__(self, device_serial):
27 super(GceAdbWrapper, self).__init__(device_serial)
28 self._Connect()
29 self.Root()
30 self._instance_ip = self.Shell('getprop net.gce.ip').strip()
32 def _Connect(self, timeout=adb_wrapper.DEFAULT_TIMEOUT,
33 retries=adb_wrapper.DEFAULT_RETRIES):
34 """Connects ADB to the android gce instance."""
35 cmd = ['connect', self._device_serial]
36 output = self._RunAdbCmd(cmd, timeout=timeout, retries=retries)
37 if 'unable to connect' in output:
38 raise device_errors.AdbCommandFailedError(cmd, output)
39 self.WaitForDevice()
41 # override
42 def Root(self, **kwargs):
43 super(GceAdbWrapper, self).Root()
44 self._Connect()
46 # override
47 def Push(self, local, remote, **kwargs):
48 """Pushes an object from the host to the gce instance.
50 Args:
51 local: Path on the host filesystem.
52 remote: Path on the instance filesystem.
53 """
54 adb_wrapper.VerifyLocalFileExists(local)
55 if os.path.isdir(local):
56 self.Shell('mkdir -p %s' % cmd_helper.SingleQuote(remote))
58 # When the object to be pushed is a directory, adb merges the source dir
59 # with the destination dir. So if local is a dir, just scp its contents.
60 for f in os.listdir(local):
61 self._PushObject(os.path.join(local, f), os.path.join(remote, f))
62 self.Shell('chmod 777 %s' %
63 cmd_helper.SingleQuote(os.path.join(remote, f)))
64 else:
65 parent_dir = remote[0:remote.rfind('/')]
66 if parent_dir:
67 self.Shell('mkdir -p %s' % cmd_helper.SingleQuote(parent_dir))
68 self._PushObject(local, remote)
69 self.Shell('chmod 777 %s' % cmd_helper.SingleQuote(remote))
71 def _PushObject(self, local, remote):
72 """Copies an object from the host to the gce instance using scp.
74 Args:
75 local: Path on the host filesystem.
76 remote: Path on the instance filesystem.
77 """
78 cmd = [
79 'scp',
80 '-r',
81 '-o', 'UserKnownHostsFile=/dev/null',
82 '-o', 'StrictHostKeyChecking=no',
83 local,
84 'root@%s:%s' % (self._instance_ip, remote)
86 status, _ = cmd_helper.GetCmdStatusAndOutput(cmd)
87 if status:
88 raise device_errors.AdbCommandFailedError(
89 cmd, 'File not reachable on host: %s' % local,
90 device_serial=str(self))
92 # override
93 def Pull(self, remote, local, **kwargs):
94 """Pulls a file from the gce instance to the host.
96 Args:
97 remote: Path on the instance filesystem.
98 local: Path on the host filesystem.
99 """
100 cmd = [
101 'scp',
102 '-p',
103 '-r',
104 '-o', 'UserKnownHostsFile=/dev/null',
105 '-o', 'StrictHostKeyChecking=no',
106 'root@%s:%s' % (self._instance_ip, remote),
107 local,
109 status, _ = cmd_helper.GetCmdStatusAndOutput(cmd)
110 if status:
111 raise device_errors.AdbCommandFailedError(
112 cmd, 'File not reachable on host: %s' % local,
113 device_serial=str(self))
115 try:
116 adb_wrapper.VerifyLocalFileExists(local)
117 except (subprocess.CalledProcessError, IOError):
118 logger.exception('Error when pulling files from android instance.')
119 raise device_errors.AdbCommandFailedError(
120 cmd, 'File not reachable on host: %s' % local,
121 device_serial=str(self))
123 # override
124 def Install(self, apk_path, forward_lock=False, reinstall=False,
125 sd_card=False, **kwargs):
126 """Installs an apk on the gce instance
128 Args:
129 apk_path: Host path to the APK file.
130 forward_lock: (optional) If set forward-locks the app.
131 reinstall: (optional) If set reinstalls the app, keeping its data.
132 sd_card: (optional) If set installs on the SD card.
134 adb_wrapper.VerifyLocalFileExists(apk_path)
135 cmd = ['install']
136 if forward_lock:
137 cmd.append('-l')
138 if reinstall:
139 cmd.append('-r')
140 if sd_card:
141 cmd.append('-s')
142 self.Push(apk_path, '/data/local/tmp/tmp.apk')
143 cmd = ['pm'] + cmd
144 cmd.append('/data/local/tmp/tmp.apk')
145 output = self.Shell(' '.join(cmd))
146 self.Shell('rm /data/local/tmp/tmp.apk')
147 if 'Success' not in output:
148 raise device_errors.AdbCommandFailedError(
149 cmd, output, device_serial=self._device_serial)
151 # override
152 @property
153 def is_emulator(self):
154 return True