• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# Copyright 2014 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""
7Unit tests for the contents of device_utils.py (mostly DeviceUtils).
8"""
9
10# pylint: disable=protected-access
11# pylint: disable=unused-argument
12
13import logging
14import unittest
15
16from devil import devil_env
17from devil.android import device_errors
18from devil.android import device_signal
19from devil.android import device_utils
20from devil.android.sdk import adb_wrapper
21from devil.android.sdk import intent
22from devil.android.sdk import version_codes
23from devil.utils import cmd_helper
24from devil.utils import mock_calls
25
26with devil_env.SysPath(devil_env.PYMOCK_PATH):
27  import mock  # pylint: disable=import-error
28
29
30class _MockApkHelper(object):
31
32  def __init__(self, path, package_name, perms=None):
33    self.path = path
34    self.package_name = package_name
35    self.perms = perms
36
37  def GetPackageName(self):
38    return self.package_name
39
40  def GetPermissions(self):
41    return self.perms
42
43
44class DeviceUtilsInitTest(unittest.TestCase):
45
46  def testInitWithStr(self):
47    serial_as_str = str('0123456789abcdef')
48    d = device_utils.DeviceUtils('0123456789abcdef')
49    self.assertEqual(serial_as_str, d.adb.GetDeviceSerial())
50
51  def testInitWithUnicode(self):
52    serial_as_unicode = unicode('fedcba9876543210')
53    d = device_utils.DeviceUtils(serial_as_unicode)
54    self.assertEqual(serial_as_unicode, d.adb.GetDeviceSerial())
55
56  def testInitWithAdbWrapper(self):
57    serial = '123456789abcdef0'
58    a = adb_wrapper.AdbWrapper(serial)
59    d = device_utils.DeviceUtils(a)
60    self.assertEqual(serial, d.adb.GetDeviceSerial())
61
62  def testInitWithMissing_fails(self):
63    with self.assertRaises(ValueError):
64      device_utils.DeviceUtils(None)
65    with self.assertRaises(ValueError):
66      device_utils.DeviceUtils('')
67
68
69class DeviceUtilsGetAVDsTest(mock_calls.TestCase):
70
71  def testGetAVDs(self):
72    mocked_attrs = {
73      'android_sdk': '/my/sdk/path'
74    }
75    with mock.patch('devil.devil_env._Environment.LocalPath',
76                    mock.Mock(side_effect=lambda a: mocked_attrs[a])):
77      with self.assertCall(
78          mock.call.devil.utils.cmd_helper.GetCmdOutput(
79              [mock.ANY, 'list', 'avd']),
80          'Available Android Virtual Devices:\n'
81          '    Name: my_android5.0\n'
82          '    Path: /some/path/to/.android/avd/my_android5.0.avd\n'
83          '  Target: Android 5.0 (API level 21)\n'
84          ' Tag/ABI: default/x86\n'
85          '    Skin: WVGA800\n'):
86        self.assertEquals(['my_android5.0'], device_utils.GetAVDs())
87
88
89class DeviceUtilsRestartServerTest(mock_calls.TestCase):
90
91  @mock.patch('time.sleep', mock.Mock())
92  def testRestartServer_succeeds(self):
93    with self.assertCalls(
94        mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.KillServer(),
95        (mock.call.devil.utils.cmd_helper.GetCmdStatusAndOutput(
96            ['pgrep', 'adb']),
97         (1, '')),
98        mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.StartServer(),
99        (mock.call.devil.utils.cmd_helper.GetCmdStatusAndOutput(
100            ['pgrep', 'adb']),
101         (1, '')),
102        (mock.call.devil.utils.cmd_helper.GetCmdStatusAndOutput(
103            ['pgrep', 'adb']),
104         (0, '123\n'))):
105      device_utils.RestartServer()
106
107
108class MockTempFile(object):
109
110  def __init__(self, name='/tmp/some/file'):
111    self.file = mock.MagicMock(spec=file)
112    self.file.name = name
113    self.file.name_quoted = cmd_helper.SingleQuote(name)
114
115  def __enter__(self):
116    return self.file
117
118  def __exit__(self, exc_type, exc_val, exc_tb):
119    pass
120
121  @property
122  def name(self):
123    return self.file.name
124
125
126class _PatchedFunction(object):
127
128  def __init__(self, patched=None, mocked=None):
129    self.patched = patched
130    self.mocked = mocked
131
132
133def _AdbWrapperMock(test_serial, is_ready=True):
134  adb = mock.Mock(spec=adb_wrapper.AdbWrapper)
135  adb.__str__ = mock.Mock(return_value=test_serial)
136  adb.GetDeviceSerial.return_value = test_serial
137  adb.is_ready = is_ready
138  return adb
139
140
141class DeviceUtilsTest(mock_calls.TestCase):
142
143  def setUp(self):
144    self.adb = _AdbWrapperMock('0123456789abcdef')
145    self.device = device_utils.DeviceUtils(
146        self.adb, default_timeout=10, default_retries=0)
147    self.watchMethodCalls(self.call.adb, ignore=['GetDeviceSerial'])
148
149  def AdbCommandError(self, args=None, output=None, status=None, msg=None):
150    if args is None:
151      args = ['[unspecified]']
152    return mock.Mock(side_effect=device_errors.AdbCommandFailedError(
153        args, output, status, msg, str(self.device)))
154
155  def CommandError(self, msg=None):
156    if msg is None:
157      msg = 'Command failed'
158    return mock.Mock(side_effect=device_errors.CommandFailedError(
159        msg, str(self.device)))
160
161  def ShellError(self, output=None, status=1):
162    def action(cmd, *args, **kwargs):
163      raise device_errors.AdbShellCommandFailedError(
164          cmd, output, status, str(self.device))
165    if output is None:
166      output = 'Permission denied\n'
167    return action
168
169  def TimeoutError(self, msg=None):
170    if msg is None:
171      msg = 'Operation timed out'
172    return mock.Mock(side_effect=device_errors.CommandTimeoutError(
173        msg, str(self.device)))
174
175
176class DeviceUtilsEqTest(DeviceUtilsTest):
177
178  def testEq_equal_deviceUtils(self):
179    other = device_utils.DeviceUtils(_AdbWrapperMock('0123456789abcdef'))
180    self.assertTrue(self.device == other)
181    self.assertTrue(other == self.device)
182
183  def testEq_equal_adbWrapper(self):
184    other = adb_wrapper.AdbWrapper('0123456789abcdef')
185    self.assertTrue(self.device == other)
186    self.assertTrue(other == self.device)
187
188  def testEq_equal_string(self):
189    other = '0123456789abcdef'
190    self.assertTrue(self.device == other)
191    self.assertTrue(other == self.device)
192
193  def testEq_devicesNotEqual(self):
194    other = device_utils.DeviceUtils(_AdbWrapperMock('0123456789abcdee'))
195    self.assertFalse(self.device == other)
196    self.assertFalse(other == self.device)
197
198  def testEq_identity(self):
199    self.assertTrue(self.device == self.device)
200
201  def testEq_serialInList(self):
202    devices = [self.device]
203    self.assertTrue('0123456789abcdef' in devices)
204
205
206class DeviceUtilsLtTest(DeviceUtilsTest):
207
208  def testLt_lessThan(self):
209    other = device_utils.DeviceUtils(_AdbWrapperMock('ffffffffffffffff'))
210    self.assertTrue(self.device < other)
211    self.assertTrue(other > self.device)
212
213  def testLt_greaterThan_lhs(self):
214    other = device_utils.DeviceUtils(_AdbWrapperMock('0000000000000000'))
215    self.assertFalse(self.device < other)
216    self.assertFalse(other > self.device)
217
218  def testLt_equal(self):
219    other = device_utils.DeviceUtils(_AdbWrapperMock('0123456789abcdef'))
220    self.assertFalse(self.device < other)
221    self.assertFalse(other > self.device)
222
223  def testLt_sorted(self):
224    devices = [
225        device_utils.DeviceUtils(_AdbWrapperMock('ffffffffffffffff')),
226        device_utils.DeviceUtils(_AdbWrapperMock('0000000000000000')),
227    ]
228    sorted_devices = sorted(devices)
229    self.assertEquals('0000000000000000',
230                      sorted_devices[0].adb.GetDeviceSerial())
231    self.assertEquals('ffffffffffffffff',
232                      sorted_devices[1].adb.GetDeviceSerial())
233
234
235class DeviceUtilsStrTest(DeviceUtilsTest):
236
237  def testStr_returnsSerial(self):
238    with self.assertCalls(
239        (self.call.adb.GetDeviceSerial(), '0123456789abcdef')):
240      self.assertEqual('0123456789abcdef', str(self.device))
241
242
243class DeviceUtilsIsOnlineTest(DeviceUtilsTest):
244
245  def testIsOnline_true(self):
246    with self.assertCall(self.call.adb.GetState(), 'device'):
247      self.assertTrue(self.device.IsOnline())
248
249  def testIsOnline_false(self):
250    with self.assertCall(self.call.adb.GetState(), 'offline'):
251      self.assertFalse(self.device.IsOnline())
252
253  def testIsOnline_error(self):
254    with self.assertCall(self.call.adb.GetState(), self.CommandError()):
255      self.assertFalse(self.device.IsOnline())
256
257
258class DeviceUtilsHasRootTest(DeviceUtilsTest):
259
260  def testHasRoot_true(self):
261    with self.assertCall(self.call.adb.Shell('ls /root'), 'foo\n'):
262      self.assertTrue(self.device.HasRoot())
263
264  def testHasRoot_false(self):
265    with self.assertCall(self.call.adb.Shell('ls /root'), self.ShellError()):
266      self.assertFalse(self.device.HasRoot())
267
268
269class DeviceUtilsEnableRootTest(DeviceUtilsTest):
270
271  def testEnableRoot_succeeds(self):
272    with self.assertCalls(
273        (self.call.device.IsUserBuild(), False),
274         self.call.adb.Root(),
275         self.call.device.WaitUntilFullyBooted()):
276      self.device.EnableRoot()
277
278  def testEnableRoot_userBuild(self):
279    with self.assertCalls(
280        (self.call.device.IsUserBuild(), True)):
281      with self.assertRaises(device_errors.CommandFailedError):
282        self.device.EnableRoot()
283
284  def testEnableRoot_rootFails(self):
285    with self.assertCalls(
286        (self.call.device.IsUserBuild(), False),
287        (self.call.adb.Root(), self.CommandError())):
288      with self.assertRaises(device_errors.CommandFailedError):
289        self.device.EnableRoot()
290
291
292class DeviceUtilsIsUserBuildTest(DeviceUtilsTest):
293
294  def testIsUserBuild_yes(self):
295    with self.assertCall(
296        self.call.device.GetProp('ro.build.type', cache=True), 'user'):
297      self.assertTrue(self.device.IsUserBuild())
298
299  def testIsUserBuild_no(self):
300    with self.assertCall(
301        self.call.device.GetProp('ro.build.type', cache=True), 'userdebug'):
302      self.assertFalse(self.device.IsUserBuild())
303
304
305class DeviceUtilsGetExternalStoragePathTest(DeviceUtilsTest):
306
307  def testGetExternalStoragePath_succeeds(self):
308    with self.assertCall(
309        self.call.adb.Shell('echo $EXTERNAL_STORAGE'), '/fake/storage/path\n'):
310      self.assertEquals('/fake/storage/path',
311                        self.device.GetExternalStoragePath())
312
313  def testGetExternalStoragePath_fails(self):
314    with self.assertCall(self.call.adb.Shell('echo $EXTERNAL_STORAGE'), '\n'):
315      with self.assertRaises(device_errors.CommandFailedError):
316        self.device.GetExternalStoragePath()
317
318
319class DeviceUtilsGetApplicationPathsInternalTest(DeviceUtilsTest):
320
321  def testGetApplicationPathsInternal_exists(self):
322    with self.assertCalls(
323        (self.call.device.GetProp('ro.build.version.sdk', cache=True), '19'),
324        (self.call.device.RunShellCommand(
325            ['pm', 'path', 'android'], check_return=True),
326         ['package:/path/to/android.apk'])):
327      self.assertEquals(['/path/to/android.apk'],
328                        self.device._GetApplicationPathsInternal('android'))
329
330  def testGetApplicationPathsInternal_notExists(self):
331    with self.assertCalls(
332        (self.call.device.GetProp('ro.build.version.sdk', cache=True), '19'),
333        (self.call.device.RunShellCommand(
334            ['pm', 'path', 'not.installed.app'], check_return=True),
335         '')):
336      self.assertEquals([],
337          self.device._GetApplicationPathsInternal('not.installed.app'))
338
339  def testGetApplicationPathsInternal_fails(self):
340    with self.assertCalls(
341        (self.call.device.GetProp('ro.build.version.sdk', cache=True), '19'),
342        (self.call.device.RunShellCommand(
343            ['pm', 'path', 'android'], check_return=True),
344         self.CommandError('ERROR. Is package manager running?\n'))):
345      with self.assertRaises(device_errors.CommandFailedError):
346        self.device._GetApplicationPathsInternal('android')
347
348
349class DeviceUtils_GetApplicationVersionTest(DeviceUtilsTest):
350
351  def test_GetApplicationVersion_exists(self):
352    with self.assertCalls(
353        (self.call.adb.Shell('dumpsys package com.android.chrome'),
354         'Packages:\n'
355         '  Package [com.android.chrome] (3901ecfb):\n'
356         '    userId=1234 gids=[123, 456, 789]\n'
357         '    pkg=Package{1fecf634 com.android.chrome}\n'
358         '    versionName=45.0.1234.7\n')):
359      self.assertEquals('45.0.1234.7',
360                        self.device.GetApplicationVersion('com.android.chrome'))
361
362  def test_GetApplicationVersion_notExists(self):
363    with self.assertCalls(
364        (self.call.adb.Shell('dumpsys package com.android.chrome'), '')):
365      self.assertEquals(None,
366                        self.device.GetApplicationVersion('com.android.chrome'))
367
368  def test_GetApplicationVersion_fails(self):
369    with self.assertCalls(
370        (self.call.adb.Shell('dumpsys package com.android.chrome'),
371         'Packages:\n'
372         '  Package [com.android.chrome] (3901ecfb):\n'
373         '    userId=1234 gids=[123, 456, 789]\n'
374         '    pkg=Package{1fecf634 com.android.chrome}\n')):
375      with self.assertRaises(device_errors.CommandFailedError):
376        self.device.GetApplicationVersion('com.android.chrome')
377
378
379class DeviceUtilsGetApplicationDataDirectoryTest(DeviceUtilsTest):
380
381  def testGetApplicationDataDirectory_exists(self):
382    with self.assertCall(
383        self.call.device._RunPipedShellCommand(
384            'pm dump foo.bar.baz | grep dataDir='),
385        ['dataDir=/data/data/foo.bar.baz']):
386      self.assertEquals(
387          '/data/data/foo.bar.baz',
388          self.device.GetApplicationDataDirectory('foo.bar.baz'))
389
390  def testGetApplicationDataDirectory_notExists(self):
391    with self.assertCall(
392        self.call.device._RunPipedShellCommand(
393            'pm dump foo.bar.baz | grep dataDir='),
394        self.ShellError()):
395      self.assertIsNone(self.device.GetApplicationDataDirectory('foo.bar.baz'))
396
397
398@mock.patch('time.sleep', mock.Mock())
399class DeviceUtilsWaitUntilFullyBootedTest(DeviceUtilsTest):
400
401  def testWaitUntilFullyBooted_succeedsNoWifi(self):
402    with self.assertCalls(
403        self.call.adb.WaitForDevice(),
404        # sd_card_ready
405        (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
406        (self.call.adb.Shell('test -d /fake/storage/path'), ''),
407        # pm_ready
408        (self.call.device._GetApplicationPathsInternal('android',
409                                                       skip_cache=True),
410         ['package:/some/fake/path']),
411        # boot_completed
412        (self.call.device.GetProp('sys.boot_completed', cache=False), '1')):
413      self.device.WaitUntilFullyBooted(wifi=False)
414
415  def testWaitUntilFullyBooted_succeedsWithWifi(self):
416    with self.assertCalls(
417        self.call.adb.WaitForDevice(),
418        # sd_card_ready
419        (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
420        (self.call.adb.Shell('test -d /fake/storage/path'), ''),
421        # pm_ready
422        (self.call.device._GetApplicationPathsInternal('android',
423                                                       skip_cache=True),
424         ['package:/some/fake/path']),
425        # boot_completed
426        (self.call.device.GetProp('sys.boot_completed', cache=False), '1'),
427        # wifi_enabled
428        (self.call.adb.Shell('dumpsys wifi'),
429         'stuff\nWi-Fi is enabled\nmore stuff\n')):
430      self.device.WaitUntilFullyBooted(wifi=True)
431
432  def testWaitUntilFullyBooted_deviceNotInitiallyAvailable(self):
433    with self.assertCalls(
434        self.call.adb.WaitForDevice(),
435        # sd_card_ready
436        (self.call.device.GetExternalStoragePath(), self.AdbCommandError()),
437        # sd_card_ready
438        (self.call.device.GetExternalStoragePath(), self.AdbCommandError()),
439        # sd_card_ready
440        (self.call.device.GetExternalStoragePath(), self.AdbCommandError()),
441        # sd_card_ready
442        (self.call.device.GetExternalStoragePath(), self.AdbCommandError()),
443        # sd_card_ready
444        (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
445        (self.call.adb.Shell('test -d /fake/storage/path'), ''),
446        # pm_ready
447        (self.call.device._GetApplicationPathsInternal('android',
448                                                       skip_cache=True),
449         ['package:/some/fake/path']),
450        # boot_completed
451        (self.call.device.GetProp('sys.boot_completed', cache=False), '1')):
452      self.device.WaitUntilFullyBooted(wifi=False)
453
454  def testWaitUntilFullyBooted_sdCardReadyFails_noPath(self):
455    with self.assertCalls(
456        self.call.adb.WaitForDevice(),
457        # sd_card_ready
458        (self.call.device.GetExternalStoragePath(), self.CommandError())):
459      with self.assertRaises(device_errors.CommandFailedError):
460        self.device.WaitUntilFullyBooted(wifi=False)
461
462  def testWaitUntilFullyBooted_sdCardReadyFails_notExists(self):
463    with self.assertCalls(
464        self.call.adb.WaitForDevice(),
465        # sd_card_ready
466        (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
467        (self.call.adb.Shell('test -d /fake/storage/path'), self.ShellError()),
468        # sd_card_ready
469        (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
470        (self.call.adb.Shell('test -d /fake/storage/path'), self.ShellError()),
471        # sd_card_ready
472        (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
473        (self.call.adb.Shell('test -d /fake/storage/path'),
474         self.TimeoutError())):
475      with self.assertRaises(device_errors.CommandTimeoutError):
476        self.device.WaitUntilFullyBooted(wifi=False)
477
478  def testWaitUntilFullyBooted_devicePmFails(self):
479    with self.assertCalls(
480        self.call.adb.WaitForDevice(),
481        # sd_card_ready
482        (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
483        (self.call.adb.Shell('test -d /fake/storage/path'), ''),
484        # pm_ready
485        (self.call.device._GetApplicationPathsInternal('android',
486                                                       skip_cache=True),
487         self.CommandError()),
488        # pm_ready
489        (self.call.device._GetApplicationPathsInternal('android',
490                                                       skip_cache=True),
491         self.CommandError()),
492        # pm_ready
493        (self.call.device._GetApplicationPathsInternal('android',
494                                                       skip_cache=True),
495         self.TimeoutError())):
496      with self.assertRaises(device_errors.CommandTimeoutError):
497        self.device.WaitUntilFullyBooted(wifi=False)
498
499  def testWaitUntilFullyBooted_bootFails(self):
500    with self.assertCalls(
501        self.call.adb.WaitForDevice(),
502        # sd_card_ready
503        (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
504        (self.call.adb.Shell('test -d /fake/storage/path'), ''),
505        # pm_ready
506        (self.call.device._GetApplicationPathsInternal('android',
507                                                       skip_cache=True),
508         ['package:/some/fake/path']),
509        # boot_completed
510        (self.call.device.GetProp('sys.boot_completed', cache=False), '0'),
511        # boot_completed
512        (self.call.device.GetProp('sys.boot_completed', cache=False), '0'),
513        # boot_completed
514        (self.call.device.GetProp('sys.boot_completed', cache=False),
515         self.TimeoutError())):
516      with self.assertRaises(device_errors.CommandTimeoutError):
517        self.device.WaitUntilFullyBooted(wifi=False)
518
519  def testWaitUntilFullyBooted_wifiFails(self):
520    with self.assertCalls(
521        self.call.adb.WaitForDevice(),
522        # sd_card_ready
523        (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
524        (self.call.adb.Shell('test -d /fake/storage/path'), ''),
525        # pm_ready
526        (self.call.device._GetApplicationPathsInternal('android',
527                                                       skip_cache=True),
528         ['package:/some/fake/path']),
529        # boot_completed
530        (self.call.device.GetProp('sys.boot_completed', cache=False), '1'),
531        # wifi_enabled
532        (self.call.adb.Shell('dumpsys wifi'), 'stuff\nmore stuff\n'),
533        # wifi_enabled
534        (self.call.adb.Shell('dumpsys wifi'), 'stuff\nmore stuff\n'),
535        # wifi_enabled
536        (self.call.adb.Shell('dumpsys wifi'), self.TimeoutError())):
537      with self.assertRaises(device_errors.CommandTimeoutError):
538        self.device.WaitUntilFullyBooted(wifi=True)
539
540
541@mock.patch('time.sleep', mock.Mock())
542class DeviceUtilsRebootTest(DeviceUtilsTest):
543
544  def testReboot_nonBlocking(self):
545    with self.assertCalls(
546        self.call.adb.Reboot(),
547        (self.call.device.IsOnline(), True),
548        (self.call.device.IsOnline(), False)):
549      self.device.Reboot(block=False)
550
551  def testReboot_blocking(self):
552    with self.assertCalls(
553        self.call.adb.Reboot(),
554        (self.call.device.IsOnline(), True),
555        (self.call.device.IsOnline(), False),
556        self.call.device.WaitUntilFullyBooted(wifi=False)):
557      self.device.Reboot(block=True)
558
559  def testReboot_blockUntilWifi(self):
560    with self.assertCalls(
561        self.call.adb.Reboot(),
562        (self.call.device.IsOnline(), True),
563        (self.call.device.IsOnline(), False),
564        self.call.device.WaitUntilFullyBooted(wifi=True)):
565      self.device.Reboot(block=True, wifi=True)
566
567
568class DeviceUtilsInstallTest(DeviceUtilsTest):
569
570  mock_apk = _MockApkHelper('/fake/test/app.apk', 'test.package', ['p1'])
571
572  def testInstall_noPriorInstall(self):
573    with self.patch_call(self.call.device.build_version_sdk, return_value=23):
574      with self.assertCalls(
575          (self.call.device._GetApplicationPathsInternal('test.package'), []),
576          self.call.adb.Install('/fake/test/app.apk', reinstall=False,
577                                allow_downgrade=False),
578          (self.call.device.GrantPermissions('test.package', ['p1']), [])):
579        self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0)
580
581  def testInstall_permissionsPreM(self):
582    with self.patch_call(self.call.device.build_version_sdk, return_value=20):
583      with self.assertCalls(
584          (self.call.device._GetApplicationPathsInternal('test.package'), []),
585          (self.call.adb.Install('/fake/test/app.apk', reinstall=False,
586                                 allow_downgrade=False))):
587        self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0)
588
589  def testInstall_findPermissions(self):
590    with self.patch_call(self.call.device.build_version_sdk, return_value=23):
591      with self.assertCalls(
592          (self.call.device._GetApplicationPathsInternal('test.package'), []),
593          (self.call.adb.Install('/fake/test/app.apk', reinstall=False,
594                                 allow_downgrade=False)),
595          (self.call.device.GrantPermissions('test.package', ['p1']), [])):
596        self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0)
597
598  def testInstall_passPermissions(self):
599    with self.assertCalls(
600        (self.call.device._GetApplicationPathsInternal('test.package'), []),
601        (self.call.adb.Install('/fake/test/app.apk', reinstall=False,
602                               allow_downgrade=False)),
603        (self.call.device.GrantPermissions('test.package', ['p1', 'p2']), [])):
604      self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0,
605                          permissions=['p1', 'p2'])
606
607  def testInstall_differentPriorInstall(self):
608    with self.assertCalls(
609        (self.call.device._GetApplicationPathsInternal('test.package'),
610         ['/fake/data/app/test.package.apk']),
611        (self.call.device._ComputeStaleApks('test.package',
612            ['/fake/test/app.apk']),
613         (['/fake/test/app.apk'], None)),
614        self.call.device.Uninstall('test.package'),
615        self.call.adb.Install('/fake/test/app.apk', reinstall=False,
616                              allow_downgrade=False)):
617      self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0,
618                          permissions=[])
619
620  def testInstall_differentPriorInstall_reinstall(self):
621    with self.assertCalls(
622        (self.call.device._GetApplicationPathsInternal('test.package'),
623         ['/fake/data/app/test.package.apk']),
624        (self.call.device._ComputeStaleApks('test.package',
625            ['/fake/test/app.apk']),
626         (['/fake/test/app.apk'], None)),
627        self.call.adb.Install('/fake/test/app.apk', reinstall=True,
628                              allow_downgrade=False)):
629      self.device.Install(DeviceUtilsInstallTest.mock_apk,
630          reinstall=True, retries=0, permissions=[])
631
632  def testInstall_identicalPriorInstall_reinstall(self):
633    with self.assertCalls(
634        (self.call.device._GetApplicationPathsInternal('test.package'),
635         ['/fake/data/app/test.package.apk']),
636        (self.call.device._ComputeStaleApks('test.package',
637            ['/fake/test/app.apk']),
638         ([], None)),
639        (self.call.device.ForceStop('test.package'))):
640      self.device.Install(DeviceUtilsInstallTest.mock_apk,
641          reinstall=True, retries=0, permissions=[])
642
643  def testInstall_fails(self):
644    with self.assertCalls(
645        (self.call.device._GetApplicationPathsInternal('test.package'), []),
646        (self.call.adb.Install('/fake/test/app.apk', reinstall=False,
647                               allow_downgrade=False),
648         self.CommandError('Failure\r\n'))):
649      with self.assertRaises(device_errors.CommandFailedError):
650        self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0)
651
652  def testInstall_downgrade(self):
653    with self.assertCalls(
654        (self.call.device._GetApplicationPathsInternal('test.package'),
655         ['/fake/data/app/test.package.apk']),
656        (self.call.device._ComputeStaleApks('test.package',
657            ['/fake/test/app.apk']),
658         (['/fake/test/app.apk'], None)),
659        self.call.adb.Install('/fake/test/app.apk', reinstall=True,
660                              allow_downgrade=True)):
661      self.device.Install(DeviceUtilsInstallTest.mock_apk,
662          reinstall=True, retries=0, permissions=[], allow_downgrade=True)
663
664
665class DeviceUtilsInstallSplitApkTest(DeviceUtilsTest):
666
667  mock_apk = _MockApkHelper('base.apk', 'test.package', ['p1'])
668
669  def testInstallSplitApk_noPriorInstall(self):
670    with self.assertCalls(
671        (self.call.device._CheckSdkLevel(21)),
672        (mock.call.devil.android.sdk.split_select.SelectSplits(
673            self.device, 'base.apk',
674            ['split1.apk', 'split2.apk', 'split3.apk'],
675            allow_cached_props=False),
676         ['split2.apk']),
677        (self.call.device._GetApplicationPathsInternal('test.package'), []),
678        (self.call.adb.InstallMultiple(
679            ['base.apk', 'split2.apk'], partial=None, reinstall=False,
680            allow_downgrade=False))):
681      self.device.InstallSplitApk(DeviceUtilsInstallSplitApkTest.mock_apk,
682          ['split1.apk', 'split2.apk', 'split3.apk'], permissions=[], retries=0)
683
684  def testInstallSplitApk_partialInstall(self):
685    with self.assertCalls(
686        (self.call.device._CheckSdkLevel(21)),
687        (mock.call.devil.android.sdk.split_select.SelectSplits(
688            self.device, 'base.apk',
689            ['split1.apk', 'split2.apk', 'split3.apk'],
690            allow_cached_props=False),
691         ['split2.apk']),
692        (self.call.device._GetApplicationPathsInternal('test.package'),
693         ['base-on-device.apk', 'split2-on-device.apk']),
694        (self.call.device._ComputeStaleApks('test.package',
695                                            ['base.apk', 'split2.apk']),
696         (['split2.apk'], None)),
697        (self.call.adb.InstallMultiple(
698            ['split2.apk'], partial='test.package', reinstall=True,
699            allow_downgrade=False))):
700      self.device.InstallSplitApk(DeviceUtilsInstallSplitApkTest.mock_apk,
701                                  ['split1.apk', 'split2.apk', 'split3.apk'],
702                                  reinstall=True, permissions=[], retries=0)
703
704  def testInstallSplitApk_downgrade(self):
705    with self.assertCalls(
706        (self.call.device._CheckSdkLevel(21)),
707        (mock.call.devil.android.sdk.split_select.SelectSplits(
708            self.device, 'base.apk',
709            ['split1.apk', 'split2.apk', 'split3.apk'],
710            allow_cached_props=False),
711         ['split2.apk']),
712        (self.call.device._GetApplicationPathsInternal('test.package'),
713         ['base-on-device.apk', 'split2-on-device.apk']),
714        (self.call.device._ComputeStaleApks('test.package',
715                                            ['base.apk', 'split2.apk']),
716         (['split2.apk'], None)),
717        (self.call.adb.InstallMultiple(
718            ['split2.apk'], partial='test.package', reinstall=True,
719            allow_downgrade=True))):
720      self.device.InstallSplitApk(DeviceUtilsInstallSplitApkTest.mock_apk,
721                                  ['split1.apk', 'split2.apk', 'split3.apk'],
722                                  reinstall=True, permissions=[], retries=0,
723                                  allow_downgrade=True)
724
725
726class DeviceUtilsUninstallTest(DeviceUtilsTest):
727
728  def testUninstall_callsThrough(self):
729    with self.assertCalls(
730        (self.call.device._GetApplicationPathsInternal('test.package'),
731         ['/path.apk']),
732        self.call.adb.Uninstall('test.package', True)):
733      self.device.Uninstall('test.package', True)
734
735  def testUninstall_noop(self):
736    with self.assertCalls(
737        (self.call.device._GetApplicationPathsInternal('test.package'), [])):
738      self.device.Uninstall('test.package', True)
739
740
741class DeviceUtilsSuTest(DeviceUtilsTest):
742
743  def testSu_preM(self):
744    with self.patch_call(
745        self.call.device.build_version_sdk,
746        return_value=version_codes.LOLLIPOP_MR1):
747      self.assertEquals('su -c foo', self.device._Su('foo'))
748
749  def testSu_mAndAbove(self):
750    with self.patch_call(
751        self.call.device.build_version_sdk,
752        return_value=version_codes.MARSHMALLOW):
753      self.assertEquals('su 0 foo', self.device._Su('foo'))
754
755
756class DeviceUtilsRunShellCommandTest(DeviceUtilsTest):
757
758  def setUp(self):
759    super(DeviceUtilsRunShellCommandTest, self).setUp()
760    self.device.NeedsSU = mock.Mock(return_value=False)
761
762  def testRunShellCommand_commandAsList(self):
763    with self.assertCall(self.call.adb.Shell('pm list packages'), ''):
764      self.device.RunShellCommand(['pm', 'list', 'packages'])
765
766  def testRunShellCommand_commandAsListQuoted(self):
767    with self.assertCall(self.call.adb.Shell("echo 'hello world' '$10'"), ''):
768      self.device.RunShellCommand(['echo', 'hello world', '$10'])
769
770  def testRunShellCommand_commandAsString(self):
771    with self.assertCall(self.call.adb.Shell('echo "$VAR"'), ''):
772      self.device.RunShellCommand('echo "$VAR"')
773
774  def testNewRunShellImpl_withEnv(self):
775    with self.assertCall(
776        self.call.adb.Shell('VAR=some_string echo "$VAR"'), ''):
777      self.device.RunShellCommand('echo "$VAR"', env={'VAR': 'some_string'})
778
779  def testNewRunShellImpl_withEnvQuoted(self):
780    with self.assertCall(
781        self.call.adb.Shell('PATH="$PATH:/other/path" run_this'), ''):
782      self.device.RunShellCommand('run_this', env={'PATH': '$PATH:/other/path'})
783
784  def testNewRunShellImpl_withEnv_failure(self):
785    with self.assertRaises(KeyError):
786      self.device.RunShellCommand('some_cmd', env={'INVALID NAME': 'value'})
787
788  def testNewRunShellImpl_withCwd(self):
789    with self.assertCall(self.call.adb.Shell('cd /some/test/path && ls'), ''):
790      self.device.RunShellCommand('ls', cwd='/some/test/path')
791
792  def testNewRunShellImpl_withCwdQuoted(self):
793    with self.assertCall(
794        self.call.adb.Shell("cd '/some test/path with/spaces' && ls"), ''):
795      self.device.RunShellCommand('ls', cwd='/some test/path with/spaces')
796
797  def testRunShellCommand_withHugeCmd(self):
798    payload = 'hi! ' * 1024
799    expected_cmd = "echo '%s'" % payload
800    with self.assertCalls(
801      (mock.call.devil.android.device_temp_file.DeviceTempFile(
802          self.adb, suffix='.sh'), MockTempFile('/sdcard/temp-123.sh')),
803      self.call.device._WriteFileWithPush('/sdcard/temp-123.sh', expected_cmd),
804      (self.call.adb.Shell('sh /sdcard/temp-123.sh'), payload + '\n')):
805      self.assertEquals([payload],
806                        self.device.RunShellCommand(['echo', payload]))
807
808  def testRunShellCommand_withHugeCmdAndSU(self):
809    payload = 'hi! ' * 1024
810    expected_cmd_without_su = """sh -c 'echo '"'"'%s'"'"''""" % payload
811    expected_cmd = 'su -c %s' % expected_cmd_without_su
812    with self.assertCalls(
813      (self.call.device.NeedsSU(), True),
814      (self.call.device._Su(expected_cmd_without_su), expected_cmd),
815      (mock.call.devil.android.device_temp_file.DeviceTempFile(
816          self.adb, suffix='.sh'), MockTempFile('/sdcard/temp-123.sh')),
817      self.call.device._WriteFileWithPush('/sdcard/temp-123.sh', expected_cmd),
818      (self.call.adb.Shell('sh /sdcard/temp-123.sh'), payload + '\n')):
819      self.assertEquals(
820          [payload],
821          self.device.RunShellCommand(['echo', payload], as_root=True))
822
823  def testRunShellCommand_withSu(self):
824    expected_cmd_without_su = "sh -c 'setprop service.adb.root 0'"
825    expected_cmd = 'su -c %s' % expected_cmd_without_su
826    with self.assertCalls(
827        (self.call.device.NeedsSU(), True),
828        (self.call.device._Su(expected_cmd_without_su), expected_cmd),
829        (self.call.adb.Shell(expected_cmd), '')):
830      self.device.RunShellCommand('setprop service.adb.root 0', as_root=True)
831
832  def testRunShellCommand_manyLines(self):
833    cmd = 'ls /some/path'
834    with self.assertCall(self.call.adb.Shell(cmd), 'file1\nfile2\nfile3\n'):
835      self.assertEquals(['file1', 'file2', 'file3'],
836                        self.device.RunShellCommand(cmd))
837
838  def testRunShellCommand_singleLine_success(self):
839    cmd = 'echo $VALUE'
840    with self.assertCall(self.call.adb.Shell(cmd), 'some value\n'):
841      self.assertEquals('some value',
842                        self.device.RunShellCommand(cmd, single_line=True))
843
844  def testRunShellCommand_singleLine_successEmptyLine(self):
845    cmd = 'echo $VALUE'
846    with self.assertCall(self.call.adb.Shell(cmd), '\n'):
847      self.assertEquals('',
848                        self.device.RunShellCommand(cmd, single_line=True))
849
850  def testRunShellCommand_singleLine_successWithoutEndLine(self):
851    cmd = 'echo -n $VALUE'
852    with self.assertCall(self.call.adb.Shell(cmd), 'some value'):
853      self.assertEquals('some value',
854                        self.device.RunShellCommand(cmd, single_line=True))
855
856  def testRunShellCommand_singleLine_successNoOutput(self):
857    cmd = 'echo -n $VALUE'
858    with self.assertCall(self.call.adb.Shell(cmd), ''):
859      self.assertEquals('',
860                        self.device.RunShellCommand(cmd, single_line=True))
861
862  def testRunShellCommand_singleLine_failTooManyLines(self):
863    cmd = 'echo $VALUE'
864    with self.assertCall(self.call.adb.Shell(cmd),
865                         'some value\nanother value\n'):
866      with self.assertRaises(device_errors.CommandFailedError):
867        self.device.RunShellCommand(cmd, single_line=True)
868
869  def testRunShellCommand_checkReturn_success(self):
870    cmd = 'echo $ANDROID_DATA'
871    output = '/data\n'
872    with self.assertCall(self.call.adb.Shell(cmd), output):
873      self.assertEquals([output.rstrip()],
874                        self.device.RunShellCommand(cmd, check_return=True))
875
876  def testRunShellCommand_checkReturn_failure(self):
877    cmd = 'ls /root'
878    output = 'opendir failed, Permission denied\n'
879    with self.assertCall(self.call.adb.Shell(cmd), self.ShellError(output)):
880      with self.assertRaises(device_errors.AdbCommandFailedError):
881        self.device.RunShellCommand(cmd, check_return=True)
882
883  def testRunShellCommand_checkReturn_disabled(self):
884    cmd = 'ls /root'
885    output = 'opendir failed, Permission denied\n'
886    with self.assertCall(self.call.adb.Shell(cmd), self.ShellError(output)):
887      self.assertEquals([output.rstrip()],
888                        self.device.RunShellCommand(cmd, check_return=False))
889
890  def testRunShellCommand_largeOutput_enabled(self):
891    cmd = 'echo $VALUE'
892    temp_file = MockTempFile('/sdcard/temp-123')
893    cmd_redirect = '( %s )>%s' % (cmd, temp_file.name)
894    with self.assertCalls(
895        (mock.call.devil.android.device_temp_file.DeviceTempFile(self.adb),
896            temp_file),
897        (self.call.adb.Shell(cmd_redirect)),
898        (self.call.device.ReadFile(temp_file.name, force_pull=True),
899         'something')):
900      self.assertEquals(
901          ['something'],
902          self.device.RunShellCommand(
903              cmd, large_output=True, check_return=True))
904
905  def testRunShellCommand_largeOutput_disabledNoTrigger(self):
906    cmd = 'something'
907    with self.assertCall(self.call.adb.Shell(cmd), self.ShellError('')):
908      with self.assertRaises(device_errors.AdbCommandFailedError):
909        self.device.RunShellCommand(cmd, check_return=True)
910
911  def testRunShellCommand_largeOutput_disabledTrigger(self):
912    cmd = 'echo $VALUE'
913    temp_file = MockTempFile('/sdcard/temp-123')
914    cmd_redirect = '( %s )>%s' % (cmd, temp_file.name)
915    with self.assertCalls(
916        (self.call.adb.Shell(cmd), self.ShellError('', None)),
917        (mock.call.devil.android.device_temp_file.DeviceTempFile(self.adb),
918            temp_file),
919        (self.call.adb.Shell(cmd_redirect)),
920        (self.call.device.ReadFile(mock.ANY, force_pull=True),
921         'something')):
922      self.assertEquals(['something'],
923                        self.device.RunShellCommand(cmd, check_return=True))
924
925
926class DeviceUtilsRunPipedShellCommandTest(DeviceUtilsTest):
927
928  def testRunPipedShellCommand_success(self):
929    with self.assertCall(
930        self.call.device.RunShellCommand(
931            'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"',
932            check_return=True),
933        ['This line contains foo', 'PIPESTATUS: 0 0']):
934      self.assertEquals(['This line contains foo'],
935                        self.device._RunPipedShellCommand('ps | grep foo'))
936
937  def testRunPipedShellCommand_firstCommandFails(self):
938    with self.assertCall(
939        self.call.device.RunShellCommand(
940            'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"',
941            check_return=True),
942        ['PIPESTATUS: 1 0']):
943      with self.assertRaises(device_errors.AdbShellCommandFailedError) as ec:
944        self.device._RunPipedShellCommand('ps | grep foo')
945      self.assertEquals([1, 0], ec.exception.status)
946
947  def testRunPipedShellCommand_secondCommandFails(self):
948    with self.assertCall(
949        self.call.device.RunShellCommand(
950            'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"',
951            check_return=True),
952        ['PIPESTATUS: 0 1']):
953      with self.assertRaises(device_errors.AdbShellCommandFailedError) as ec:
954        self.device._RunPipedShellCommand('ps | grep foo')
955      self.assertEquals([0, 1], ec.exception.status)
956
957  def testRunPipedShellCommand_outputCutOff(self):
958    with self.assertCall(
959        self.call.device.RunShellCommand(
960            'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"',
961            check_return=True),
962        ['foo.bar'] * 256 + ['foo.ba']):
963      with self.assertRaises(device_errors.AdbShellCommandFailedError) as ec:
964        self.device._RunPipedShellCommand('ps | grep foo')
965      self.assertIs(None, ec.exception.status)
966
967
968@mock.patch('time.sleep', mock.Mock())
969class DeviceUtilsKillAllTest(DeviceUtilsTest):
970
971  def testKillAll_noMatchingProcessesFailure(self):
972    with self.assertCall(self.call.device.GetPids('test_process'), {}):
973      with self.assertRaises(device_errors.CommandFailedError):
974        self.device.KillAll('test_process')
975
976  def testKillAll_noMatchingProcessesQuiet(self):
977    with self.assertCall(self.call.device.GetPids('test_process'), {}):
978      self.assertEqual(0, self.device.KillAll('test_process', quiet=True))
979
980  def testKillAll_nonblocking(self):
981    with self.assertCalls(
982        (self.call.device.GetPids('some.process'),
983         {'some.process': ['1234'], 'some.processing.thing': ['5678']}),
984        (self.call.adb.Shell('kill -9 1234 5678'), '')):
985      self.assertEquals(
986          2, self.device.KillAll('some.process', blocking=False))
987
988  def testKillAll_blocking(self):
989    with self.assertCalls(
990        (self.call.device.GetPids('some.process'),
991         {'some.process': ['1234'], 'some.processing.thing': ['5678']}),
992        (self.call.adb.Shell('kill -9 1234 5678'), ''),
993        (self.call.device.GetPids('some.process'),
994         {'some.processing.thing': ['5678']}),
995        (self.call.device.GetPids('some.process'),
996         {'some.process': ['1111']})):  # Other instance with different pid.
997      self.assertEquals(
998          2, self.device.KillAll('some.process', blocking=True))
999
1000  def testKillAll_exactNonblocking(self):
1001    with self.assertCalls(
1002        (self.call.device.GetPids('some.process'),
1003         {'some.process': ['1234'], 'some.processing.thing': ['5678']}),
1004        (self.call.adb.Shell('kill -9 1234'), '')):
1005      self.assertEquals(
1006          1, self.device.KillAll('some.process', exact=True, blocking=False))
1007
1008  def testKillAll_exactBlocking(self):
1009    with self.assertCalls(
1010        (self.call.device.GetPids('some.process'),
1011         {'some.process': ['1234'], 'some.processing.thing': ['5678']}),
1012        (self.call.adb.Shell('kill -9 1234'), ''),
1013        (self.call.device.GetPids('some.process'),
1014         {'some.process': ['1234'], 'some.processing.thing': ['5678']}),
1015        (self.call.device.GetPids('some.process'),
1016         {'some.processing.thing': ['5678']})):
1017      self.assertEquals(
1018          1, self.device.KillAll('some.process', exact=True, blocking=True))
1019
1020  def testKillAll_root(self):
1021    with self.assertCalls(
1022        (self.call.device.GetPids('some.process'), {'some.process': ['1234']}),
1023        (self.call.device.NeedsSU(), True),
1024        (self.call.device._Su("sh -c 'kill -9 1234'"),
1025         "su -c sh -c 'kill -9 1234'"),
1026        (self.call.adb.Shell("su -c sh -c 'kill -9 1234'"), '')):
1027      self.assertEquals(
1028          1, self.device.KillAll('some.process', as_root=True))
1029
1030  def testKillAll_sigterm(self):
1031    with self.assertCalls(
1032        (self.call.device.GetPids('some.process'),
1033            {'some.process': ['1234']}),
1034        (self.call.adb.Shell('kill -15 1234'), '')):
1035      self.assertEquals(
1036          1, self.device.KillAll('some.process', signum=device_signal.SIGTERM))
1037
1038  def testKillAll_multipleInstances(self):
1039    with self.assertCalls(
1040        (self.call.device.GetPids('some.process'),
1041            {'some.process': ['1234', '4567']}),
1042        (self.call.adb.Shell('kill -15 1234 4567'), '')):
1043      self.assertEquals(
1044          2, self.device.KillAll('some.process', signum=device_signal.SIGTERM))
1045
1046
1047class DeviceUtilsStartActivityTest(DeviceUtilsTest):
1048
1049  def testStartActivity_actionOnly(self):
1050    test_intent = intent.Intent(action='android.intent.action.VIEW')
1051    with self.assertCall(
1052        self.call.adb.Shell('am start '
1053                            '-a android.intent.action.VIEW'),
1054        'Starting: Intent { act=android.intent.action.VIEW }'):
1055      self.device.StartActivity(test_intent)
1056
1057  def testStartActivity_success(self):
1058    test_intent = intent.Intent(action='android.intent.action.VIEW',
1059                                package='test.package',
1060                                activity='.Main')
1061    with self.assertCall(
1062        self.call.adb.Shell('am start '
1063                            '-a android.intent.action.VIEW '
1064                            '-n test.package/.Main'),
1065        'Starting: Intent { act=android.intent.action.VIEW }'):
1066      self.device.StartActivity(test_intent)
1067
1068  def testStartActivity_failure(self):
1069    test_intent = intent.Intent(action='android.intent.action.VIEW',
1070                                package='test.package',
1071                                activity='.Main')
1072    with self.assertCall(
1073        self.call.adb.Shell('am start '
1074                            '-a android.intent.action.VIEW '
1075                            '-n test.package/.Main'),
1076        'Error: Failed to start test activity'):
1077      with self.assertRaises(device_errors.CommandFailedError):
1078        self.device.StartActivity(test_intent)
1079
1080  def testStartActivity_blocking(self):
1081    test_intent = intent.Intent(action='android.intent.action.VIEW',
1082                                package='test.package',
1083                                activity='.Main')
1084    with self.assertCall(
1085        self.call.adb.Shell('am start '
1086                            '-W '
1087                            '-a android.intent.action.VIEW '
1088                            '-n test.package/.Main'),
1089        'Starting: Intent { act=android.intent.action.VIEW }'):
1090      self.device.StartActivity(test_intent, blocking=True)
1091
1092  def testStartActivity_withCategory(self):
1093    test_intent = intent.Intent(action='android.intent.action.VIEW',
1094                                package='test.package',
1095                                activity='.Main',
1096                                category='android.intent.category.HOME')
1097    with self.assertCall(
1098        self.call.adb.Shell('am start '
1099                            '-a android.intent.action.VIEW '
1100                            '-c android.intent.category.HOME '
1101                            '-n test.package/.Main'),
1102        'Starting: Intent { act=android.intent.action.VIEW }'):
1103      self.device.StartActivity(test_intent)
1104
1105  def testStartActivity_withMultipleCategories(self):
1106    test_intent = intent.Intent(action='android.intent.action.VIEW',
1107                                package='test.package',
1108                                activity='.Main',
1109                                category=['android.intent.category.HOME',
1110                                          'android.intent.category.BROWSABLE'])
1111    with self.assertCall(
1112        self.call.adb.Shell('am start '
1113                            '-a android.intent.action.VIEW '
1114                            '-c android.intent.category.HOME '
1115                            '-c android.intent.category.BROWSABLE '
1116                            '-n test.package/.Main'),
1117        'Starting: Intent { act=android.intent.action.VIEW }'):
1118      self.device.StartActivity(test_intent)
1119
1120  def testStartActivity_withData(self):
1121    test_intent = intent.Intent(action='android.intent.action.VIEW',
1122                                package='test.package',
1123                                activity='.Main',
1124                                data='http://www.google.com/')
1125    with self.assertCall(
1126        self.call.adb.Shell('am start '
1127                            '-a android.intent.action.VIEW '
1128                            '-d http://www.google.com/ '
1129                            '-n test.package/.Main'),
1130        'Starting: Intent { act=android.intent.action.VIEW }'):
1131      self.device.StartActivity(test_intent)
1132
1133  def testStartActivity_withStringExtra(self):
1134    test_intent = intent.Intent(action='android.intent.action.VIEW',
1135                                package='test.package',
1136                                activity='.Main',
1137                                extras={'foo': 'test'})
1138    with self.assertCall(
1139        self.call.adb.Shell('am start '
1140                            '-a android.intent.action.VIEW '
1141                            '-n test.package/.Main '
1142                            '--es foo test'),
1143        'Starting: Intent { act=android.intent.action.VIEW }'):
1144      self.device.StartActivity(test_intent)
1145
1146  def testStartActivity_withBoolExtra(self):
1147    test_intent = intent.Intent(action='android.intent.action.VIEW',
1148                                package='test.package',
1149                                activity='.Main',
1150                                extras={'foo': True})
1151    with self.assertCall(
1152        self.call.adb.Shell('am start '
1153                            '-a android.intent.action.VIEW '
1154                            '-n test.package/.Main '
1155                            '--ez foo True'),
1156        'Starting: Intent { act=android.intent.action.VIEW }'):
1157      self.device.StartActivity(test_intent)
1158
1159  def testStartActivity_withIntExtra(self):
1160    test_intent = intent.Intent(action='android.intent.action.VIEW',
1161                                package='test.package',
1162                                activity='.Main',
1163                                extras={'foo': 123})
1164    with self.assertCall(
1165        self.call.adb.Shell('am start '
1166                            '-a android.intent.action.VIEW '
1167                            '-n test.package/.Main '
1168                            '--ei foo 123'),
1169        'Starting: Intent { act=android.intent.action.VIEW }'):
1170      self.device.StartActivity(test_intent)
1171
1172  def testStartActivity_withTraceFile(self):
1173    test_intent = intent.Intent(action='android.intent.action.VIEW',
1174                                package='test.package',
1175                                activity='.Main')
1176    with self.assertCall(
1177        self.call.adb.Shell('am start '
1178                            '--start-profiler test_trace_file.out '
1179                            '-a android.intent.action.VIEW '
1180                            '-n test.package/.Main'),
1181        'Starting: Intent { act=android.intent.action.VIEW }'):
1182      self.device.StartActivity(test_intent,
1183                                trace_file_name='test_trace_file.out')
1184
1185  def testStartActivity_withForceStop(self):
1186    test_intent = intent.Intent(action='android.intent.action.VIEW',
1187                                package='test.package',
1188                                activity='.Main')
1189    with self.assertCall(
1190        self.call.adb.Shell('am start '
1191                            '-S '
1192                            '-a android.intent.action.VIEW '
1193                            '-n test.package/.Main'),
1194        'Starting: Intent { act=android.intent.action.VIEW }'):
1195      self.device.StartActivity(test_intent, force_stop=True)
1196
1197  def testStartActivity_withFlags(self):
1198    test_intent = intent.Intent(action='android.intent.action.VIEW',
1199                                package='test.package',
1200                                activity='.Main',
1201                                flags='0x10000000')
1202    with self.assertCall(
1203        self.call.adb.Shell('am start '
1204                            '-a android.intent.action.VIEW '
1205                            '-n test.package/.Main '
1206                            '-f 0x10000000'),
1207        'Starting: Intent { act=android.intent.action.VIEW }'):
1208      self.device.StartActivity(test_intent)
1209
1210
1211class DeviceUtilsStartInstrumentationTest(DeviceUtilsTest):
1212
1213  def testStartInstrumentation_nothing(self):
1214    with self.assertCalls(
1215        self.call.device.RunShellCommand(
1216            'p=test.package;am instrument "$p"/.TestInstrumentation',
1217            check_return=True, large_output=True)):
1218      self.device.StartInstrumentation(
1219          'test.package/.TestInstrumentation',
1220          finish=False, raw=False, extras=None)
1221
1222  def testStartInstrumentation_finish(self):
1223    with self.assertCalls(
1224        (self.call.device.RunShellCommand(
1225            'p=test.package;am instrument -w "$p"/.TestInstrumentation',
1226            check_return=True, large_output=True),
1227         ['OK (1 test)'])):
1228      output = self.device.StartInstrumentation(
1229          'test.package/.TestInstrumentation',
1230          finish=True, raw=False, extras=None)
1231      self.assertEquals(['OK (1 test)'], output)
1232
1233  def testStartInstrumentation_raw(self):
1234    with self.assertCalls(
1235        self.call.device.RunShellCommand(
1236            'p=test.package;am instrument -r "$p"/.TestInstrumentation',
1237            check_return=True, large_output=True)):
1238      self.device.StartInstrumentation(
1239          'test.package/.TestInstrumentation',
1240          finish=False, raw=True, extras=None)
1241
1242  def testStartInstrumentation_extras(self):
1243    with self.assertCalls(
1244        self.call.device.RunShellCommand(
1245            'p=test.package;am instrument -e "$p".foo Foo -e bar \'Val \'"$p" '
1246            '"$p"/.TestInstrumentation',
1247            check_return=True, large_output=True)):
1248      self.device.StartInstrumentation(
1249          'test.package/.TestInstrumentation',
1250          finish=False, raw=False, extras={'test.package.foo': 'Foo',
1251                                           'bar': 'Val test.package'})
1252
1253
1254class DeviceUtilsBroadcastIntentTest(DeviceUtilsTest):
1255
1256  def testBroadcastIntent_noExtras(self):
1257    test_intent = intent.Intent(action='test.package.with.an.INTENT')
1258    with self.assertCall(
1259        self.call.adb.Shell('am broadcast -a test.package.with.an.INTENT'),
1260        'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
1261      self.device.BroadcastIntent(test_intent)
1262
1263  def testBroadcastIntent_withExtra(self):
1264    test_intent = intent.Intent(action='test.package.with.an.INTENT',
1265                                extras={'foo': 'bar value'})
1266    with self.assertCall(
1267        self.call.adb.Shell(
1268            "am broadcast -a test.package.with.an.INTENT --es foo 'bar value'"),
1269        'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
1270      self.device.BroadcastIntent(test_intent)
1271
1272  def testBroadcastIntent_withExtra_noValue(self):
1273    test_intent = intent.Intent(action='test.package.with.an.INTENT',
1274                                extras={'foo': None})
1275    with self.assertCall(
1276        self.call.adb.Shell(
1277            'am broadcast -a test.package.with.an.INTENT --esn foo'),
1278        'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
1279      self.device.BroadcastIntent(test_intent)
1280
1281
1282class DeviceUtilsGoHomeTest(DeviceUtilsTest):
1283
1284  def testGoHome_popupsExist(self):
1285    with self.assertCalls(
1286        (self.call.device.RunShellCommand(
1287            ['dumpsys', 'window', 'windows'], check_return=True,
1288            large_output=True), []),
1289        (self.call.device.RunShellCommand(
1290            ['am', 'start', '-W', '-a', 'android.intent.action.MAIN',
1291            '-c', 'android.intent.category.HOME'], check_return=True),
1292         'Starting: Intent { act=android.intent.action.MAIN }\r\n'''),
1293        (self.call.device.RunShellCommand(
1294            ['dumpsys', 'window', 'windows'], check_return=True,
1295            large_output=True), []),
1296        (self.call.device.RunShellCommand(
1297            ['input', 'keyevent', '66'], check_return=True)),
1298        (self.call.device.RunShellCommand(
1299            ['input', 'keyevent', '4'], check_return=True)),
1300        (self.call.device.RunShellCommand(
1301            ['dumpsys', 'window', 'windows'], check_return=True,
1302            large_output=True),
1303         ['mCurrentFocus Launcher'])):
1304      self.device.GoHome()
1305
1306  def testGoHome_willRetry(self):
1307    with self.assertCalls(
1308        (self.call.device.RunShellCommand(
1309            ['dumpsys', 'window', 'windows'], check_return=True,
1310            large_output=True), []),
1311        (self.call.device.RunShellCommand(
1312            ['am', 'start', '-W', '-a', 'android.intent.action.MAIN',
1313            '-c', 'android.intent.category.HOME'], check_return=True),
1314         'Starting: Intent { act=android.intent.action.MAIN }\r\n'''),
1315        (self.call.device.RunShellCommand(
1316            ['dumpsys', 'window', 'windows'], check_return=True,
1317            large_output=True), []),
1318        (self.call.device.RunShellCommand(
1319            ['input', 'keyevent', '66'], check_return=True,)),
1320        (self.call.device.RunShellCommand(
1321            ['input', 'keyevent', '4'], check_return=True)),
1322        (self.call.device.RunShellCommand(
1323            ['dumpsys', 'window', 'windows'], check_return=True,
1324            large_output=True), []),
1325        (self.call.device.RunShellCommand(
1326            ['input', 'keyevent', '66'], check_return=True)),
1327        (self.call.device.RunShellCommand(
1328            ['input', 'keyevent', '4'], check_return=True)),
1329        (self.call.device.RunShellCommand(
1330            ['dumpsys', 'window', 'windows'], check_return=True,
1331            large_output=True),
1332         self.TimeoutError())):
1333      with self.assertRaises(device_errors.CommandTimeoutError):
1334        self.device.GoHome()
1335
1336  def testGoHome_alreadyFocused(self):
1337    with self.assertCall(
1338        self.call.device.RunShellCommand(
1339            ['dumpsys', 'window', 'windows'], check_return=True,
1340            large_output=True),
1341        ['mCurrentFocus Launcher']):
1342      self.device.GoHome()
1343
1344  def testGoHome_alreadyFocusedAlternateCase(self):
1345    with self.assertCall(
1346        self.call.device.RunShellCommand(
1347            ['dumpsys', 'window', 'windows'], check_return=True,
1348            large_output=True),
1349        [' mCurrentFocus .launcher/.']):
1350      self.device.GoHome()
1351
1352  def testGoHome_obtainsFocusAfterGoingHome(self):
1353    with self.assertCalls(
1354        (self.call.device.RunShellCommand(
1355            ['dumpsys', 'window', 'windows'], check_return=True,
1356            large_output=True), []),
1357        (self.call.device.RunShellCommand(
1358            ['am', 'start', '-W', '-a', 'android.intent.action.MAIN',
1359            '-c', 'android.intent.category.HOME'], check_return=True),
1360         'Starting: Intent { act=android.intent.action.MAIN }\r\n'''),
1361        (self.call.device.RunShellCommand(
1362            ['dumpsys', 'window', 'windows'], check_return=True,
1363            large_output=True),
1364         ['mCurrentFocus Launcher'])):
1365      self.device.GoHome()
1366
1367
1368class DeviceUtilsForceStopTest(DeviceUtilsTest):
1369
1370  def testForceStop(self):
1371    with self.assertCall(
1372        self.call.adb.Shell('p=test.package;if [[ "$(ps)" = *$p* ]]; then '
1373                            'am force-stop $p; fi'),
1374        ''):
1375      self.device.ForceStop('test.package')
1376
1377
1378class DeviceUtilsClearApplicationStateTest(DeviceUtilsTest):
1379
1380  def testClearApplicationState_setPermissions(self):
1381    with self.assertCalls(
1382        (self.call.device.GetProp('ro.build.version.sdk', cache=True), '17'),
1383        (self.call.device._GetApplicationPathsInternal('this.package.exists'),
1384         ['/data/app/this.package.exists.apk']),
1385        (self.call.device.RunShellCommand(
1386            ['pm', 'clear', 'this.package.exists'],
1387            check_return=True),
1388         ['Success']),
1389        (self.call.device.GrantPermissions(
1390            'this.package.exists', ['p1']), [])):
1391      self.device.ClearApplicationState(
1392          'this.package.exists', permissions=['p1'])
1393
1394  def testClearApplicationState_packageDoesntExist(self):
1395    with self.assertCalls(
1396        (self.call.device.GetProp('ro.build.version.sdk', cache=True), '11'),
1397        (self.call.device._GetApplicationPathsInternal('does.not.exist'),
1398         [])):
1399      self.device.ClearApplicationState('does.not.exist')
1400
1401  def testClearApplicationState_packageDoesntExistOnAndroidJBMR2OrAbove(self):
1402    with self.assertCalls(
1403        (self.call.device.GetProp('ro.build.version.sdk', cache=True), '18'),
1404        (self.call.device.RunShellCommand(
1405            ['pm', 'clear', 'this.package.does.not.exist'],
1406            check_return=True),
1407         ['Failed'])):
1408      self.device.ClearApplicationState('this.package.does.not.exist')
1409
1410  def testClearApplicationState_packageExists(self):
1411    with self.assertCalls(
1412        (self.call.device.GetProp('ro.build.version.sdk', cache=True), '17'),
1413        (self.call.device._GetApplicationPathsInternal('this.package.exists'),
1414         ['/data/app/this.package.exists.apk']),
1415        (self.call.device.RunShellCommand(
1416            ['pm', 'clear', 'this.package.exists'],
1417            check_return=True),
1418         ['Success'])):
1419      self.device.ClearApplicationState('this.package.exists')
1420
1421  def testClearApplicationState_packageExistsOnAndroidJBMR2OrAbove(self):
1422    with self.assertCalls(
1423        (self.call.device.GetProp('ro.build.version.sdk', cache=True), '18'),
1424        (self.call.device.RunShellCommand(
1425            ['pm', 'clear', 'this.package.exists'],
1426            check_return=True),
1427         ['Success'])):
1428      self.device.ClearApplicationState('this.package.exists')
1429
1430
1431class DeviceUtilsSendKeyEventTest(DeviceUtilsTest):
1432
1433  def testSendKeyEvent(self):
1434    with self.assertCall(self.call.adb.Shell('input keyevent 66'), ''):
1435      self.device.SendKeyEvent(66)
1436
1437
1438class DeviceUtilsPushChangedFilesIndividuallyTest(DeviceUtilsTest):
1439
1440  def testPushChangedFilesIndividually_empty(self):
1441    test_files = []
1442    with self.assertCalls():
1443      self.device._PushChangedFilesIndividually(test_files)
1444
1445  def testPushChangedFilesIndividually_single(self):
1446    test_files = [('/test/host/path', '/test/device/path')]
1447    with self.assertCalls(self.call.adb.Push(*test_files[0])):
1448      self.device._PushChangedFilesIndividually(test_files)
1449
1450  def testPushChangedFilesIndividually_multiple(self):
1451    test_files = [
1452        ('/test/host/path/file1', '/test/device/path/file1'),
1453        ('/test/host/path/file2', '/test/device/path/file2')]
1454    with self.assertCalls(
1455        self.call.adb.Push(*test_files[0]),
1456        self.call.adb.Push(*test_files[1])):
1457      self.device._PushChangedFilesIndividually(test_files)
1458
1459
1460class DeviceUtilsPushChangedFilesZippedTest(DeviceUtilsTest):
1461
1462  def testPushChangedFilesZipped_noUnzipCommand(self):
1463    test_files = [('/test/host/path/file1', '/test/device/path/file1')]
1464    mock_zip_temp = mock.mock_open()
1465    mock_zip_temp.return_value.name = '/test/temp/file/tmp.zip'
1466    with self.assertCalls(
1467        (mock.call.tempfile.NamedTemporaryFile(suffix='.zip'), mock_zip_temp),
1468        (mock.call.multiprocessing.Process(
1469            target=device_utils.DeviceUtils._CreateDeviceZip,
1470            args=('/test/temp/file/tmp.zip', test_files)), mock.Mock()),
1471        (self.call.device._MaybeInstallCommands(), False)):
1472      self.assertFalse(self.device._PushChangedFilesZipped(test_files,
1473                                                           ['/test/dir']))
1474
1475  def _testPushChangedFilesZipped_spec(self, test_files):
1476    mock_zip_temp = mock.mock_open()
1477    mock_zip_temp.return_value.name = '/test/temp/file/tmp.zip'
1478    with self.assertCalls(
1479        (mock.call.tempfile.NamedTemporaryFile(suffix='.zip'), mock_zip_temp),
1480        (mock.call.multiprocessing.Process(
1481            target=device_utils.DeviceUtils._CreateDeviceZip,
1482            args=('/test/temp/file/tmp.zip', test_files)), mock.Mock()),
1483        (self.call.device._MaybeInstallCommands(), True),
1484        (self.call.device.NeedsSU(), True),
1485        (mock.call.devil.android.device_temp_file.DeviceTempFile(self.adb,
1486                                                                 suffix='.zip'),
1487             MockTempFile('/test/sdcard/foo123.zip')),
1488        self.call.adb.Push(
1489            '/test/temp/file/tmp.zip', '/test/sdcard/foo123.zip'),
1490        self.call.device.RunShellCommand(
1491            'unzip /test/sdcard/foo123.zip&&chmod -R 777 /test/dir',
1492            as_root=True,
1493            env={'PATH': '/data/local/tmp/bin:$PATH'},
1494            check_return=True)):
1495      self.assertTrue(self.device._PushChangedFilesZipped(test_files,
1496                                                          ['/test/dir']))
1497
1498  def testPushChangedFilesZipped_single(self):
1499    self._testPushChangedFilesZipped_spec(
1500        [('/test/host/path/file1', '/test/device/path/file1')])
1501
1502  def testPushChangedFilesZipped_multiple(self):
1503    self._testPushChangedFilesZipped_spec(
1504        [('/test/host/path/file1', '/test/device/path/file1'),
1505         ('/test/host/path/file2', '/test/device/path/file2')])
1506
1507
1508class DeviceUtilsPathExistsTest(DeviceUtilsTest):
1509
1510  def testPathExists_pathExists(self):
1511    with self.assertCall(
1512        self.call.device.RunShellCommand(
1513            "test -e '/path/file exists'",
1514            as_root=False, check_return=True, timeout=10, retries=0),
1515        []):
1516      self.assertTrue(self.device.PathExists('/path/file exists'))
1517
1518  def testPathExists_multiplePathExists(self):
1519    with self.assertCall(
1520        self.call.device.RunShellCommand(
1521            "test -e '/path 1' -a -e /path2",
1522            as_root=False, check_return=True, timeout=10, retries=0),
1523        []):
1524      self.assertTrue(self.device.PathExists(('/path 1', '/path2')))
1525
1526  def testPathExists_pathDoesntExist(self):
1527    with self.assertCall(
1528        self.call.device.RunShellCommand(
1529            "test -e /path/file.not.exists",
1530            as_root=False, check_return=True, timeout=10, retries=0),
1531        self.ShellError()):
1532      self.assertFalse(self.device.PathExists('/path/file.not.exists'))
1533
1534  def testPathExists_asRoot(self):
1535    with self.assertCall(
1536        self.call.device.RunShellCommand(
1537            "test -e /root/path/exists",
1538            as_root=True, check_return=True, timeout=10, retries=0),
1539        self.ShellError()):
1540      self.assertFalse(
1541          self.device.PathExists('/root/path/exists', as_root=True))
1542
1543  def testFileExists_pathDoesntExist(self):
1544    with self.assertCall(
1545        self.call.device.RunShellCommand(
1546            "test -e /path/file.not.exists",
1547            as_root=False, check_return=True, timeout=10, retries=0),
1548        self.ShellError()):
1549      self.assertFalse(self.device.FileExists('/path/file.not.exists'))
1550
1551
1552class DeviceUtilsPullFileTest(DeviceUtilsTest):
1553
1554  def testPullFile_existsOnDevice(self):
1555    with mock.patch('os.path.exists', return_value=True):
1556      with self.assertCall(
1557          self.call.adb.Pull('/data/app/test.file.exists',
1558                             '/test/file/host/path')):
1559        self.device.PullFile('/data/app/test.file.exists',
1560                             '/test/file/host/path')
1561
1562  def testPullFile_doesntExistOnDevice(self):
1563    with mock.patch('os.path.exists', return_value=True):
1564      with self.assertCall(
1565          self.call.adb.Pull('/data/app/test.file.does.not.exist',
1566                             '/test/file/host/path'),
1567          self.CommandError('remote object does not exist')):
1568        with self.assertRaises(device_errors.CommandFailedError):
1569          self.device.PullFile('/data/app/test.file.does.not.exist',
1570                               '/test/file/host/path')
1571
1572
1573class DeviceUtilsReadFileTest(DeviceUtilsTest):
1574
1575  def testReadFileWithPull_success(self):
1576    tmp_host_dir = '/tmp/dir/on.host/'
1577    tmp_host = MockTempFile('/tmp/dir/on.host/tmp_ReadFileWithPull')
1578    tmp_host.file.read.return_value = 'some interesting contents'
1579    with self.assertCalls(
1580        (mock.call.tempfile.mkdtemp(), tmp_host_dir),
1581        (self.call.adb.Pull('/path/to/device/file', mock.ANY)),
1582        (mock.call.__builtin__.open(mock.ANY, 'r'), tmp_host),
1583        (mock.call.os.path.exists(tmp_host_dir), True),
1584        (mock.call.shutil.rmtree(tmp_host_dir), None)):
1585      self.assertEquals('some interesting contents',
1586                        self.device._ReadFileWithPull('/path/to/device/file'))
1587    tmp_host.file.read.assert_called_once_with()
1588
1589  def testReadFileWithPull_rejected(self):
1590    tmp_host_dir = '/tmp/dir/on.host/'
1591    with self.assertCalls(
1592        (mock.call.tempfile.mkdtemp(), tmp_host_dir),
1593        (self.call.adb.Pull('/path/to/device/file', mock.ANY),
1594         self.CommandError()),
1595        (mock.call.os.path.exists(tmp_host_dir), True),
1596        (mock.call.shutil.rmtree(tmp_host_dir), None)):
1597      with self.assertRaises(device_errors.CommandFailedError):
1598        self.device._ReadFileWithPull('/path/to/device/file')
1599
1600  def testReadFile_exists(self):
1601    with self.assertCalls(
1602        (self.call.device.RunShellCommand(
1603            ['ls', '-l', '/read/this/test/file'],
1604            as_root=False, check_return=True),
1605         ['-rw-rw---- root foo 256 1970-01-01 00:00 file']),
1606        (self.call.device.RunShellCommand(
1607            ['cat', '/read/this/test/file'],
1608            as_root=False, check_return=True),
1609         ['this is a test file'])):
1610      self.assertEqual('this is a test file\n',
1611                       self.device.ReadFile('/read/this/test/file'))
1612
1613  def testReadFile_exists2(self):
1614    # Same as testReadFile_exists, but uses Android N ls output.
1615    with self.assertCalls(
1616        (self.call.device.RunShellCommand(
1617            ['ls', '-l', '/read/this/test/file'],
1618            as_root=False, check_return=True),
1619         ['-rw-rw-rw- 1 root root 256 2016-03-15 03:27 /read/this/test/file']),
1620        (self.call.device.RunShellCommand(
1621            ['cat', '/read/this/test/file'],
1622            as_root=False, check_return=True),
1623         ['this is a test file'])):
1624      self.assertEqual('this is a test file\n',
1625                       self.device.ReadFile('/read/this/test/file'))
1626
1627  def testReadFile_doesNotExist(self):
1628    with self.assertCall(
1629        self.call.device.RunShellCommand(
1630            ['ls', '-l', '/this/file/does.not.exist'],
1631            as_root=False, check_return=True),
1632        self.CommandError('File does not exist')):
1633      with self.assertRaises(device_errors.CommandFailedError):
1634        self.device.ReadFile('/this/file/does.not.exist')
1635
1636  def testReadFile_zeroSize(self):
1637    with self.assertCalls(
1638        (self.call.device.RunShellCommand(
1639            ['ls', '-l', '/this/file/has/zero/size'],
1640            as_root=False, check_return=True),
1641         ['-r--r--r-- root foo 0 1970-01-01 00:00 zero_size_file']),
1642        (self.call.device._ReadFileWithPull('/this/file/has/zero/size'),
1643         'but it has contents\n')):
1644      self.assertEqual('but it has contents\n',
1645                       self.device.ReadFile('/this/file/has/zero/size'))
1646
1647  def testReadFile_withSU(self):
1648    with self.assertCalls(
1649        (self.call.device.RunShellCommand(
1650            ['ls', '-l', '/this/file/can.be.read.with.su'],
1651            as_root=True, check_return=True),
1652         ['-rw------- root root 256 1970-01-01 00:00 can.be.read.with.su']),
1653        (self.call.device.RunShellCommand(
1654            ['cat', '/this/file/can.be.read.with.su'],
1655            as_root=True, check_return=True),
1656         ['this is a test file', 'read with su'])):
1657      self.assertEqual(
1658          'this is a test file\nread with su\n',
1659          self.device.ReadFile('/this/file/can.be.read.with.su',
1660                               as_root=True))
1661
1662  def testReadFile_withPull(self):
1663    contents = 'a' * 123456
1664    with self.assertCalls(
1665        (self.call.device.RunShellCommand(
1666            ['ls', '-l', '/read/this/big/test/file'],
1667            as_root=False, check_return=True),
1668         ['-rw-rw---- root foo 123456 1970-01-01 00:00 file']),
1669        (self.call.device._ReadFileWithPull('/read/this/big/test/file'),
1670         contents)):
1671      self.assertEqual(
1672          contents, self.device.ReadFile('/read/this/big/test/file'))
1673
1674  def testReadFile_withPullAndSU(self):
1675    contents = 'b' * 123456
1676    with self.assertCalls(
1677        (self.call.device.RunShellCommand(
1678            ['ls', '-l', '/this/big/file/can.be.read.with.su'],
1679            as_root=True, check_return=True),
1680         ['-rw------- root root 123456 1970-01-01 00:00 can.be.read.with.su']),
1681        (self.call.device.NeedsSU(), True),
1682        (mock.call.devil.android.device_temp_file.DeviceTempFile(self.adb),
1683         MockTempFile('/sdcard/tmp/on.device')),
1684        self.call.device.RunShellCommand(
1685            'SRC=/this/big/file/can.be.read.with.su DEST=/sdcard/tmp/on.device;'
1686            'cp "$SRC" "$DEST" && chmod 666 "$DEST"',
1687            as_root=True, check_return=True),
1688        (self.call.device._ReadFileWithPull('/sdcard/tmp/on.device'),
1689         contents)):
1690      self.assertEqual(
1691          contents,
1692          self.device.ReadFile('/this/big/file/can.be.read.with.su',
1693                               as_root=True))
1694
1695  def testReadFile_forcePull(self):
1696    contents = 'a' * 123456
1697    with self.assertCall(
1698        self.call.device._ReadFileWithPull('/read/this/big/test/file'),
1699        contents):
1700      self.assertEqual(
1701          contents,
1702          self.device.ReadFile('/read/this/big/test/file', force_pull=True))
1703
1704
1705class DeviceUtilsWriteFileTest(DeviceUtilsTest):
1706
1707  def testWriteFileWithPush_success(self):
1708    tmp_host = MockTempFile('/tmp/file/on.host')
1709    contents = 'some interesting contents'
1710    with self.assertCalls(
1711        (mock.call.tempfile.NamedTemporaryFile(), tmp_host),
1712        self.call.adb.Push('/tmp/file/on.host', '/path/to/device/file')):
1713      self.device._WriteFileWithPush('/path/to/device/file', contents)
1714    tmp_host.file.write.assert_called_once_with(contents)
1715
1716  def testWriteFileWithPush_rejected(self):
1717    tmp_host = MockTempFile('/tmp/file/on.host')
1718    contents = 'some interesting contents'
1719    with self.assertCalls(
1720        (mock.call.tempfile.NamedTemporaryFile(), tmp_host),
1721        (self.call.adb.Push('/tmp/file/on.host', '/path/to/device/file'),
1722         self.CommandError())):
1723      with self.assertRaises(device_errors.CommandFailedError):
1724        self.device._WriteFileWithPush('/path/to/device/file', contents)
1725
1726  def testWriteFile_withPush(self):
1727    contents = 'some large contents ' * 26  # 20 * 26 = 520 chars
1728    with self.assertCalls(
1729        self.call.device._WriteFileWithPush('/path/to/device/file', contents)):
1730      self.device.WriteFile('/path/to/device/file', contents)
1731
1732  def testWriteFile_withPushForced(self):
1733    contents = 'tiny contents'
1734    with self.assertCalls(
1735        self.call.device._WriteFileWithPush('/path/to/device/file', contents)):
1736      self.device.WriteFile('/path/to/device/file', contents, force_push=True)
1737
1738  def testWriteFile_withPushAndSU(self):
1739    contents = 'some large contents ' * 26  # 20 * 26 = 520 chars
1740    with self.assertCalls(
1741        (self.call.device.NeedsSU(), True),
1742        (mock.call.devil.android.device_temp_file.DeviceTempFile(self.adb),
1743         MockTempFile('/sdcard/tmp/on.device')),
1744        self.call.device._WriteFileWithPush('/sdcard/tmp/on.device', contents),
1745        self.call.device.RunShellCommand(
1746            ['cp', '/sdcard/tmp/on.device', '/path/to/device/file'],
1747            as_root=True, check_return=True)):
1748      self.device.WriteFile('/path/to/device/file', contents, as_root=True)
1749
1750  def testWriteFile_withEcho(self):
1751    with self.assertCall(self.call.adb.Shell(
1752        "echo -n the.contents > /test/file/to.write"), ''):
1753      self.device.WriteFile('/test/file/to.write', 'the.contents')
1754
1755  def testWriteFile_withEchoAndQuotes(self):
1756    with self.assertCall(self.call.adb.Shell(
1757        "echo -n 'the contents' > '/test/file/to write'"), ''):
1758      self.device.WriteFile('/test/file/to write', 'the contents')
1759
1760  def testWriteFile_withEchoAndSU(self):
1761    expected_cmd_without_su = "sh -c 'echo -n contents > /test/file'"
1762    expected_cmd = 'su -c %s' % expected_cmd_without_su
1763    with self.assertCalls(
1764        (self.call.device.NeedsSU(), True),
1765        (self.call.device._Su(expected_cmd_without_su), expected_cmd),
1766        (self.call.adb.Shell(expected_cmd),
1767         '')):
1768      self.device.WriteFile('/test/file', 'contents', as_root=True)
1769
1770
1771class DeviceUtilsLsTest(DeviceUtilsTest):
1772
1773  def testLs_directory(self):
1774    result = [('.', adb_wrapper.DeviceStat(16889, 4096, 1417436123)),
1775              ('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)),
1776              ('testfile.txt', adb_wrapper.DeviceStat(33206, 3, 1417436122))]
1777    with self.assertCalls(
1778        (self.call.adb.Ls('/data/local/tmp'), result)):
1779      self.assertEquals(result,
1780                        self.device.Ls('/data/local/tmp'))
1781
1782  def testLs_nothing(self):
1783    with self.assertCalls(
1784        (self.call.adb.Ls('/data/local/tmp/testfile.txt'), [])):
1785      self.assertEquals([],
1786                        self.device.Ls('/data/local/tmp/testfile.txt'))
1787
1788
1789class DeviceUtilsStatTest(DeviceUtilsTest):
1790
1791  def testStat_file(self):
1792    result = [('.', adb_wrapper.DeviceStat(16889, 4096, 1417436123)),
1793              ('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)),
1794              ('testfile.txt', adb_wrapper.DeviceStat(33206, 3, 1417436122))]
1795    with self.assertCalls(
1796        (self.call.adb.Ls('/data/local/tmp'), result)):
1797      self.assertEquals(adb_wrapper.DeviceStat(33206, 3, 1417436122),
1798                        self.device.Stat('/data/local/tmp/testfile.txt'))
1799
1800  def testStat_directory(self):
1801    result = [('.', adb_wrapper.DeviceStat(16873, 4096, 12382237)),
1802              ('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)),
1803              ('tmp', adb_wrapper.DeviceStat(16889, 4096, 1417436123))]
1804    with self.assertCalls(
1805        (self.call.adb.Ls('/data/local'), result)):
1806      self.assertEquals(adb_wrapper.DeviceStat(16889, 4096, 1417436123),
1807                        self.device.Stat('/data/local/tmp'))
1808
1809  def testStat_doesNotExist(self):
1810    result = [('.', adb_wrapper.DeviceStat(16889, 4096, 1417436123)),
1811              ('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)),
1812              ('testfile.txt', adb_wrapper.DeviceStat(33206, 3, 1417436122))]
1813    with self.assertCalls(
1814        (self.call.adb.Ls('/data/local/tmp'), result)):
1815      with self.assertRaises(device_errors.CommandFailedError):
1816        self.device.Stat('/data/local/tmp/does.not.exist.txt')
1817
1818
1819class DeviceUtilsSetJavaAssertsTest(DeviceUtilsTest):
1820
1821  def testSetJavaAsserts_enable(self):
1822    with self.assertCalls(
1823        (self.call.device.ReadFile(self.device.LOCAL_PROPERTIES_PATH),
1824         'some.example.prop=with an example value\n'
1825         'some.other.prop=value_ok\n'),
1826        self.call.device.WriteFile(
1827            self.device.LOCAL_PROPERTIES_PATH,
1828            'some.example.prop=with an example value\n'
1829            'some.other.prop=value_ok\n'
1830            'dalvik.vm.enableassertions=all\n'),
1831        (self.call.device.GetProp('dalvik.vm.enableassertions'), ''),
1832        self.call.device.SetProp('dalvik.vm.enableassertions', 'all')):
1833      self.assertTrue(self.device.SetJavaAsserts(True))
1834
1835  def testSetJavaAsserts_disable(self):
1836    with self.assertCalls(
1837        (self.call.device.ReadFile(self.device.LOCAL_PROPERTIES_PATH),
1838         'some.example.prop=with an example value\n'
1839         'dalvik.vm.enableassertions=all\n'
1840         'some.other.prop=value_ok\n'),
1841        self.call.device.WriteFile(
1842            self.device.LOCAL_PROPERTIES_PATH,
1843            'some.example.prop=with an example value\n'
1844            'some.other.prop=value_ok\n'),
1845        (self.call.device.GetProp('dalvik.vm.enableassertions'), 'all'),
1846        self.call.device.SetProp('dalvik.vm.enableassertions', '')):
1847      self.assertTrue(self.device.SetJavaAsserts(False))
1848
1849  def testSetJavaAsserts_alreadyEnabled(self):
1850    with self.assertCalls(
1851        (self.call.device.ReadFile(self.device.LOCAL_PROPERTIES_PATH),
1852         'some.example.prop=with an example value\n'
1853         'dalvik.vm.enableassertions=all\n'
1854         'some.other.prop=value_ok\n'),
1855        (self.call.device.GetProp('dalvik.vm.enableassertions'), 'all')):
1856      self.assertFalse(self.device.SetJavaAsserts(True))
1857
1858  def testSetJavaAsserts_malformedLocalProp(self):
1859    with self.assertCalls(
1860        (self.call.device.ReadFile(self.device.LOCAL_PROPERTIES_PATH),
1861         'some.example.prop=with an example value\n'
1862         'malformed_property\n'
1863         'dalvik.vm.enableassertions=all\n'
1864         'some.other.prop=value_ok\n'),
1865        (self.call.device.GetProp('dalvik.vm.enableassertions'), 'all')):
1866      self.assertFalse(self.device.SetJavaAsserts(True))
1867
1868
1869class DeviceUtilsGetPropTest(DeviceUtilsTest):
1870
1871  def testGetProp_exists(self):
1872    with self.assertCall(
1873        self.call.device.RunShellCommand(
1874            ['getprop', 'test.property'], check_return=True, single_line=True,
1875            timeout=self.device._default_timeout,
1876            retries=self.device._default_retries),
1877        'property_value'):
1878      self.assertEqual('property_value',
1879                       self.device.GetProp('test.property'))
1880
1881  def testGetProp_doesNotExist(self):
1882    with self.assertCall(
1883        self.call.device.RunShellCommand(
1884            ['getprop', 'property.does.not.exist'],
1885            check_return=True, single_line=True,
1886            timeout=self.device._default_timeout,
1887            retries=self.device._default_retries),
1888        ''):
1889      self.assertEqual('', self.device.GetProp('property.does.not.exist'))
1890
1891  def testGetProp_cachedRoProp(self):
1892    with self.assertCall(
1893        self.call.device.RunShellCommand(
1894            ['getprop'], check_return=True, large_output=True,
1895            timeout=self.device._default_timeout,
1896            retries=self.device._default_retries),
1897        ['[ro.build.type]: [userdebug]']):
1898      self.assertEqual('userdebug',
1899                       self.device.GetProp('ro.build.type', cache=True))
1900      self.assertEqual('userdebug',
1901                       self.device.GetProp('ro.build.type', cache=True))
1902
1903  def testGetProp_retryAndCache(self):
1904    with self.assertCalls(
1905        (self.call.device.RunShellCommand(
1906            ['getprop'], check_return=True, large_output=True,
1907            timeout=self.device._default_timeout,
1908            retries=3),
1909         ['[ro.build.type]: [userdebug]'])):
1910      self.assertEqual('userdebug',
1911                       self.device.GetProp('ro.build.type',
1912                                           cache=True, retries=3))
1913      self.assertEqual('userdebug',
1914                       self.device.GetProp('ro.build.type',
1915                                           cache=True, retries=3))
1916
1917
1918class DeviceUtilsSetPropTest(DeviceUtilsTest):
1919
1920  def testSetProp(self):
1921    with self.assertCall(
1922        self.call.device.RunShellCommand(
1923            ['setprop', 'test.property', 'test value'], check_return=True)):
1924      self.device.SetProp('test.property', 'test value')
1925
1926  def testSetProp_check_succeeds(self):
1927    with self.assertCalls(
1928        (self.call.device.RunShellCommand(
1929            ['setprop', 'test.property', 'new_value'], check_return=True)),
1930        (self.call.device.GetProp('test.property', cache=False), 'new_value')):
1931      self.device.SetProp('test.property', 'new_value', check=True)
1932
1933  def testSetProp_check_fails(self):
1934    with self.assertCalls(
1935        (self.call.device.RunShellCommand(
1936            ['setprop', 'test.property', 'new_value'], check_return=True)),
1937        (self.call.device.GetProp('test.property', cache=False), 'old_value')):
1938      with self.assertRaises(device_errors.CommandFailedError):
1939        self.device.SetProp('test.property', 'new_value', check=True)
1940
1941
1942class DeviceUtilsGetPidsTest(DeviceUtilsTest):
1943
1944  def testGetPids_noMatches(self):
1945    with self.assertCall(
1946        self.call.device._RunPipedShellCommand('ps | grep -F does.not.match'),
1947        []):
1948      self.assertEqual({}, self.device.GetPids('does.not.match'))
1949
1950  def testGetPids_oneMatch(self):
1951    with self.assertCall(
1952        self.call.device._RunPipedShellCommand('ps | grep -F one.match'),
1953        ['user  1001    100   1024 1024   ffffffff 00000000 one.match']):
1954      self.assertEqual(
1955          {'one.match': ['1001']},
1956          self.device.GetPids('one.match'))
1957
1958  def testGetPids_multipleMatches(self):
1959    with self.assertCall(
1960        self.call.device._RunPipedShellCommand('ps | grep -F match'),
1961        ['user  1001    100   1024 1024   ffffffff 00000000 one.match',
1962         'user  1002    100   1024 1024   ffffffff 00000000 two.match',
1963         'user  1003    100   1024 1024   ffffffff 00000000 three.match']):
1964      self.assertEqual(
1965          {'one.match': ['1001'],
1966           'two.match': ['1002'],
1967           'three.match': ['1003']},
1968          self.device.GetPids('match'))
1969
1970  def testGetPids_exactMatch(self):
1971    with self.assertCall(
1972        self.call.device._RunPipedShellCommand('ps | grep -F exact.match'),
1973        ['user  1000    100   1024 1024   ffffffff 00000000 not.exact.match',
1974         'user  1234    100   1024 1024   ffffffff 00000000 exact.match']):
1975      self.assertEqual(
1976          {'not.exact.match': ['1000'], 'exact.match': ['1234']},
1977          self.device.GetPids('exact.match'))
1978
1979  def testGetPids_quotable(self):
1980    with self.assertCall(
1981        self.call.device._RunPipedShellCommand("ps | grep -F 'my$process'"),
1982        ['user  1234    100   1024 1024   ffffffff 00000000 my$process']):
1983      self.assertEqual(
1984          {'my$process': ['1234']}, self.device.GetPids('my$process'))
1985
1986  def testGetPids_multipleInstances(self):
1987    with self.assertCall(
1988        self.call.device._RunPipedShellCommand('ps | grep -F foo'),
1989        ['user  1000    100   1024 1024   ffffffff 00000000 foo',
1990         'user  1234    100   1024 1024   ffffffff 00000000 foo']):
1991      self.assertEqual(
1992          {'foo': ['1000', '1234']},
1993          self.device.GetPids('foo'))
1994
1995
1996class DeviceUtilsTakeScreenshotTest(DeviceUtilsTest):
1997
1998  def testTakeScreenshot_fileNameProvided(self):
1999    with self.assertCalls(
2000        (mock.call.devil.android.device_temp_file.DeviceTempFile(
2001            self.adb, suffix='.png'),
2002         MockTempFile('/tmp/path/temp-123.png')),
2003        (self.call.adb.Shell('/system/bin/screencap -p /tmp/path/temp-123.png'),
2004         ''),
2005        self.call.device.PullFile('/tmp/path/temp-123.png',
2006                                  '/test/host/screenshot.png')):
2007      self.device.TakeScreenshot('/test/host/screenshot.png')
2008
2009
2010class DeviceUtilsGetMemoryUsageForPidTest(DeviceUtilsTest):
2011
2012  def setUp(self):
2013    super(DeviceUtilsGetMemoryUsageForPidTest, self).setUp()
2014
2015  def testGetMemoryUsageForPid_validPid(self):
2016    with self.assertCalls(
2017        (self.call.device._RunPipedShellCommand(
2018            'showmap 1234 | grep TOTAL', as_root=True),
2019         ['100 101 102 103 104 105 106 107 TOTAL']),
2020        (self.call.device.ReadFile('/proc/1234/status', as_root=True),
2021         'VmHWM: 1024 kB\n')):
2022      self.assertEqual(
2023          {
2024            'Size': 100,
2025            'Rss': 101,
2026            'Pss': 102,
2027            'Shared_Clean': 103,
2028            'Shared_Dirty': 104,
2029            'Private_Clean': 105,
2030            'Private_Dirty': 106,
2031            'VmHWM': 1024
2032          },
2033          self.device.GetMemoryUsageForPid(1234))
2034
2035  def testGetMemoryUsageForPid_noSmaps(self):
2036    with self.assertCalls(
2037        (self.call.device._RunPipedShellCommand(
2038            'showmap 4321 | grep TOTAL', as_root=True),
2039         ['cannot open /proc/4321/smaps: No such file or directory']),
2040        (self.call.device.ReadFile('/proc/4321/status', as_root=True),
2041         'VmHWM: 1024 kb\n')):
2042      self.assertEquals({'VmHWM': 1024}, self.device.GetMemoryUsageForPid(4321))
2043
2044  def testGetMemoryUsageForPid_noStatus(self):
2045    with self.assertCalls(
2046        (self.call.device._RunPipedShellCommand(
2047            'showmap 4321 | grep TOTAL', as_root=True),
2048         ['100 101 102 103 104 105 106 107 TOTAL']),
2049        (self.call.device.ReadFile('/proc/4321/status', as_root=True),
2050         self.CommandError())):
2051      self.assertEquals(
2052          {
2053            'Size': 100,
2054            'Rss': 101,
2055            'Pss': 102,
2056            'Shared_Clean': 103,
2057            'Shared_Dirty': 104,
2058            'Private_Clean': 105,
2059            'Private_Dirty': 106,
2060          },
2061          self.device.GetMemoryUsageForPid(4321))
2062
2063
2064class DeviceUtilsDismissCrashDialogIfNeededTest(DeviceUtilsTest):
2065
2066  def testDismissCrashDialogIfNeeded_crashedPageckageNotFound(self):
2067    sample_dumpsys_output = '''
2068WINDOW MANAGER WINDOWS (dumpsys window windows)
2069  Window #11 Window{f8b647a u0 SearchPanel}:
2070    mDisplayId=0 mSession=Session{8 94:122} mClient=android.os.BinderProxy@1ba5
2071    mOwnerUid=100 mShowToOwnerOnly=false package=com.android.systemui appop=NONE
2072    mAttrs=WM.LayoutParams{(0,0)(fillxfill) gr=#53 sim=#31 ty=2024 fl=100
2073    Requested w=1080 h=1920 mLayoutSeq=426
2074    mBaseLayer=211000 mSubLayer=0 mAnimLayer=211000+0=211000 mLastLayer=211000
2075'''
2076    with self.assertCalls(
2077        (self.call.device.RunShellCommand(
2078            ['dumpsys', 'window', 'windows'], check_return=True,
2079            large_output=True), sample_dumpsys_output.split('\n'))):
2080      package_name = self.device.DismissCrashDialogIfNeeded()
2081      self.assertIsNone(package_name)
2082
2083  def testDismissCrashDialogIfNeeded_crashedPageckageFound(self):
2084    sample_dumpsys_output = '''
2085WINDOW MANAGER WINDOWS (dumpsys window windows)
2086  Window #11 Window{f8b647a u0 SearchPanel}:
2087    mDisplayId=0 mSession=Session{8 94:122} mClient=android.os.BinderProxy@1ba5
2088    mOwnerUid=102 mShowToOwnerOnly=false package=com.android.systemui appop=NONE
2089    mAttrs=WM.LayoutParams{(0,0)(fillxfill) gr=#53 sim=#31 ty=2024 fl=100
2090    Requested w=1080 h=1920 mLayoutSeq=426
2091    mBaseLayer=211000 mSubLayer=0 mAnimLayer=211000+0=211000 mLastLayer=211000
2092  mHasPermanentDpad=false
2093  mCurrentFocus=Window{3a27740f u0 Application Error: com.android.chrome}
2094  mFocusedApp=AppWindowToken{470af6f token=Token{272ec24e ActivityRecord{t894}}}
2095'''
2096    with self.assertCalls(
2097        (self.call.device.RunShellCommand(
2098            ['dumpsys', 'window', 'windows'], check_return=True,
2099            large_output=True), sample_dumpsys_output.split('\n')),
2100        (self.call.device.RunShellCommand(
2101            ['input', 'keyevent', '22'], check_return=True)),
2102        (self.call.device.RunShellCommand(
2103            ['input', 'keyevent', '22'], check_return=True)),
2104        (self.call.device.RunShellCommand(
2105            ['input', 'keyevent', '66'], check_return=True)),
2106        (self.call.device.RunShellCommand(
2107            ['dumpsys', 'window', 'windows'], check_return=True,
2108            large_output=True), [])):
2109      package_name = self.device.DismissCrashDialogIfNeeded()
2110      self.assertEqual(package_name, 'com.android.chrome')
2111
2112
2113class DeviceUtilsClientCache(DeviceUtilsTest):
2114
2115  def testClientCache_twoCaches(self):
2116    self.device._cache['test'] = 0
2117    client_cache_one = self.device.GetClientCache('ClientOne')
2118    client_cache_one['test'] = 1
2119    client_cache_two = self.device.GetClientCache('ClientTwo')
2120    client_cache_two['test'] = 2
2121    self.assertEqual(self.device._cache['test'], 0)
2122    self.assertEqual(client_cache_one, {'test': 1})
2123    self.assertEqual(client_cache_two, {'test': 2})
2124    self.device._ClearCache()
2125    self.assertTrue('test' not in self.device._cache)
2126    self.assertEqual(client_cache_one, {})
2127    self.assertEqual(client_cache_two, {})
2128
2129  def testClientCache_multipleInstances(self):
2130    client_cache_one = self.device.GetClientCache('ClientOne')
2131    client_cache_one['test'] = 1
2132    client_cache_two = self.device.GetClientCache('ClientOne')
2133    self.assertEqual(client_cache_one, {'test': 1})
2134    self.assertEqual(client_cache_two, {'test': 1})
2135    self.device._ClearCache()
2136    self.assertEqual(client_cache_one, {})
2137    self.assertEqual(client_cache_two, {})
2138
2139
2140class DeviceUtilsHealthyDevicesTest(mock_calls.TestCase):
2141
2142  def testHealthyDevices_emptyBlacklist(self):
2143    test_serials = ['0123456789abcdef', 'fedcba9876543210']
2144    with self.assertCalls(
2145        (mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(),
2146         [_AdbWrapperMock(s) for s in test_serials])):
2147      blacklist = mock.NonCallableMock(**{'Read.return_value': []})
2148      devices = device_utils.DeviceUtils.HealthyDevices(blacklist)
2149    for serial, device in zip(test_serials, devices):
2150      self.assertTrue(isinstance(device, device_utils.DeviceUtils))
2151      self.assertEquals(serial, device.adb.GetDeviceSerial())
2152
2153  def testHealthyDevices_blacklist(self):
2154    test_serials = ['0123456789abcdef', 'fedcba9876543210']
2155    with self.assertCalls(
2156        (mock.call.devil.android.sdk.adb_wrapper.AdbWrapper.Devices(),
2157         [_AdbWrapperMock(s) for s in test_serials])):
2158      blacklist = mock.NonCallableMock(
2159          **{'Read.return_value': ['fedcba9876543210']})
2160      devices = device_utils.DeviceUtils.HealthyDevices(blacklist)
2161    self.assertEquals(1, len(devices))
2162    self.assertTrue(isinstance(devices[0], device_utils.DeviceUtils))
2163    self.assertEquals('0123456789abcdef', devices[0].adb.GetDeviceSerial())
2164
2165
2166class DeviceUtilsRestartAdbdTest(DeviceUtilsTest):
2167
2168  def testAdbdRestart(self):
2169    mock_temp_file = '/sdcard/temp-123.sh'
2170    with self.assertCalls(
2171        (mock.call.devil.android.device_temp_file.DeviceTempFile(
2172            self.adb, suffix='.sh'), MockTempFile(mock_temp_file)),
2173        self.call.device.WriteFile(mock.ANY, mock.ANY),
2174        (self.call.device.RunShellCommand(
2175            ['source', mock_temp_file], as_root=True)),
2176        self.call.adb.WaitForDevice()):
2177      self.device.RestartAdbd()
2178
2179
2180class DeviceUtilsGrantPermissionsTest(DeviceUtilsTest):
2181
2182  def testGrantPermissions_none(self):
2183    self.device.GrantPermissions('package', [])
2184
2185  def testGrantPermissions_underM(self):
2186    with self.patch_call(self.call.device.build_version_sdk,
2187                         return_value=version_codes.LOLLIPOP):
2188      self.device.GrantPermissions('package', ['p1'])
2189
2190  def testGrantPermissions_one(self):
2191    permissions_cmd = 'pm grant package p1'
2192    with self.patch_call(self.call.device.build_version_sdk,
2193                         return_value=version_codes.MARSHMALLOW):
2194      with self.assertCalls(
2195          (self.call.device.RunShellCommand(
2196              permissions_cmd, check_return=True), [])):
2197        self.device.GrantPermissions('package', ['p1'])
2198
2199  def testGrantPermissions_multiple(self):
2200    permissions_cmd = 'pm grant package p1&&pm grant package p2'
2201    with self.patch_call(self.call.device.build_version_sdk,
2202                         return_value=version_codes.MARSHMALLOW):
2203      with self.assertCalls(
2204          (self.call.device.RunShellCommand(
2205              permissions_cmd, check_return=True), [])):
2206        self.device.GrantPermissions('package', ['p1', 'p2'])
2207
2208  def testGrantPermissions_WriteExtrnalStorage(self):
2209    permissions_cmd = (
2210        'pm grant package android.permission.WRITE_EXTERNAL_STORAGE&&'
2211        'pm grant package android.permission.READ_EXTERNAL_STORAGE')
2212    with self.patch_call(self.call.device.build_version_sdk,
2213                         return_value=version_codes.MARSHMALLOW):
2214      with self.assertCalls(
2215          (self.call.device.RunShellCommand(
2216              permissions_cmd, check_return=True), [])):
2217        self.device.GrantPermissions(
2218            'package', ['android.permission.WRITE_EXTERNAL_STORAGE'])
2219
2220  def testGrantPermissions_BlackList(self):
2221    with self.patch_call(self.call.device.build_version_sdk,
2222                         return_value=version_codes.MARSHMALLOW):
2223      self.device.GrantPermissions(
2224          'package', ['android.permission.ACCESS_MOCK_LOCATION'])
2225
2226
2227class DeviecUtilsIsScreenOn(DeviceUtilsTest):
2228
2229  _L_SCREEN_ON = ['test=test mInteractive=true']
2230  _K_SCREEN_ON = ['test=test mScreenOn=true']
2231  _L_SCREEN_OFF = ['mInteractive=false']
2232  _K_SCREEN_OFF = ['mScreenOn=false']
2233
2234  def testIsScreenOn_onPreL(self):
2235    with self.patch_call(self.call.device.build_version_sdk,
2236                         return_value=version_codes.KITKAT):
2237      with self.assertCalls(
2238          (self.call.device._RunPipedShellCommand(
2239              'dumpsys input_method | grep mScreenOn'), self._K_SCREEN_ON)):
2240        self.assertTrue(self.device.IsScreenOn())
2241
2242  def testIsScreenOn_onL(self):
2243    with self.patch_call(self.call.device.build_version_sdk,
2244                         return_value=version_codes.LOLLIPOP):
2245      with self.assertCalls(
2246          (self.call.device._RunPipedShellCommand(
2247              'dumpsys input_method | grep mInteractive'), self._L_SCREEN_ON)):
2248        self.assertTrue(self.device.IsScreenOn())
2249
2250  def testIsScreenOn_offPreL(self):
2251    with self.patch_call(self.call.device.build_version_sdk,
2252                         return_value=version_codes.KITKAT):
2253      with self.assertCalls(
2254          (self.call.device._RunPipedShellCommand(
2255              'dumpsys input_method | grep mScreenOn'), self._K_SCREEN_OFF)):
2256        self.assertFalse(self.device.IsScreenOn())
2257
2258  def testIsScreenOn_offL(self):
2259    with self.patch_call(self.call.device.build_version_sdk,
2260                         return_value=version_codes.LOLLIPOP):
2261      with self.assertCalls(
2262          (self.call.device._RunPipedShellCommand(
2263              'dumpsys input_method | grep mInteractive'), self._L_SCREEN_OFF)):
2264        self.assertFalse(self.device.IsScreenOn())
2265
2266  def testIsScreenOn_noOutput(self):
2267    with self.patch_call(self.call.device.build_version_sdk,
2268                         return_value=version_codes.LOLLIPOP):
2269      with self.assertCalls(
2270          (self.call.device._RunPipedShellCommand(
2271              'dumpsys input_method | grep mInteractive'), [])):
2272        with self.assertRaises(device_errors.CommandFailedError):
2273          self.device.IsScreenOn()
2274
2275
2276class DeviecUtilsSetScreen(DeviceUtilsTest):
2277
2278  @mock.patch('time.sleep', mock.Mock())
2279  def testSetScren_alreadySet(self):
2280    with self.assertCalls(
2281        (self.call.device.IsScreenOn(), False)):
2282      self.device.SetScreen(False)
2283
2284  @mock.patch('time.sleep', mock.Mock())
2285  def testSetScreen_on(self):
2286    with self.assertCalls(
2287        (self.call.device.IsScreenOn(), False),
2288        (self.call.device.RunShellCommand('input keyevent 26'), []),
2289        (self.call.device.IsScreenOn(), True)):
2290      self.device.SetScreen(True)
2291
2292  @mock.patch('time.sleep', mock.Mock())
2293  def testSetScreen_off(self):
2294    with self.assertCalls(
2295        (self.call.device.IsScreenOn(), True),
2296        (self.call.device.RunShellCommand('input keyevent 26'), []),
2297        (self.call.device.IsScreenOn(), False)):
2298      self.device.SetScreen(False)
2299
2300  @mock.patch('time.sleep', mock.Mock())
2301  def testSetScreen_slow(self):
2302    with self.assertCalls(
2303        (self.call.device.IsScreenOn(), True),
2304        (self.call.device.RunShellCommand('input keyevent 26'), []),
2305        (self.call.device.IsScreenOn(), True),
2306        (self.call.device.IsScreenOn(), True),
2307        (self.call.device.IsScreenOn(), False)):
2308      self.device.SetScreen(False)
2309
2310if __name__ == '__main__':
2311  logging.getLogger().setLevel(logging.DEBUG)
2312  unittest.main(verbosity=2)
2313