Update from https://crrev.com/328418
This includes the switch to libc++ on android.
Fixes outside of the rolled code:
*) ::TestSuite -> base::TestSuite
*) base::ScopedPtrHashMap's second parameter Value->scoped_ptr<Value>
*) re2 std::tr1 changes from upstream libc++ changes
*) tracked_objects:: api changes in mojo/common/task_tracker*
Review URL: https://codereview.chromium.org/1128733002
diff --git a/build/all.gyp b/build/all.gyp
index 255a35c..1866c2e 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -124,6 +124,7 @@
'../jingle/jingle.gyp:*',
'../media/cast/cast.gyp:*',
'../media/media.gyp:*',
+ '../media/midi/midi.gyp:*',
'../mojo/mojo.gyp:*',
'../mojo/mojo_base.gyp:*',
'../ppapi/ppapi.gyp:*',
@@ -318,6 +319,7 @@
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
'../ui/display/display.gyp:display_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
+ '../ui/gl/gl_tests.gyp:gl_unittests',
'../url/url.gyp:url_unittests',
],
'conditions': [
@@ -344,6 +346,7 @@
'../jingle/jingle.gyp:jingle_unittests',
'../media/cast/cast.gyp:cast_unittests',
'../media/media.gyp:media_unittests',
+ '../media/midi/midi.gyp:midi_unittests',
'../mojo/mojo.gyp:mojo',
'../ppapi/ppapi_internal.gyp:ppapi_unittests',
'../remoting/remoting.gyp:remoting_unittests',
@@ -567,6 +570,7 @@
'../content/content_shell_and_tests.gyp:content_shell',
'../gpu/gpu.gyp:gpu_perftests',
'../media/media.gyp:media_perftests',
+ '../media/midi/midi.gyp:midi_unittests',
'../tools/perf/clear_system_cache/clear_system_cache.gyp:*',
'../tools/telemetry/telemetry.gyp:*',
],
@@ -681,6 +685,7 @@
'../content/content_shell_and_tests.gyp:content_browsertests',
'../content/content_shell_and_tests.gyp:content_unittests',
'../media/media.gyp:media_unittests',
+ '../media/midi/midi.gyp:midi_unittests',
'../third_party/webrtc/tools/tools.gyp:frame_analyzer',
'../third_party/webrtc/tools/tools.gyp:rgba_to_i420_converter',
],
@@ -814,6 +819,8 @@
'../ipc/ipc.gyp:ipc_tests',
'../media/media.gyp:media_perftests_apk',
'../media/media.gyp:media_unittests',
+ '../media/midi/midi.gyp:midi_unittests_apk',
+ '../media/midi/midi.gyp:midi_unittests',
'../net/net.gyp:net_unittests',
'../sandbox/sandbox.gyp:sandbox_linux_unittests_deps',
'../skia/skia_tests.gyp:skia_unittests',
@@ -843,6 +850,7 @@
'../gpu/gpu.gyp:gpu_unittests_apk',
'../ipc/ipc.gyp:ipc_tests_apk',
'../media/media.gyp:media_unittests_apk',
+ '../media/midi/midi.gyp:midi_unittests_apk',
'../net/net.gyp:net_unittests_apk',
'../sandbox/sandbox.gyp:sandbox_linux_jni_unittests_apk',
'../skia/skia_tests.gyp:skia_unittests_apk',
@@ -853,6 +861,7 @@
'../ui/base/ui_base_tests.gyp:ui_base_unittests_apk',
'../ui/events/events.gyp:events_unittests_apk',
'../ui/gfx/gfx_tests.gyp:gfx_unittests_apk',
+ '../ui/gl/gl_tests.gyp:gl_unittests_apk',
'../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests_apk',
],
'conditions': [
@@ -929,6 +938,7 @@
'../ipc/mojo/ipc_mojo.gyp:ipc_mojo_unittests',
'../jingle/jingle.gyp:jingle_unittests',
'../media/media.gyp:media_unittests',
+ '../media/midi/midi.gyp:midi_unittests',
'../ppapi/ppapi_internal.gyp:ppapi_unittests',
'../printing/printing.gyp:printing_unittests',
'../remoting/remoting.gyp:remoting_unittests',
@@ -944,6 +954,7 @@
'../tools/telemetry/telemetry.gyp:*',
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
+ '../ui/gl/gl_tests.gyp:gl_unittests',
'../url/url.gyp:url_unittests',
],
},
@@ -968,6 +979,7 @@
'../ipc/mojo/ipc_mojo.gyp:ipc_mojo_unittests',
'../jingle/jingle.gyp:jingle_unittests',
'../media/media.gyp:media_unittests',
+ '../media/midi/midi.gyp:midi_unittests',
'../ppapi/ppapi_internal.gyp:ppapi_unittests',
'../printing/printing.gyp:printing_unittests',
'../remoting/remoting.gyp:remoting_unittests',
@@ -982,6 +994,7 @@
'../tools/telemetry/telemetry.gyp:*',
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
+ '../ui/gl/gl_tests.gyp:gl_unittests',
'../url/url.gyp:url_unittests',
],
},
@@ -995,6 +1008,7 @@
'../ipc/ipc.gyp:ipc_tests',
'../jingle/jingle.gyp:jingle_unittests',
'../media/media.gyp:media_unittests',
+ '../media/midi/midi.gyp:midi_unittests',
'../net/net.gyp:net_unittests',
'../printing/printing.gyp:printing_unittests',
'../remoting/remoting.gyp:remoting_unittests',
@@ -1018,6 +1032,7 @@
'../ipc/ipc.gyp:ipc_tests',
'../jingle/jingle.gyp:jingle_unittests',
'../media/media.gyp:media_unittests',
+ '../media/midi/midi.gyp:midi_unittests',
'../net/net.gyp:net_unittests',
'../google_apis/gcm/gcm.gyp:gcm_unit_tests',
'../printing/printing.gyp:printing_unittests',
@@ -1031,6 +1046,7 @@
'../third_party/libphonenumber/libphonenumber.gyp:libphonenumber_unittests',
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
+ '../ui/gl/gl_tests.gyp:gl_unittests',
'../url/url.gyp:url_unittests',
],
},
@@ -1069,6 +1085,7 @@
'../ipc/mojo/ipc_mojo.gyp:ipc_mojo_unittests',
'../jingle/jingle.gyp:jingle_unittests',
'../media/media.gyp:media_unittests',
+ '../media/midi/midi.gyp:midi_unittests',
'../ppapi/ppapi_internal.gyp:ppapi_unittests',
'../printing/printing.gyp:printing_unittests',
'../remoting/remoting.gyp:remoting_unittests',
@@ -1084,6 +1101,7 @@
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
'../ui/events/events.gyp:events_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
+ '../ui/gl/gl_tests.gyp:gl_unittests',
'../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
'../ui/views/views.gyp:views_unittests',
'../url/url.gyp:url_unittests',
@@ -1108,6 +1126,7 @@
'../ipc/ipc.gyp:ipc_tests',
'../jingle/jingle.gyp:jingle_unittests',
'../media/media.gyp:media_unittests',
+ '../media/midi/midi.gyp:midi_unittests',
'../net/net.gyp:net_unittests',
'../printing/printing.gyp:printing_unittests',
'../remoting/remoting.gyp:remoting_unittests',
@@ -1166,6 +1185,7 @@
'../jingle/jingle.gyp:jingle_unittests',
'../media/cast/cast.gyp:cast_unittests',
'../media/media.gyp:media_unittests',
+ '../media/midi/midi.gyp:midi_unittests',
'../mojo/mojo.gyp:mojo',
'../net/net.gyp:net_unittests',
'../printing/printing.gyp:printing_unittests',
@@ -1186,6 +1206,7 @@
'../ui/display/display.gyp:display_unittests',
'../ui/events/events.gyp:events_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
+ '../ui/gl/gl_tests.gyp:gl_unittests',
'../ui/keyboard/keyboard.gyp:keyboard_unittests',
'../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
'../url/url.gyp:url_unittests',
@@ -1234,12 +1255,14 @@
'../chrome/chrome.gyp:sync_integration_tests',
'../ipc/ipc.gyp:ipc_tests',
'../media/media.gyp:media_unittests',
+ '../media/midi/midi.gyp:midi_unittests',
'../net/net.gyp:net_unittests_run',
'../printing/printing.gyp:printing_unittests',
'../sql/sql.gyp:sql_unittests',
'../sync/sync.gyp:sync_unit_tests',
'../ui/base/ui_base_tests.gyp:ui_base_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
+ '../ui/gl/gl_tests.gyp:gl_unittests',
'../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
'../ui/views/views.gyp:views_unittests',
'../url/url.gyp:url_unittests',
@@ -1273,6 +1296,7 @@
'../ui/display/display.gyp:display_unittests',
'../ui/events/events.gyp:*',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
+ '../ui/gl/gl_tests.gyp:gl_unittests',
'../ui/keyboard/keyboard.gyp:*',
'../ui/snapshot/snapshot.gyp:snapshot_unittests',
'../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
diff --git a/build/android/PRESUBMIT.py b/build/android/PRESUBMIT.py
index 92095be..6e0a3de 100644
--- a/build/android/PRESUBMIT.py
+++ b/build/android/PRESUBMIT.py
@@ -42,6 +42,7 @@
input_api,
output_api,
unit_tests=[
+ J('pylib', 'base', 'test_dispatcher_unittest.py'),
J('pylib', 'device', 'battery_utils_test.py'),
J('pylib', 'device', 'device_utils_test.py'),
J('pylib', 'device', 'logcat_monitor_test.py'),
diff --git a/build/android/gyp/dex.py b/build/android/gyp/dex.py
index 4e62332..778a8c2 100755
--- a/build/android/gyp/dex.py
+++ b/build/android/gyp/dex.py
@@ -15,7 +15,9 @@
def DoDex(options, paths):
dx_binary = os.path.join(options.android_sdk_tools, 'dx')
# See http://crbug.com/272064 for context on --force-jumbo.
- dex_cmd = [dx_binary, '--dex', '--force-jumbo', '--output', options.dex_path]
+ # --num-threads=10 made final dexing go from 10s -> 5s on a z620.
+ dex_cmd = [dx_binary, '--num-threads=10', '--dex', '--force-jumbo',
+ '--output', options.dex_path]
if options.no_locals != '0':
dex_cmd.append('--no-locals')
diff --git a/build/android/gyp/jinja_template.py b/build/android/gyp/jinja_template.py
index 6653f21..e7c9a34 100755
--- a/build/android/gyp/jinja_template.py
+++ b/build/android/gyp/jinja_template.py
@@ -51,7 +51,7 @@
os.path.abspath(inputs_base_dir))
if relpath.startswith(os.pardir):
raise Exception('input file %s is not contained in inputs base dir %s'
- % input_filename, inputs_base_dir)
+ % (input_filename, inputs_base_dir))
output_filename = os.path.join(temp_dir, relpath)
parent_dir = os.path.dirname(output_filename)
diff --git a/build/android/pylib/base/base_test_runner.py b/build/android/pylib/base/base_test_runner.py
index 1ca0338..2a7fdd3 100644
--- a/build/android/pylib/base/base_test_runner.py
+++ b/build/android/pylib/base/base_test_runner.py
@@ -26,14 +26,15 @@
class BaseTestRunner(object):
"""Base class for running tests on a single device."""
- def __init__(self, device_serial, tool):
+ def __init__(self, device, tool):
"""
Args:
- device: Tests will run on the device of this ID.
+ device: An instance of DeviceUtils that the tests will run on.
tool: Name of the Valgrind tool.
"""
- self.device_serial = device_serial
- self.device = device_utils.DeviceUtils(device_serial)
+ assert isinstance(device, device_utils.DeviceUtils)
+ self.device = device
+ self.device_serial = self.device.adb.GetDeviceSerial()
self.tool = CreateTool(tool, self.device)
self._http_server = None
self._forwarder_device_port = 8000
diff --git a/build/android/pylib/base/test_dispatcher.py b/build/android/pylib/base/test_dispatcher.py
index 1a8e0c1..f919965 100644
--- a/build/android/pylib/base/test_dispatcher.py
+++ b/build/android/pylib/base/test_dispatcher.py
@@ -21,7 +21,6 @@
import logging
import threading
-from pylib import android_commands
from pylib import constants
from pylib.base import base_test_result
from pylib.base import test_collection
@@ -102,7 +101,7 @@
for test in collection:
watcher.Reset()
try:
- if runner.device_serial not in android_commands.GetAttachedDevices():
+ if not runner.device.IsOnline():
# Device is unresponsive, stop handling tests on this device.
msg = 'Device %s is unresponsive.' % runner.device_serial
logging.warning(msg)
@@ -150,10 +149,7 @@
runner = runner_factory(device, index)
runner.SetUp()
out_runners.append(runner)
- except (device_errors.DeviceUnreachableError,
- # TODO(jbudorick) Remove this once the underlying implementations
- # for the above are switched or wrapped.
- android_commands.errors.DeviceUnresponsiveError) as e:
+ except device_errors.DeviceUnreachableError as e:
logging.warning('Failed to create shard for %s: [%s]', device, e)
@@ -195,10 +191,7 @@
# Catch DeviceUnreachableErrors and set a warning exit code
try:
workers.JoinAll(watcher)
- except (device_errors.DeviceUnreachableError,
- # TODO(jbudorick) Remove this once the underlying implementations
- # for the above are switched or wrapped.
- android_commands.errors.DeviceUnresponsiveError) as e:
+ except device_errors.DeviceUnreachableError as e:
logging.error(e)
if not all((len(tc) == 0 for tc in test_collections)):
@@ -236,7 +229,7 @@
threads = reraiser_thread.ReraiserThreadGroup(
[reraiser_thread.ReraiserThread(_SetUp,
[runner_factory, d, runners, counter],
- name=d[-4:])
+ name=str(d)[-4:])
for d in devices])
threads.StartAll()
threads.JoinAll(watchdog_timer.WatchdogTimer(timeout))
@@ -333,10 +326,7 @@
finally:
try:
_TearDownRunners(runners, setup_timeout)
- except (device_errors.DeviceUnreachableError,
- # TODO(jbudorick) Remove this once the underlying implementations
- # for the above are switched or wrapped.
- android_commands.errors.DeviceUnresponsiveError) as e:
+ except device_errors.DeviceUnreachableError as e:
logging.warning('Device unresponsive during TearDown: [%s]', e)
except Exception as e:
logging.error('Unexpected exception caught during TearDown: %s' % str(e))
diff --git a/build/android/pylib/base/test_dispatcher_unittest.py b/build/android/pylib/base/test_dispatcher_unittest.py
old mode 100644
new mode 100755
index b57cca9..cace9a6
--- a/build/android/pylib/base/test_dispatcher_unittest.py
+++ b/build/android/pylib/base/test_dispatcher_unittest.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -10,27 +11,38 @@
import sys
import unittest
-sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)),
- os.pardir, os.pardir))
-# Mock out android_commands.GetAttachedDevices().
-from pylib import android_commands
-android_commands.GetAttachedDevices = lambda: ['0', '1']
from pylib import constants
from pylib.base import base_test_result
from pylib.base import test_collection
from pylib.base import test_dispatcher
+from pylib.device import adb_wrapper
+from pylib.device import device_utils
from pylib.utils import watchdog_timer
+sys.path.append(
+ os.path.join(constants.DIR_SOURCE_ROOT, 'third_party', 'pymock'))
+import mock
+
class TestException(Exception):
pass
+def _MockDevice(serial):
+ d = mock.MagicMock(spec=device_utils.DeviceUtils)
+ d.__str__.return_value = serial
+ d.adb = mock.MagicMock(spec=adb_wrapper.AdbWrapper)
+ d.adb.GetDeviceSerial = mock.MagicMock(return_value=serial)
+ d.IsOnline = mock.MagicMock(return_value=True)
+ return d
+
+
class MockRunner(object):
"""A mock TestRunner."""
- def __init__(self, device='0', shard_index=0):
- self.device_serial = device
+ def __init__(self, device=None, shard_index=0):
+ self.device = device or _MockDevice('0')
+ self.device_serial = self.device.adb.GetDeviceSerial()
self.shard_index = shard_index
self.setups = 0
self.teardowns = 0
@@ -57,7 +69,7 @@
class MockRunnerFailTwice(MockRunner):
- def __init__(self, device='0', shard_index=0):
+ def __init__(self, device=None, shard_index=0):
super(MockRunnerFailTwice, self).__init__(device, shard_index)
self._fails = 0
@@ -111,7 +123,7 @@
def testSetUp(self):
runners = []
counter = test_dispatcher._ThreadSafeCounter()
- test_dispatcher._SetUp(MockRunner, '0', runners, counter)
+ test_dispatcher._SetUp(MockRunner, _MockDevice('0'), runners, counter)
self.assertEqual(len(runners), 1)
self.assertEqual(runners[0].setups, 1)
@@ -135,7 +147,8 @@
self.test_collection_factory = lambda: shared_test_collection
def testCreate(self):
- runners = test_dispatcher._CreateRunners(MockRunner, ['0', '1'])
+ runners = test_dispatcher._CreateRunners(
+ MockRunner, [_MockDevice('0'), _MockDevice('1')])
for runner in runners:
self.assertEqual(runner.setups, 1)
self.assertEqual(set([r.device_serial for r in runners]),
@@ -144,27 +157,29 @@
set([0, 1]))
def testRun(self):
- runners = [MockRunner('0'), MockRunner('1')]
+ runners = [MockRunner(_MockDevice('0')), MockRunner(_MockDevice('1'))]
results, exit_code = test_dispatcher._RunAllTests(
runners, self.test_collection_factory, 0)
self.assertEqual(len(results.GetPass()), len(self.tests))
self.assertEqual(exit_code, 0)
def testTearDown(self):
- runners = [MockRunner('0'), MockRunner('1')]
+ runners = [MockRunner(_MockDevice('0')), MockRunner(_MockDevice('1'))]
test_dispatcher._TearDownRunners(runners)
for runner in runners:
self.assertEqual(runner.teardowns, 1)
def testRetry(self):
- runners = test_dispatcher._CreateRunners(MockRunnerFail, ['0', '1'])
+ runners = test_dispatcher._CreateRunners(
+ MockRunnerFail, [_MockDevice('0'), _MockDevice('1')])
results, exit_code = test_dispatcher._RunAllTests(
runners, self.test_collection_factory, 0)
self.assertEqual(len(results.GetFail()), len(self.tests))
self.assertEqual(exit_code, constants.ERROR_EXIT_CODE)
def testReraise(self):
- runners = test_dispatcher._CreateRunners(MockRunnerException, ['0', '1'])
+ runners = test_dispatcher._CreateRunners(
+ MockRunnerException, [_MockDevice('0'), _MockDevice('1')])
with self.assertRaises(TestException):
test_dispatcher._RunAllTests(runners, self.test_collection_factory, 0)
@@ -174,7 +189,8 @@
@staticmethod
def _RunShard(runner_factory):
return test_dispatcher.RunTests(
- ['a', 'b', 'c'], runner_factory, ['0', '1'], shard=True)
+ ['a', 'b', 'c'], runner_factory, [_MockDevice('0'), _MockDevice('1')],
+ shard=True)
def testShard(self):
results, exit_code = TestShard._RunShard(MockRunner)
@@ -189,7 +205,7 @@
def testNoTests(self):
results, exit_code = test_dispatcher.RunTests(
- [], MockRunner, ['0', '1'], shard=True)
+ [], MockRunner, [_MockDevice('0'), _MockDevice('1')], shard=True)
self.assertEqual(len(results.GetAll()), 0)
self.assertEqual(exit_code, constants.ERROR_EXIT_CODE)
@@ -199,7 +215,8 @@
@staticmethod
def _RunReplicate(runner_factory):
return test_dispatcher.RunTests(
- ['a', 'b', 'c'], runner_factory, ['0', '1'], shard=False)
+ ['a', 'b', 'c'], runner_factory, [_MockDevice('0'), _MockDevice('1')],
+ shard=False)
def testReplicate(self):
results, exit_code = TestReplicate._RunReplicate(MockRunner)
@@ -215,7 +232,7 @@
def testNoTests(self):
results, exit_code = test_dispatcher.RunTests(
- [], MockRunner, ['0', '1'], shard=False)
+ [], MockRunner, [_MockDevice('0'), _MockDevice('1')], shard=False)
self.assertEqual(len(results.GetAll()), 0)
self.assertEqual(exit_code, constants.ERROR_EXIT_CODE)
diff --git a/build/android/pylib/constants/__init__.py b/build/android/pylib/constants/__init__.py
index 6e92f6d..025860c 100644
--- a/build/android/pylib/constants/__init__.py
+++ b/build/android/pylib/constants/__init__.py
@@ -102,7 +102,7 @@
'org.chromium.android_webview.test'),
'gtest': PackageInfo(
'org.chromium.native_test',
- 'org.chromium.native_test.ChromeNativeTestActivity',
+ 'org.chromium.native_test.NativeTestActivity',
'/data/local/tmp/chrome-native-tests-command-line',
None,
None),
@@ -229,7 +229,8 @@
try:
return os.environ['BUILDTYPE']
except KeyError:
- raise Exception('The BUILDTYPE environment variable has not been set')
+ raise EnvironmentError(
+ 'The BUILDTYPE environment variable has not been set')
def SetBuildType(build_type):
@@ -240,7 +241,7 @@
os.environ['CHROMIUM_OUT_DIR'] = build_directory
-def SetOutputDirectort(output_directory):
+def SetOutputDirectory(output_directory):
os.environ['CHROMIUM_OUTPUT_DIR'] = output_directory
diff --git a/build/android/pylib/device/adb_wrapper.py b/build/android/pylib/device/adb_wrapper.py
index 20787c1..8e8abf8 100644
--- a/build/android/pylib/device/adb_wrapper.py
+++ b/build/android/pylib/device/adb_wrapper.py
@@ -450,7 +450,7 @@
timeout: (optional) Timeout per try in seconds.
retries: (optional) Number of retries to attempt.
"""
- cmd = ['backup', path]
+ cmd = ['backup', '-f', path]
if apk:
cmd.append('-apk')
if shared:
@@ -542,6 +542,24 @@
raise device_errors.AdbCommandFailedError(
['root'], output, device_serial=self._device_serial)
+ def Emu(self, cmd, timeout=_DEFAULT_TIMEOUT,
+ retries=_DEFAULT_RETRIES):
+ """Runs an emulator console command.
+
+ See http://developer.android.com/tools/devices/emulator.html#console
+
+ Args:
+ cmd: The command to run on the emulator console.
+ timeout: (optional) Timeout per try in seconds.
+ retries: (optional) Number of retries to attempt.
+
+ Returns:
+ The output of the emulator console command.
+ """
+ if isinstance(cmd, basestring):
+ cmd = [cmd]
+ return self._RunDeviceAdbCmd(['emu'] + cmd, timeout, retries)
+
@property
def is_emulator(self):
return _EMULATOR_RE.match(self._device_serial)
diff --git a/build/android/pylib/device/battery_utils_test.py b/build/android/pylib/device/battery_utils_test.py
index 15b4c34..434b9d8 100755
--- a/build/android/pylib/device/battery_utils_test.py
+++ b/build/android/pylib/device/battery_utils_test.py
@@ -14,7 +14,6 @@
import sys
import unittest
-from pylib import android_commands
from pylib import constants
from pylib.device import battery_utils
from pylib.device import device_errors
@@ -62,8 +61,7 @@
def testInitWithDeviceUtil(self):
serial = '0fedcba987654321'
- a = android_commands.AndroidCommands(device=serial)
- d = device_utils.DeviceUtils(a)
+ d = device_utils.DeviceUtils(serial)
b = battery_utils.BatteryUtils(d)
self.assertEqual(d, b._device)
diff --git a/build/android/pylib/device/device_utils.py b/build/android/pylib/device/device_utils.py
index 46aec6f..091bb8e 100644
--- a/build/android/pylib/device/device_utils.py
+++ b/build/android/pylib/device/device_utils.py
@@ -175,6 +175,29 @@
assert hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR)
assert hasattr(self, decorators.DEFAULT_RETRIES_ATTR)
+ def __eq__(self, other):
+ """Checks whether |other| refers to the same device as |self|.
+
+ Args:
+ other: The object to compare to. This can be a basestring, an instance
+ of adb_wrapper.AdbWrapper, or an instance of DeviceUtils.
+ Returns:
+ Whether |other| refers to the same device as |self|.
+ """
+ return self.adb.GetDeviceSerial() == str(other)
+
+ def __lt__(self, other):
+ """Compares two instances of DeviceUtils.
+
+ This merely compares their serial numbers.
+
+ Args:
+ other: The instance of DeviceUtils to compare to.
+ Returns:
+ Whether |self| is less than |other|.
+ """
+ return self.adb.GetDeviceSerial() < other.adb.GetDeviceSerial()
+
def __str__(self):
"""Returns the device serial."""
return self.adb.GetDeviceSerial()
@@ -535,9 +558,9 @@
with device_temp_file.DeviceTempFile(self.adb) as large_output_file:
cmd = '%s > %s' % (cmd, large_output_file.name)
logging.info('Large output mode enabled. Will write output to device '
- ' and read results from file.')
+ 'and read results from file.')
handle_large_command(cmd)
- return self.ReadFile(large_output_file.name)
+ return self.ReadFile(large_output_file.name, force_pull=True)
else:
try:
return handle_large_command(cmd)
@@ -853,13 +876,17 @@
if not real_device_path:
return [(host_path, device_path)]
- host_checksums = md5sum.CalculateHostMd5Sums([real_host_path])
- device_paths_to_md5 = (
- real_device_path if os.path.isfile(real_host_path)
- else ('%s/%s' % (real_device_path, os.path.relpath(p, real_host_path))
- for p in host_checksums.iterkeys()))
- device_checksums = md5sum.CalculateDeviceMd5Sums(
- device_paths_to_md5, self)
+ try:
+ host_checksums = md5sum.CalculateHostMd5Sums([real_host_path])
+ device_paths_to_md5 = (
+ real_device_path if os.path.isfile(real_host_path)
+ else ('%s/%s' % (real_device_path, os.path.relpath(p, real_host_path))
+ for p in host_checksums.iterkeys()))
+ device_checksums = md5sum.CalculateDeviceMd5Sums(
+ device_paths_to_md5, self)
+ except EnvironmentError as e:
+ logging.warning('Error calculating md5: %s', e)
+ return [(host_path, device_path)]
if os.path.isfile(host_path):
host_checksum = host_checksums.get(real_host_path)
@@ -1016,7 +1043,7 @@
+ r'(?P<date>\S+) +(?P<time>\S+) +(?P<name>.+)$')
@decorators.WithTimeoutAndRetriesFromInstance()
- def ReadFile(self, device_path, as_root=False,
+ def ReadFile(self, device_path, as_root=False, force_pull=False,
timeout=None, retries=None):
"""Reads the contents of a file from the device.
@@ -1025,6 +1052,9 @@
from the device.
as_root: A boolean indicating whether the read should be executed with
root privileges.
+ force_pull: A boolean indicating whether to force the operation to be
+ performed by pulling a file from the device. The default is, when the
+ contents are short, to retrieve the contents using cat instead.
timeout: timeout in seconds
retries: number of retries
@@ -1038,20 +1068,20 @@
CommandTimeoutError on timeout.
DeviceUnreachableError on missing device.
"""
- # TODO(jbudorick): Implement a generic version of Stat() that handles
- # as_root=True, then switch this implementation to use that.
- size = None
- ls_out = self.RunShellCommand(['ls', '-l', device_path], as_root=as_root,
- check_return=True)
- for line in ls_out:
- m = self._LS_RE.match(line)
- if m and m.group('name') == posixpath.basename(device_path):
- size = int(m.group('size'))
- break
- else:
+ def get_size(path):
+ # TODO(jbudorick): Implement a generic version of Stat() that handles
+ # as_root=True, then switch this implementation to use that.
+ ls_out = self.RunShellCommand(['ls', '-l', device_path], as_root=as_root,
+ check_return=True)
+ for line in ls_out:
+ m = self._LS_RE.match(line)
+ if m and m.group('name') == posixpath.basename(device_path):
+ return int(m.group('size'))
logging.warning('Could not determine size of %s.', device_path)
+ return None
- if 0 < size <= self._MAX_ADB_OUTPUT_LENGTH:
+ if (not force_pull
+ and 0 < get_size(device_path) <= self._MAX_ADB_OUTPUT_LENGTH):
return _JoinLines(self.RunShellCommand(
['cat', device_path], as_root=as_root, check_return=True))
elif as_root and self.NeedsSU():
diff --git a/build/android/pylib/device/device_utils_test.py b/build/android/pylib/device/device_utils_test.py
index 4301e9d..e5e3936 100755
--- a/build/android/pylib/device/device_utils_test.py
+++ b/build/android/pylib/device/device_utils_test.py
@@ -161,6 +161,73 @@
msg, str(self.device)))
+class DeviceUtilsEqTest(DeviceUtilsTest):
+
+ def testEq_equal_deviceUtils(self):
+ other = device_utils.DeviceUtils(_AdbWrapperMock('0123456789abcdef'))
+ self.assertTrue(self.device == other)
+ self.assertTrue(other == self.device)
+
+ def testEq_equal_adbWrapper(self):
+ other = adb_wrapper.AdbWrapper('0123456789abcdef')
+ self.assertTrue(self.device == other)
+ self.assertTrue(other == self.device)
+
+ def testEq_equal_string(self):
+ other = '0123456789abcdef'
+ self.assertTrue(self.device == other)
+ self.assertTrue(other == self.device)
+
+ def testEq_devicesNotEqual(self):
+ other = device_utils.DeviceUtils(_AdbWrapperMock('0123456789abcdee'))
+ self.assertFalse(self.device == other)
+ self.assertFalse(other == self.device)
+
+ def testEq_identity(self):
+ self.assertTrue(self.device == self.device)
+
+ def testEq_serialInList(self):
+ devices = [self.device]
+ self.assertTrue('0123456789abcdef' in devices)
+
+
+class DeviceUtilsLtTest(DeviceUtilsTest):
+
+ def testLt_lessThan(self):
+ other = device_utils.DeviceUtils(_AdbWrapperMock('ffffffffffffffff'))
+ self.assertTrue(self.device < other)
+ self.assertTrue(other > self.device)
+
+ def testLt_greaterThan_lhs(self):
+ other = device_utils.DeviceUtils(_AdbWrapperMock('0000000000000000'))
+ self.assertFalse(self.device < other)
+ self.assertFalse(other > self.device)
+
+ def testLt_equal(self):
+ other = device_utils.DeviceUtils(_AdbWrapperMock('0123456789abcdef'))
+ self.assertFalse(self.device < other)
+ self.assertFalse(other > self.device)
+
+ def testLt_sorted(self):
+ devices = [
+ device_utils.DeviceUtils(_AdbWrapperMock('ffffffffffffffff')),
+ device_utils.DeviceUtils(_AdbWrapperMock('0000000000000000')),
+ ]
+ sorted_devices = sorted(devices)
+ self.assertEquals('0000000000000000',
+ sorted_devices[0].adb.GetDeviceSerial())
+ self.assertEquals('ffffffffffffffff',
+ sorted_devices[1].adb.GetDeviceSerial())
+
+
+class DeviceUtilsStrTest(DeviceUtilsTest):
+
+ def testStr_returnsSerial(self):
+ with self.assertCalls(
+ (self.call.adb.GetDeviceSerial(), '0123456789abcdef')):
+ self.assertEqual('0123456789abcdef', str(self.device))
+
+
class DeviceUtilsIsOnlineTest(DeviceUtilsTest):
def testIsOnline_true(self):
@@ -594,7 +661,8 @@
(mock.call.pylib.utils.device_temp_file.DeviceTempFile(self.adb),
temp_file),
(self.call.adb.Shell(cmd_redirect)),
- (self.call.device.ReadFile(temp_file.name), 'something')):
+ (self.call.device.ReadFile(temp_file.name, force_pull=True),
+ 'something')):
self.assertEquals(
['something'],
self.device.RunShellCommand(
@@ -615,7 +683,8 @@
(mock.call.pylib.utils.device_temp_file.DeviceTempFile(self.adb),
temp_file),
(self.call.adb.Shell(cmd_redirect)),
- (self.call.device.ReadFile(mock.ANY), 'something')):
+ (self.call.device.ReadFile(mock.ANY, force_pull=True),
+ 'something')):
self.assertEquals(['something'],
self.device.RunShellCommand(cmd, check_return=True))
@@ -1223,6 +1292,15 @@
self.device.ReadFile('/this/big/file/can.be.read.with.su',
as_root=True))
+ def testReadFile_forcePull(self):
+ contents = 'a' * 123456
+ with self.assertCall(
+ self.call.device._ReadFileWithPull('/read/this/big/test/file'),
+ contents):
+ self.assertEqual(
+ contents,
+ self.device.ReadFile('/read/this/big/test/file', force_pull=True))
+
class DeviceUtilsWriteFileTest(DeviceUtilsTest):
@@ -1539,14 +1617,6 @@
self.device.GetMemoryUsageForPid(4321))
-class DeviceUtilsStrTest(DeviceUtilsTest):
-
- def testStr_returnsSerial(self):
- with self.assertCalls(
- (self.call.adb.GetDeviceSerial(), '0123456789abcdef')):
- self.assertEqual('0123456789abcdef', str(self.device))
-
-
class DeviceUtilsClientCache(DeviceUtilsTest):
def testClientCache_twoCaches(self):
diff --git a/build/android/pylib/device/shared_prefs.py b/build/android/pylib/device/shared_prefs.py
new file mode 100644
index 0000000..32cef4b
--- /dev/null
+++ b/build/android/pylib/device/shared_prefs.py
@@ -0,0 +1,391 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Helper object to read and modify Shared Preferences from Android apps.
+
+See e.g.:
+ http://developer.android.com/reference/android/content/SharedPreferences.html
+"""
+
+import collections
+import logging
+import posixpath
+
+from xml.etree import ElementTree
+
+
+_XML_DECLARATION = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+
+
+class BasePref(object):
+ """Base class for getting/setting the value of a specific preference type.
+
+ Should not be instantiated directly. The SharedPrefs collection will
+ instantiate the appropriate subclasses, which directly manipulate the
+ underlying xml document, to parse and serialize values according to their
+ type.
+
+ Args:
+ elem: An xml ElementTree object holding the preference data.
+
+ Properties:
+ tag_name: A string with the tag that must be used for this preference type.
+ """
+ tag_name = None
+
+ def __init__(self, elem):
+ if elem.tag != type(self).tag_name:
+ raise TypeError('Property %r has type %r, but trying to access as %r' %
+ (elem.get('name'), elem.tag, type(self).tag_name))
+ self._elem = elem
+
+ def __str__(self):
+ """Get the underlying xml element as a string."""
+ return ElementTree.tostring(self._elem)
+
+ def get(self):
+ """Get the value of this preference."""
+ return self._elem.get('value')
+
+ def set(self, value):
+ """Set from a value casted as a string."""
+ self._elem.set('value', str(value))
+
+ @property
+ def has_value(self):
+ """Check whether the element has a value."""
+ return self._elem.get('value') is not None
+
+
+class BooleanPref(BasePref):
+ """Class for getting/setting a preference with a boolean value.
+
+ The underlying xml element has the form, e.g.:
+ <boolean name="featureEnabled" value="false" />
+ """
+ tag_name = 'boolean'
+ VALUES = {'true': True, 'false': False}
+
+ def get(self):
+ """Get the value as a Python bool."""
+ return type(self).VALUES[super(BooleanPref, self).get()]
+
+ def set(self, value):
+ """Set from a value casted as a bool."""
+ super(BooleanPref, self).set('true' if value else 'false')
+
+
+class FloatPref(BasePref):
+ """Class for getting/setting a preference with a float value.
+
+ The underlying xml element has the form, e.g.:
+ <float name="someMetric" value="4.7" />
+ """
+ tag_name = 'float'
+
+ def get(self):
+ """Get the value as a Python float."""
+ return float(super(FloatPref, self).get())
+
+
+class IntPref(BasePref):
+ """Class for getting/setting a preference with an int value.
+
+ The underlying xml element has the form, e.g.:
+ <int name="aCounter" value="1234" />
+ """
+ tag_name = 'int'
+
+ def get(self):
+ """Get the value as a Python int."""
+ return int(super(IntPref, self).get())
+
+
+class LongPref(IntPref):
+ """Class for getting/setting a preference with a long value.
+
+ The underlying xml element has the form, e.g.:
+ <long name="aLongCounter" value="1234" />
+
+ We use the same implementation from IntPref.
+ """
+ tag_name = 'long'
+
+
+class StringPref(BasePref):
+ """Class for getting/setting a preference with a string value.
+
+ The underlying xml element has the form, e.g.:
+ <string name="someHashValue">249b3e5af13d4db2</string>
+ """
+ tag_name = 'string'
+
+ def get(self):
+ """Get the value as a Python string."""
+ return self._elem.text
+
+ def set(self, value):
+ """Set from a value casted as a string."""
+ self._elem.text = str(value)
+
+
+class StringSetPref(StringPref):
+ """Class for getting/setting a preference with a set of string values.
+
+ The underlying xml element has the form, e.g.:
+ <set name="managed_apps">
+ <string>com.mine.app1</string>
+ <string>com.mine.app2</string>
+ <string>com.mine.app3</string>
+ </set>
+ """
+ tag_name = 'set'
+
+ def get(self):
+ """Get a list with the string values contained."""
+ value = []
+ for child in self._elem:
+ assert child.tag == 'string'
+ value.append(child.text)
+ return value
+
+ def set(self, value):
+ """Set from a sequence of values, each casted as a string."""
+ for child in list(self._elem):
+ self._elem.remove(child)
+ for item in value:
+ ElementTree.SubElement(self._elem, 'string').text = str(item)
+
+
+_PREF_TYPES = {c.tag_name: c for c in [BooleanPref, FloatPref, IntPref,
+ LongPref, StringPref, StringSetPref]}
+
+
+class SharedPrefs(object):
+ def __init__(self, device, package, filename):
+ """Helper object to read and update "Shared Prefs" of Android apps.
+
+ Such files typically look like, e.g.:
+
+ <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
+ <map>
+ <int name="databaseVersion" value="107" />
+ <boolean name="featureEnabled" value="false" />
+ <string name="someHashValue">249b3e5af13d4db2</string>
+ </map>
+
+ Example usage:
+
+ prefs = shared_prefs.SharedPrefs(device, 'com.my.app', 'my_prefs.xml')
+ prefs.Load()
+ prefs.GetString('someHashValue') # => '249b3e5af13d4db2'
+ prefs.SetInt('databaseVersion', 42)
+ prefs.Remove('featureEnabled')
+ prefs.Commit()
+
+ The object may also be used as a context manager to automatically load and
+ commit, respectively, upon entering and leaving the context.
+
+ Args:
+ device: A DeviceUtils object.
+ package: A string with the package name of the app that owns the shared
+ preferences file.
+ filename: A string with the name of the preferences file to read/write.
+ """
+ self._device = device
+ self._xml = None
+ self._package = package
+ self._filename = filename
+ self._path = '/data/data/%s/shared_prefs/%s' % (package, filename)
+ self._changed = False
+
+ def __repr__(self):
+ """Get a useful printable representation of the object."""
+ return '<{cls} file {filename} for {package} on {device}>'.format(
+ cls=type(self).__name__, filename=self.filename, package=self.package,
+ device=str(self._device))
+
+ def __str__(self):
+ """Get the underlying xml document as a string."""
+ return _XML_DECLARATION + ElementTree.tostring(self.xml)
+
+ @property
+ def package(self):
+ """Get the package name of the app that owns the shared preferences."""
+ return self._package
+
+ @property
+ def filename(self):
+ """Get the filename of the shared preferences file."""
+ return self._filename
+
+ @property
+ def path(self):
+ """Get the full path to the shared preferences file on the device."""
+ return self._path
+
+ @property
+ def changed(self):
+ """True if properties have changed and a commit would be needed."""
+ return self._changed
+
+ @property
+ def xml(self):
+ """Get the underlying xml document as an ElementTree object."""
+ if self._xml is None:
+ self._xml = ElementTree.Element('map')
+ return self._xml
+
+ def Load(self):
+ """Load the shared preferences file from the device.
+
+ A empty xml document, which may be modified and saved on |commit|, is
+ created if the file does not already exist.
+ """
+ if self._device.FileExists(self.path):
+ self._xml = ElementTree.fromstring(
+ self._device.ReadFile(self.path, as_root=True))
+ assert self._xml.tag == 'map'
+ else:
+ self._xml = None
+ self._changed = False
+
+ def Clear(self):
+ """Clear all of the preferences contained in this object."""
+ if self._xml is not None and len(self): # only clear if not already empty
+ self._xml = None
+ self._changed = True
+
+ def Commit(self):
+ """Save the current set of preferences to the device.
+
+ Only actually saves if some preferences have been modified.
+ """
+ if not self.changed:
+ return
+ self._device.RunShellCommand(
+ ['mkdir', '-p', posixpath.dirname(self.path)],
+ as_root=True, check_return=True)
+ self._device.WriteFile(self.path, str(self), as_root=True)
+ self._device.KillAll(self.package, as_root=True, quiet=True)
+ self._changed = False
+
+ def __len__(self):
+ """Get the number of preferences in this collection."""
+ return len(self.xml)
+
+ def PropertyType(self, key):
+ """Get the type (i.e. tag name) of a property in the collection."""
+ return self._GetChild(key).tag
+
+ def HasProperty(self, key):
+ try:
+ self._GetChild(key)
+ return True
+ except KeyError:
+ return False
+
+ def GetBoolean(self, key):
+ """Get a boolean property."""
+ return BooleanPref(self._GetChild(key)).get()
+
+ def SetBoolean(self, key, value):
+ """Set a boolean property."""
+ self._SetPrefValue(key, value, BooleanPref)
+
+ def GetFloat(self, key):
+ """Get a float property."""
+ return FloatPref(self._GetChild(key)).get()
+
+ def SetFloat(self, key, value):
+ """Set a float property."""
+ self._SetPrefValue(key, value, FloatPref)
+
+ def GetInt(self, key):
+ """Get an int property."""
+ return IntPref(self._GetChild(key)).get()
+
+ def SetInt(self, key, value):
+ """Set an int property."""
+ self._SetPrefValue(key, value, IntPref)
+
+ def GetLong(self, key):
+ """Get a long property."""
+ return LongPref(self._GetChild(key)).get()
+
+ def SetLong(self, key, value):
+ """Set a long property."""
+ self._SetPrefValue(key, value, LongPref)
+
+ def GetString(self, key):
+ """Get a string property."""
+ return StringPref(self._GetChild(key)).get()
+
+ def SetString(self, key, value):
+ """Set a string property."""
+ self._SetPrefValue(key, value, StringPref)
+
+ def GetStringSet(self, key):
+ """Get a string set property."""
+ return StringSetPref(self._GetChild(key)).get()
+
+ def SetStringSet(self, key, value):
+ """Set a string set property."""
+ self._SetPrefValue(key, value, StringSetPref)
+
+ def Remove(self, key):
+ """Remove a preference from the collection."""
+ self.xml.remove(self._GetChild(key))
+
+ def AsDict(self):
+ """Return the properties and their values as a dictionary."""
+ d = {}
+ for child in self.xml:
+ pref = _PREF_TYPES[child.tag](child)
+ d[child.get('name')] = pref.get()
+ return d
+
+ def __enter__(self):
+ """Load preferences file from the device when entering a context."""
+ self.Load()
+ return self
+
+ def __exit__(self, exc_type, _exc_value, _traceback):
+ """Save preferences file to the device when leaving a context."""
+ if not exc_type:
+ self.Commit()
+
+ def _GetChild(self, key):
+ """Get the underlying xml node that holds the property of a given key.
+
+ Raises:
+ KeyError when the key is not found in the collection.
+ """
+ for child in self.xml:
+ if child.get('name') == key:
+ return child
+ raise KeyError(key)
+
+ def _SetPrefValue(self, key, value, pref_cls):
+ """Set the value of a property.
+
+ Args:
+ key: The key of the property to set.
+ value: The new value of the property.
+ pref_cls: A subclass of BasePref used to access the property.
+
+ Raises:
+ TypeError when the key already exists but with a different type.
+ """
+ try:
+ pref = pref_cls(self._GetChild(key))
+ old_value = pref.get()
+ except KeyError:
+ pref = pref_cls(ElementTree.SubElement(
+ self.xml, pref_cls.tag_name, {'name': key}))
+ old_value = None
+ if old_value != value:
+ pref.set(value)
+ self._changed = True
+ logging.info('Setting property: %s', pref)
diff --git a/build/android/pylib/device/shared_prefs_test.py b/build/android/pylib/device/shared_prefs_test.py
new file mode 100755
index 0000000..c5f0ec3
--- /dev/null
+++ b/build/android/pylib/device/shared_prefs_test.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Unit tests for the contents of shared_prefs.py (mostly SharedPrefs).
+"""
+
+import logging
+import os
+import sys
+import unittest
+
+from pylib import constants
+from pylib.device import device_utils
+from pylib.device import shared_prefs
+
+sys.path.append(os.path.join(
+ constants.DIR_SOURCE_ROOT, 'third_party', 'pymock'))
+import mock
+
+
+def MockDeviceWithFiles(files=None):
+ if files is None:
+ files = {}
+
+ def file_exists(path):
+ return path in files
+
+ def write_file(path, contents, **_kwargs):
+ files[path] = contents
+
+ def read_file(path, **_kwargs):
+ return files[path]
+
+ device = mock.MagicMock(spec=device_utils.DeviceUtils)
+ device.FileExists = mock.Mock(side_effect=file_exists)
+ device.WriteFile = mock.Mock(side_effect=write_file)
+ device.ReadFile = mock.Mock(side_effect=read_file)
+ return device
+
+
+class SharedPrefsTest(unittest.TestCase):
+
+ def setUp(self):
+ self.device = MockDeviceWithFiles({
+ '/data/data/com.some.package/shared_prefs/prefs.xml':
+ "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ '<map>\n'
+ ' <int name="databaseVersion" value="107" />\n'
+ ' <boolean name="featureEnabled" value="false" />\n'
+ ' <string name="someHashValue">249b3e5af13d4db2</string>\n'
+ '</map>'})
+ self.expected_data = {'databaseVersion': 107,
+ 'featureEnabled': False,
+ 'someHashValue': '249b3e5af13d4db2'}
+
+ def testPropertyLifetime(self):
+ prefs = shared_prefs.SharedPrefs(
+ self.device, 'com.some.package', 'prefs.xml')
+ self.assertEquals(len(prefs), 0) # collection is empty before loading
+ prefs.SetInt('myValue', 444)
+ self.assertEquals(len(prefs), 1)
+ self.assertEquals(prefs.GetInt('myValue'), 444)
+ self.assertTrue(prefs.HasProperty('myValue'))
+ prefs.Remove('myValue')
+ self.assertEquals(len(prefs), 0)
+ self.assertFalse(prefs.HasProperty('myValue'))
+ with self.assertRaises(KeyError):
+ prefs.GetInt('myValue')
+
+ def testPropertyType(self):
+ prefs = shared_prefs.SharedPrefs(
+ self.device, 'com.some.package', 'prefs.xml')
+ prefs.SetInt('myValue', 444)
+ self.assertEquals(prefs.PropertyType('myValue'), 'int')
+ with self.assertRaises(TypeError):
+ prefs.GetString('myValue')
+ with self.assertRaises(TypeError):
+ prefs.SetString('myValue', 'hello')
+
+ def testLoad(self):
+ prefs = shared_prefs.SharedPrefs(
+ self.device, 'com.some.package', 'prefs.xml')
+ self.assertEquals(len(prefs), 0) # collection is empty before loading
+ prefs.Load()
+ self.assertEquals(len(prefs), len(self.expected_data))
+ self.assertEquals(prefs.AsDict(), self.expected_data)
+ self.assertFalse(prefs.changed)
+
+ def testClear(self):
+ prefs = shared_prefs.SharedPrefs(
+ self.device, 'com.some.package', 'prefs.xml')
+ prefs.Load()
+ self.assertEquals(prefs.AsDict(), self.expected_data)
+ self.assertFalse(prefs.changed)
+ prefs.Clear()
+ self.assertEquals(len(prefs), 0) # collection is empty now
+ self.assertTrue(prefs.changed)
+
+ def testCommit(self):
+ prefs = shared_prefs.SharedPrefs(
+ self.device, 'com.some.package', 'other_prefs.xml')
+ self.assertFalse(self.device.FileExists(prefs.path)) # file does not exist
+ prefs.Load()
+ self.assertEquals(len(prefs), 0) # file did not exist, collection is empty
+ prefs.SetInt('magicNumber', 42)
+ prefs.SetFloat('myMetric', 3.14)
+ prefs.SetLong('bigNumner', 6000000000)
+ prefs.SetStringSet('apps', ['gmail', 'chrome', 'music'])
+ self.assertFalse(self.device.FileExists(prefs.path)) # still does not exist
+ self.assertTrue(prefs.changed)
+ prefs.Commit()
+ self.assertTrue(self.device.FileExists(prefs.path)) # should exist now
+ self.device.KillAll.assert_called_once_with(prefs.package, as_root=True,
+ quiet=True)
+ self.assertFalse(prefs.changed)
+
+ prefs = shared_prefs.SharedPrefs(
+ self.device, 'com.some.package', 'other_prefs.xml')
+ self.assertEquals(len(prefs), 0) # collection is empty before loading
+ prefs.Load()
+ self.assertEquals(prefs.AsDict(), {
+ 'magicNumber': 42,
+ 'myMetric': 3.14,
+ 'bigNumner': 6000000000,
+ 'apps': ['gmail', 'chrome', 'music']}) # data survived roundtrip
+
+ def testAsContextManager_onlyReads(self):
+ with shared_prefs.SharedPrefs(
+ self.device, 'com.some.package', 'prefs.xml') as prefs:
+ self.assertEquals(prefs.AsDict(), self.expected_data) # loaded and ready
+ self.assertEquals(self.device.WriteFile.call_args_list, []) # did not write
+
+ def testAsContextManager_readAndWrite(self):
+ with shared_prefs.SharedPrefs(
+ self.device, 'com.some.package', 'prefs.xml') as prefs:
+ prefs.SetBoolean('featureEnabled', True)
+ prefs.Remove('someHashValue')
+ prefs.SetString('newString', 'hello')
+
+ self.assertTrue(self.device.WriteFile.called) # did write
+ with shared_prefs.SharedPrefs(
+ self.device, 'com.some.package', 'prefs.xml') as prefs:
+ # changes persisted
+ self.assertTrue(prefs.GetBoolean('featureEnabled'))
+ self.assertFalse(prefs.HasProperty('someHashValue'))
+ self.assertEquals(prefs.GetString('newString'), 'hello')
+ self.assertTrue(prefs.HasProperty('databaseVersion')) # still there
+
+ def testAsContextManager_commitAborted(self):
+ with self.assertRaises(TypeError):
+ with shared_prefs.SharedPrefs(
+ self.device, 'com.some.package', 'prefs.xml') as prefs:
+ prefs.SetBoolean('featureEnabled', True)
+ prefs.Remove('someHashValue')
+ prefs.SetString('newString', 'hello')
+ prefs.SetInt('newString', 123) # oops!
+
+ self.assertEquals(self.device.WriteFile.call_args_list, []) # did not write
+ with shared_prefs.SharedPrefs(
+ self.device, 'com.some.package', 'prefs.xml') as prefs:
+ # contents were not modified
+ self.assertEquals(prefs.AsDict(), self.expected_data)
+
+if __name__ == '__main__':
+ logging.getLogger().setLevel(logging.DEBUG)
+ unittest.main(verbosity=2)
diff --git a/build/android/pylib/gtest/filter/net_unittests_disabled b/build/android/pylib/gtest/filter/net_unittests_disabled
index 2632e7c..75a1c86 100644
--- a/build/android/pylib/gtest/filter/net_unittests_disabled
+++ b/build/android/pylib/gtest/filter/net_unittests_disabled
@@ -1,11 +1,5 @@
# List of suppressions.
-# Bug: 171812
-MultiThreadedCertVerifierTest.CancelRequest
-
-# Bug: 380340
-SSLServerSocketTest.Handshake
-
PythonUtils.PythonRunTime
VerifyEndEntity/CertVerifyProcWeakDigestTest.Verify/0
VerifyEndEntity/CertVerifyProcWeakDigestTest.Verify/1
diff --git a/build/android/pylib/gtest/gtest_config.py b/build/android/pylib/gtest/gtest_config.py
index 6ce0fb1..6e332c7 100644
--- a/build/android/pylib/gtest/gtest_config.py
+++ b/build/android/pylib/gtest/gtest_config.py
@@ -32,6 +32,7 @@
'gpu_unittests',
'ipc_tests',
'media_unittests',
+ 'midi_unittests',
'net_unittests',
'sandbox_linux_unittests',
'skia_unittests',
diff --git a/build/android/pylib/gtest/local_device_gtest_run.py b/build/android/pylib/gtest/local_device_gtest_run.py
index fd143d6..4241e85 100644
--- a/build/android/pylib/gtest/local_device_gtest_run.py
+++ b/build/android/pylib/gtest/local_device_gtest_run.py
@@ -21,9 +21,9 @@
_COMMAND_LINE_FLAGS_SUPPORTED = True
_EXTRA_COMMAND_LINE_FILE = (
- 'org.chromium.native_test.ChromeNativeTestActivity.CommandLineFile')
+ 'org.chromium.native_test.NativeTestActivity.CommandLineFile')
_EXTRA_COMMAND_LINE_FLAGS = (
- 'org.chromium.native_test.ChromeNativeTestActivity.CommandLineFlags')
+ 'org.chromium.native_test.NativeTestActivity.CommandLineFlags')
_MAX_SHARD_SIZE = 256
diff --git a/build/android/pylib/gtest/setup.py b/build/android/pylib/gtest/setup.py
index 44662d0..2676152 100644
--- a/build/android/pylib/gtest/setup.py
+++ b/build/android/pylib/gtest/setup.py
@@ -37,6 +37,7 @@
'content_unittests': 'content/content_unittests.isolate',
'media_perftests': 'media/media_perftests.isolate',
'media_unittests': 'media/media_unittests.isolate',
+ 'midi_unittests': 'media/midi/midi_unittests.isolate',
'net_unittests': 'net/net_unittests.isolate',
'sql_unittests': 'sql/sql_unittests.isolate',
'sync_unit_tests': 'sync/sync_unit_tests.isolate',
diff --git a/build/android/pylib/gtest/test_package_apk.py b/build/android/pylib/gtest/test_package_apk.py
index 8da3c74..9672f7a 100644
--- a/build/android/pylib/gtest/test_package_apk.py
+++ b/build/android/pylib/gtest/test_package_apk.py
@@ -51,7 +51,7 @@
def _GetFifo(self):
# The test.fifo path is determined by:
# testing/android/native_test/java/src/org/chromium/native_test/
- # ChromeNativeTestActivity.java and
+ # NativeTestActivity.java and
# testing/android/native_test_launcher.cc
return '/data/data/' + self._package_info.package + '/files/test.fifo'
diff --git a/build/android/pylib/host_driven/test_case.py b/build/android/pylib/host_driven/test_case.py
index a7c6a18..6ff4c5f 100644
--- a/build/android/pylib/host_driven/test_case.py
+++ b/build/android/pylib/host_driven/test_case.py
@@ -68,9 +68,9 @@
def SetUp(self, device, shard_index, ports_to_forward=None):
if not ports_to_forward:
ports_to_forward = []
- self.device_id = device
+ self.device = device
self.shard_index = shard_index
- self.device = device_utils.DeviceUtils(self.device_id)
+ self.device_id = str(self.device)
if ports_to_forward:
self.ports_to_forward = ports_to_forward
@@ -117,10 +117,9 @@
# TODO(bulach): move this to SetUp() stage.
self.__StartForwarder()
- java_test_runner = test_runner.TestRunner(self.instrumentation_options,
- self.device_id,
- self.shard_index, test_pkg,
- additional_flags=additional_flags)
+ java_test_runner = test_runner.TestRunner(
+ self.instrumentation_options, self.device, self.shard_index,
+ test_pkg, additional_flags=additional_flags)
try:
java_test_runner.SetUp()
return java_test_runner.RunTest(test)[0]
diff --git a/build/android/pylib/host_driven/test_runner.py b/build/android/pylib/host_driven/test_runner.py
index 5e175bc..8620aa1 100644
--- a/build/android/pylib/host_driven/test_runner.py
+++ b/build/android/pylib/host_driven/test_runner.py
@@ -86,7 +86,7 @@
exception_raised = False
try:
- test.SetUp(str(self.device), self.shard_index)
+ test.SetUp(self.device, self.shard_index)
except Exception:
logging.exception(
'Caught exception while trying to run SetUp() for test: ' +
diff --git a/build/android/pylib/instrumentation/instrumentation_test_instance.py b/build/android/pylib/instrumentation/instrumentation_test_instance.py
index ccc0e72..0633f14 100644
--- a/build/android/pylib/instrumentation/instrumentation_test_instance.py
+++ b/build/android/pylib/instrumentation/instrumentation_test_instance.py
@@ -30,6 +30,17 @@
_DEFAULT_ANNOTATIONS = [
'Smoke', 'SmallTest', 'MediumTest', 'LargeTest',
'EnormousTest', 'IntegrationTest']
+_EXTRA_ENABLE_HTTP_SERVER = (
+ 'org.chromium.chrome.test.ChromeInstrumentationTestRunner.'
+ + 'EnableTestHttpServer')
+_EXTRA_DRIVER_TEST_LIST = (
+ 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TestList')
+_EXTRA_DRIVER_TEST_LIST_FILE = (
+ 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TestListFile')
+_EXTRA_DRIVER_TARGET_PACKAGE = (
+ 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TargetPackage')
+_EXTRA_DRIVER_TARGET_CLASS = (
+ 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TargetClass')
_NATIVE_CRASH_RE = re.compile('native crash', re.IGNORECASE)
_PICKLE_FORMAT_VERSION = 10
@@ -130,29 +141,35 @@
self._apk_under_test = None
self._package_info = None
+ self._suite = None
self._test_apk = None
self._test_jar = None
self._test_package = None
self._test_runner = None
self._test_support_apk = None
- self.__initializeApkAttributes(args, error_func)
+ self._initializeApkAttributes(args, error_func)
self._data_deps = None
self._isolate_abs_path = None
self._isolate_delegate = None
self._isolated_abs_path = None
self._test_data = None
- self.__initializeDataDependencyAttributes(args, isolate_delegate)
+ self._initializeDataDependencyAttributes(args, isolate_delegate)
self._annotations = None
self._excluded_annotations = None
self._test_filter = None
- self.__initializeTestFilterAttributes(args)
+ self._initializeTestFilterAttributes(args)
self._flags = None
- self.__initializeFlagAttributes(args)
+ self._initializeFlagAttributes(args)
- def __initializeApkAttributes(self, args, error_func):
+ self._driver_apk = None
+ self._driver_package = None
+ self._driver_name = None
+ self._initializeDriverAttributes()
+
+ def _initializeApkAttributes(self, args, error_func):
if args.apk_under_test.endswith('.apk'):
self._apk_under_test = args.apk_under_test
else:
@@ -164,20 +181,20 @@
error_func('Unable to find APK under test: %s' % self._apk_under_test)
if args.test_apk.endswith('.apk'):
- test_apk_root = os.path.splitext(os.path.basename(args.test_apk))[0]
+ self._suite = os.path.splitext(os.path.basename(args.test_apk))[0]
self._test_apk = args.test_apk
else:
- test_apk_root = args.test_apk
+ self._suite = args.test_apk
self._test_apk = os.path.join(
constants.GetOutDirectory(), constants.SDK_BUILD_APKS_DIR,
'%s.apk' % args.test_apk)
self._test_jar = os.path.join(
constants.GetOutDirectory(), constants.SDK_BUILD_TEST_JAVALIB_DIR,
- '%s.jar' % test_apk_root)
+ '%s.jar' % self._suite)
self._test_support_apk = os.path.join(
constants.GetOutDirectory(), constants.SDK_BUILD_TEST_JAVALIB_DIR,
- '%sSupport.apk' % test_apk_root)
+ '%sSupport.apk' % self._suite)
if not os.path.exists(self._test_apk):
error_func('Unable to find test APK: %s' % self._test_apk)
@@ -194,7 +211,7 @@
if not self._package_info:
logging.warning('Unable to find package info for %s', self._test_package)
- def __initializeDataDependencyAttributes(self, args, isolate_delegate):
+ def _initializeDataDependencyAttributes(self, args, isolate_delegate):
self._data_deps = []
if args.isolate_file_path:
self._isolate_abs_path = os.path.abspath(args.isolate_file_path)
@@ -215,7 +232,7 @@
if not self._isolate_delegate and not self._test_data:
logging.warning('No data dependencies will be pushed.')
- def __initializeTestFilterAttributes(self, args):
+ def _initializeTestFilterAttributes(self, args):
self._test_filter = args.test_filter
def annotation_dict_element(a):
@@ -240,7 +257,7 @@
else:
self._excluded_annotations = {}
- def __initializeFlagAttributes(self, args):
+ def _initializeFlagAttributes(self, args):
self._flags = ['--disable-fre', '--enable-test-intents']
# TODO(jbudorick): Transition "--device-flags" to "--device-flags-file"
if hasattr(args, 'device_flags') and args.device_flags:
@@ -252,9 +269,17 @@
stripped_lines = (l.strip() for l in device_flags_file)
self._flags.extend([flag for flag in stripped_lines if flag])
- @property
- def suite(self):
- return 'instrumentation'
+ def _initializeDriverAttributes(self):
+ self._driver_apk = os.path.join(
+ constants.GetOutDirectory(), constants.SDK_BUILD_APKS_DIR,
+ 'OnDeviceInstrumentationDriver.apk')
+ if os.path.exists(self._driver_apk):
+ self._driver_package = apk_helper.GetPackageName(
+ self._driver_apk)
+ self._driver_name = apk_helper.GetInstrumentationName(
+ self._driver_apk)
+ else:
+ self._driver_apk = None
@property
def apk_under_test(self):
@@ -265,10 +290,26 @@
return self._flags
@property
+ def driver_apk(self):
+ return self._driver_apk
+
+ @property
+ def driver_package(self):
+ return self._driver_package
+
+ @property
+ def driver_name(self):
+ return self._driver_name
+
+ @property
def package_info(self):
return self._package_info
@property
+ def suite(self):
+ return self._suite
+
+ @property
def test_apk(self):
return self._test_apk
@@ -446,6 +487,28 @@
return inflated_tests
@staticmethod
+ def GetHttpServerEnvironmentVars():
+ return {
+ _EXTRA_ENABLE_HTTP_SERVER: None,
+ }
+
+ def GetDriverEnvironmentVars(
+ self, test_list=None, test_list_file_path=None):
+ env = {
+ _EXTRA_DRIVER_TARGET_PACKAGE: self.test_package,
+ _EXTRA_DRIVER_TARGET_CLASS: self.test_runner,
+ }
+
+ if test_list:
+ env[_EXTRA_DRIVER_TEST_LIST] = ','.join(test_list)
+
+ if test_list_file_path:
+ env[_EXTRA_DRIVER_TEST_LIST_FILE] = (
+ os.path.basename(test_list_file_path))
+
+ return env
+
+ @staticmethod
def ParseAmInstrumentRawOutput(raw_output):
return ParseAmInstrumentRawOutput(raw_output)
diff --git a/build/android/pylib/local/device/local_device_instrumentation_test_run.py b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
index adc1037..e388fce 100644
--- a/build/android/pylib/local/device/local_device_instrumentation_test_run.py
+++ b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
@@ -130,22 +130,41 @@
#override
def _RunTest(self, device, test):
- test_name = self._GetTestName(test)
- logging.info('preparing to run %s: %s' % (test_name, test))
+ extras = self._test_instance.GetHttpServerEnvironmentVars()
- extras = {
- 'class': test_name,
- 'org.chromium.chrome.test.ChromeInstrumentationTestRunner'
- '.EnableTestHttpServer': '',
- }
- timeout = self._GetTimeoutFromAnnotations(test['annotations'], test_name)
+ if isinstance(test, list):
+ if not self._test_instance.driver_apk:
+ raise Exception('driver_apk does not exist. '
+ 'Please build it and try again.')
+
+ def name_and_timeout(t):
+ n = self._GetTestName(t)
+ i = self._GetTimeoutFromAnnotations(t['annotations'], n)
+ return (n, i)
+
+ test_names, timeouts = zip(*(name_and_timeout(t) for t in test))
+
+ test_name = ','.join(test_names)
+ target = '%s/%s' % (
+ self._test_instance.driver_package,
+ self._test_instance.driver_name)
+ extras.update(
+ self._test_instance.GetDriverEnvironmentVars(
+ test_list=test_names))
+ timeout = sum(timeouts)
+ else:
+ test_name = self._GetTestName(test)
+ target = '%s/%s' % (
+ self._test_instance.test_package, self._test_instance.test_runner)
+ extras['class'] = test_name
+ timeout = self._GetTimeoutFromAnnotations(test['annotations'], test_name)
+
+ logging.info('preparing to run %s: %s' % (test_name, test))
time_ms = lambda: int(time.time() * 1e3)
start_ms = time_ms()
output = device.StartInstrumentation(
- '%s/%s' % (self._test_instance.test_package,
- self._test_instance.test_runner),
- raw=True, extras=extras, timeout=timeout, retries=0)
+ target, raw=True, extras=extras, timeout=timeout, retries=0)
duration_ms = time_ms() - start_ms
# TODO(jbudorick): Make instrumentation tests output a JSON so this
diff --git a/build/android/pylib/perf/perf_control_unittest.py b/build/android/pylib/perf/perf_control_unittest.py
index dd7cb88..69b8b46 100644
--- a/build/android/pylib/perf/perf_control_unittest.py
+++ b/build/android/pylib/perf/perf_control_unittest.py
@@ -9,7 +9,6 @@
sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
-from pylib import android_commands
from pylib.device import device_utils
from pylib.perf import perf_control
@@ -18,10 +17,9 @@
if not os.getenv('BUILDTYPE'):
os.environ['BUILDTYPE'] = 'Debug'
- devices = android_commands.GetAttachedDevices()
+ devices = device_utils.DeviceUtils.HealthyDevices()
self.assertGreater(len(devices), 0, 'No device attached!')
- self._device = device_utils.DeviceUtils(
- android_commands.AndroidCommands(device=devices[0]))
+ self._device = devices[0]
def testHighPerfMode(self):
perf = perf_control.PerfControl(self._device)
diff --git a/build/android/pylib/perf/setup.py b/build/android/pylib/perf/setup.py
index 8884d60..8e1fc28 100644
--- a/build/android/pylib/perf/setup.py
+++ b/build/android/pylib/perf/setup.py
@@ -10,10 +10,10 @@
import os
import shutil
-from pylib import android_commands
from pylib import constants
from pylib import forwarder
from pylib.device import device_list
+from pylib.device import device_utils
from pylib.perf import test_runner
from pylib.utils import test_environment
@@ -22,10 +22,11 @@
devices_path = os.path.join(os.environ.get('CHROMIUM_OUT_DIR', 'out'),
device_list.LAST_DEVICES_FILENAME)
try:
- devices = device_list.GetPersistentDeviceList(devices_path)
+ devices = [device_utils.DeviceUtils(s)
+ for s in device_list.GetPersistentDeviceList(devices_path)]
except IOError as e:
logging.error('Unable to find %s [%s]', devices_path, e)
- devices = android_commands.GetAttachedDevices()
+ devices = device_utils.DeviceUtils.HealthyDevices()
return sorted(devices)
diff --git a/build/android/pylib/remote/device/remote_device_environment.py b/build/android/pylib/remote/device/remote_device_environment.py
index b69c7b2..d055ae0 100644
--- a/build/android/pylib/remote/device/remote_device_environment.py
+++ b/build/android/pylib/remote/device/remote_device_environment.py
@@ -78,7 +78,8 @@
self._remote_device_minimum_os = device_json.get(
'remote_device_minimum_os', None)
self._remote_device_os = device_json.get('remote_device_os', None)
- self._remote_device_timeout = device_json.get('remote_device_timeout', None)
+ self._remote_device_timeout = device_json.get(
+ 'remote_device_timeout', None)
self._results_path = device_json.get('results_path', None)
self._runner_package = device_json.get('runner_package', None)
self._runner_type = device_json.get('runner_type', None)
@@ -330,11 +331,6 @@
return self._network_config
@property
- def only_output_failures(self):
- # TODO(jbudorick): Remove this once b/18981674 is fixed.
- return True
-
- @property
def results_path(self):
return self._results_path
diff --git a/build/android/pylib/remote/device/remote_device_gtest_run.py b/build/android/pylib/remote/device/remote_device_gtest_run.py
index 973eebe..ec747f1 100644
--- a/build/android/pylib/remote/device/remote_device_gtest_run.py
+++ b/build/android/pylib/remote/device/remote_device_gtest_run.py
@@ -17,18 +17,14 @@
_EXTRA_COMMAND_LINE_FILE = (
- 'org.chromium.native_test.ChromeNativeTestActivity.CommandLineFile')
-# TODO(jbudorick): Remove this extra when b/18981674 is fixed.
-_EXTRA_ONLY_OUTPUT_FAILURES = (
- 'org.chromium.native_test.ChromeNativeTestInstrumentationTestRunner.'
- 'OnlyOutputFailures')
+ 'org.chromium.native_test.NativeTestActivity.CommandLineFile')
class RemoteDeviceGtestTestRun(remote_device_test_run.RemoteDeviceTestRun):
"""Run gtests and uirobot tests on a remote device."""
DEFAULT_RUNNER_PACKAGE = (
- 'org.chromium.native_test.ChromeNativeTestInstrumentationTestRunner')
+ 'org.chromium.native_test.NativeTestInstrumentationTestRunner')
#override
def TestPackage(self):
@@ -61,8 +57,6 @@
env_vars[_EXTRA_COMMAND_LINE_FILE] = os.path.basename(flag_file.name)
self._test_instance._data_deps.append(
(os.path.abspath(flag_file.name), None))
- if self._env.only_output_failures:
- env_vars[_EXTRA_ONLY_OUTPUT_FAILURES] = None
self._AmInstrumentTestSetup(
dummy_app_path, self._test_instance.apk, runner_package,
environment_variables=env_vars)
@@ -73,15 +67,13 @@
def _ParseTestResults(self):
logging.info('Parsing results from stdout.')
results = base_test_result.TestRunResults()
- output = self._results['results']['output'].splitlines()
+ output = self._GetRawTestOutput().splitlines()
output = (l[len(self._INSTRUMENTATION_STREAM_LEADER):] for l in output
if l.startswith(self._INSTRUMENTATION_STREAM_LEADER))
results_list = self._test_instance.ParseGTestOutput(output)
results.AddResults(results_list)
- if self._env.only_output_failures:
- logging.info('See logcat for more results information.')
if not self._results['results']['pass']:
results.AddResult(base_test_result.BaseTestResult(
'Remote Service detected error.',
base_test_result.ResultType.FAIL))
- return results
\ No newline at end of file
+ return results
diff --git a/build/android/pylib/remote/device/remote_device_helper.py b/build/android/pylib/remote/device/remote_device_helper.py
index 5b1411e..896ae99 100644
--- a/build/android/pylib/remote/device/remote_device_helper.py
+++ b/build/android/pylib/remote/device/remote_device_helper.py
@@ -20,4 +20,5 @@
error_msg: Error message to display if bad response is seen.
"""
if response.status_code != 200:
- raise RemoteDeviceError(error_msg)
+ raise RemoteDeviceError(
+ '%s (%d: %s)' % (error_msg, response.status_code, response.reason))
diff --git a/build/android/pylib/remote/device/remote_device_instrumentation_test_run.py b/build/android/pylib/remote/device/remote_device_instrumentation_test_run.py
index fe173a4..0b0afb1 100644
--- a/build/android/pylib/remote/device/remote_device_instrumentation_test_run.py
+++ b/build/android/pylib/remote/device/remote_device_instrumentation_test_run.py
@@ -8,6 +8,7 @@
import os
import tempfile
+from pylib import constants
from pylib.base import base_test_result
from pylib.remote.device import remote_device_test_run
from pylib.utils import apk_helper
@@ -25,9 +26,33 @@
def _TriggerSetUp(self):
"""Set up the triggering of a test run."""
logging.info('Triggering test run.')
- self._AmInstrumentTestSetup(
- self._test_instance._apk_under_test, self._test_instance.test_apk,
- self._test_instance.test_runner, environment_variables={})
+
+ with tempfile.NamedTemporaryFile(suffix='.txt') as test_list_file:
+ tests = self._test_instance.GetTests()
+ logging.debug('preparing to run %d instrumentation tests remotely:',
+ len(tests))
+ for t in tests:
+ test_name = '%s#%s' % (t['class'], t['method'])
+ logging.debug(' %s', test_name)
+ test_list_file.write('%s\n' % test_name)
+ test_list_file.flush()
+ self._test_instance._data_deps.append(
+ (os.path.abspath(test_list_file.name), None))
+
+ env_vars = self._test_instance.GetDriverEnvironmentVars(
+ test_list_file_path=test_list_file.name)
+ env_vars.update(self._test_instance.GetHttpServerEnvironmentVars())
+
+ logging.debug('extras:')
+ for k, v in env_vars.iteritems():
+ logging.debug(' %s: %s', k, v)
+
+ self._AmInstrumentTestSetup(
+ self._test_instance.apk_under_test,
+ self._test_instance.driver_apk,
+ self._test_instance.driver_name,
+ environment_variables=env_vars,
+ extra_apks=[self._test_instance.test_apk])
#override
def _ParseTestResults(self):
@@ -35,7 +60,7 @@
r = base_test_result.TestRunResults()
result_code, result_bundle, statuses = (
self._test_instance.ParseAmInstrumentRawOutput(
- self._results['results']['output'].splitlines()))
+ self._GetRawTestOutput().splitlines()))
result = self._test_instance.GenerateTestResults(
result_code, result_bundle, statuses, 0, 0)
diff --git a/build/android/pylib/remote/device/remote_device_test_run.py b/build/android/pylib/remote/device/remote_device_test_run.py
index 7aa91ae..60a0664 100644
--- a/build/android/pylib/remote/device/remote_device_test_run.py
+++ b/build/android/pylib/remote/device/remote_device_test_run.py
@@ -29,6 +29,8 @@
COMPLETE = 'complete'
HEARTBEAT_INTERVAL = 300
+ _RESULTS_FILE = 'appurify_results/result.txt'
+
def __init__(self, env, test_instance):
"""Constructor.
@@ -173,7 +175,7 @@
"""Download the test results from remote device service.
Args:
- results_path: path to download results to.
+ results_path: Path to download appurify results zipfile.
"""
if results_path:
logging.info('Downloading results to %s.' % results_path)
@@ -184,6 +186,21 @@
appurify_sanitized.utils.wget(self._results['results']['url'],
results_path)
+ def _GetRawTestOutput(self):
+ """Returns the test output."""
+ # TODO(mikecase): Remove getting results from zip when b/18981674 is fixed.
+ results_zipfile = self._env.results_path
+ if results_zipfile and os.path.exists(results_zipfile):
+ with zipfile.ZipFile(results_zipfile) as z:
+ with z.open(self._RESULTS_FILE, 'r') as r:
+ return r.read()
+ else:
+ logging.warning(
+ 'If the test output is too long, some test results may get cut off.')
+ logging.warning(
+ 'Use the --results-path option to ensure you get the full results.')
+ return self._results['results']['output']
+
def _GetTestStatus(self, test_run_id):
"""Checks the state of the test, and sets self._results
@@ -201,7 +218,7 @@
return self._results['status']
def _AmInstrumentTestSetup(self, app_path, test_path, runner_package,
- environment_variables):
+ environment_variables, extra_apks=None):
config = {'runner': runner_package}
if environment_variables:
config['environment_vars'] = ','.join(
@@ -213,6 +230,7 @@
if data_deps:
with tempfile.NamedTemporaryFile(suffix='.zip') as test_with_deps:
sdcard_files = []
+ additional_apks = []
host_test = os.path.basename(test_path)
with zipfile.ZipFile(test_with_deps.name, 'w') as zip_file:
zip_file.write(test_path, host_test, zipfile.ZIP_DEFLATED)
@@ -223,8 +241,14 @@
else:
zip_utils.WriteToZipFile(zip_file, h, os.path.basename(h))
sdcard_files.append(os.path.basename(h))
+ for a in extra_apks or ():
+ zip_utils.WriteToZipFile(zip_file, a, os.path.basename(a));
+ additional_apks.append(os.path.basename(a))
+
config['sdcard_files'] = ','.join(sdcard_files)
config['host_test'] = host_test
+ if additional_apks:
+ config['additional_apks'] = ','.join(additional_apks)
self._test_id = self._UploadTestToDevice(
'robotium', test_with_deps.name, app_id=self._app_id)
else:
@@ -238,7 +262,8 @@
def _UploadAppToDevice(self, app_path):
"""Upload app to device."""
- logging.info('Uploading %s to remote service.', app_path)
+ logging.info('Uploading %s to remote service as %s.', app_path,
+ self._test_instance.suite)
with open(app_path, 'rb') as apk_src:
with appurify_sanitized.SanitizeLogging(self._env.verbose_count,
logging.WARNING):
@@ -297,4 +322,4 @@
config_response = appurify_sanitized.api.config_upload(
self._env.token, config, self._test_id)
remote_device_helper.TestHttpResponse(
- config_response, 'Unable to upload test config.')
\ No newline at end of file
+ config_response, 'Unable to upload test config.')
diff --git a/build/android/pylib/utils/emulator.py b/build/android/pylib/utils/emulator.py
index 26b9109..635462f 100644
--- a/build/android/pylib/utils/emulator.py
+++ b/build/android/pylib/utils/emulator.py
@@ -15,7 +15,6 @@
import time
# TODO(craigdh): Move these pylib dependencies to pylib/utils/.
-from pylib import android_commands
from pylib import cmd_helper
from pylib import constants
from pylib import pexpect
@@ -90,14 +89,14 @@
running but a device slot is taken. A little bot trouble and and
we're out of room forever.
"""
- emulators = android_commands.GetAttachedDevices(hardware=False)
+ emulators = [d for d in device_utils.HealthyDevices() if d.adb.is_emulator]
if not emulators:
return
- for emu_name in emulators:
- cmd_helper.RunCmd(['adb', '-s', emu_name, 'emu', 'kill'])
+ for e in emulators:
+ e.adb.Emu(['kill'])
logging.info('Emulator killing is async; give a few seconds for all to die.')
for _ in range(5):
- if not android_commands.GetAttachedDevices(hardware=False):
+ if not any(d.adb.is_emulator for d in device_utils.HealthyDevices()):
return
time.sleep(1)
@@ -141,9 +140,9 @@
def _GetAvailablePort():
"""Returns an available TCP port for the console."""
used_ports = []
- emulators = android_commands.GetAttachedDevices(hardware=False)
+ emulators = [d for d in device_utils.HealthyDevices() if d.adb.is_emulator]
for emulator in emulators:
- used_ports.append(emulator.split('-')[1])
+ used_ports.append(emulator.adb.GetDeviceSerial().split('-')[1])
for port in PortPool.port_range():
if str(port) not in used_ports:
return port
diff --git a/build/android/pylib/utils/isolator.py b/build/android/pylib/utils/isolator.py
index 90d5ca0..cac39d8 100644
--- a/build/android/pylib/utils/isolator.py
+++ b/build/android/pylib/utils/isolator.py
@@ -36,6 +36,7 @@
'enable_plugins': '0',
'fastbuild': '0',
'icu_use_data_file_flag': '1',
+ 'kasko': '0',
'lsan': '0',
'msan': '0',
# TODO(maruel): This may not always be true.
diff --git a/build/android/pylib/utils/md5sum.py b/build/android/pylib/utils/md5sum.py
index 4d7d0b0..d59245c 100644
--- a/build/android/pylib/utils/md5sum.py
+++ b/build/android/pylib/utils/md5sum.py
@@ -34,9 +34,11 @@
if isinstance(paths, basestring):
paths = [paths]
- out = cmd_helper.GetCmdOutput(
- [os.path.join(constants.GetOutDirectory(), 'md5sum_bin_host')] +
- [p for p in paths])
+ md5sum_bin_host_path = os.path.join(
+ constants.GetOutDirectory(), 'md5sum_bin_host')
+ if not os.path.exists(md5sum_bin_host_path):
+ raise IOError('File not built: %s' % md5sum_bin_host_path)
+ out = cmd_helper.GetCmdOutput([md5sum_bin_host_path] + [p for p in paths])
return _ParseMd5SumOutput(out.splitlines())
@@ -53,9 +55,10 @@
paths = [paths]
if not device.FileExists(MD5SUM_DEVICE_BIN_PATH):
- device.adb.Push(
- os.path.join(constants.GetOutDirectory(), 'md5sum_dist'),
- MD5SUM_DEVICE_LIB_PATH)
+ md5sum_dist_path = os.path.join(constants.GetOutDirectory(), 'md5sum_dist')
+ if not os.path.exists(md5sum_dist_path):
+ raise IOError('File not built: %s' % md5sum_dist_path)
+ device.adb.Push(md5sum_dist_path, MD5SUM_DEVICE_LIB_PATH)
out = []
diff --git a/build/android/pylib/utils/md5sum_test.py b/build/android/pylib/utils/md5sum_test.py
index de9cd35..5bdee32 100755
--- a/build/android/pylib/utils/md5sum_test.py
+++ b/build/android/pylib/utils/md5sum_test.py
@@ -24,6 +24,8 @@
self._patchers = [
mock.patch('pylib.constants.GetOutDirectory',
new=mock.Mock(return_value=TEST_OUT_DIR)),
+ mock.patch('os.path.exists',
+ new=mock.Mock(return_value=True)),
]
for p in self._patchers:
p.start()
diff --git a/build/android/setup.gyp b/build/android/setup.gyp
index 7dce19d..b3c3422 100644
--- a/build/android/setup.gyp
+++ b/build/android/setup.gyp
@@ -16,7 +16,7 @@
{
'destination': '<(SHARED_LIB_DIR)/',
'files': [
- '<(android_stlport_libs_dir)/libstlport_shared.so',
+ '<(android_libcpp_libs_dir)/libc++_shared.so',
],
},
],
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index c54ed28..b9d2a3f 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -16,7 +16,6 @@
import threading
import unittest
-from pylib import android_commands
from pylib import constants
from pylib import forwarder
from pylib import ports
@@ -25,6 +24,8 @@
from pylib.base import test_dispatcher
from pylib.base import test_instance_factory
from pylib.base import test_run_factory
+from pylib.device import device_errors
+from pylib.device import device_utils
from pylib.gtest import gtest_config
from pylib.gtest import setup as gtest_setup
from pylib.gtest import test_options as gtest_test_options
@@ -110,7 +111,7 @@
if args.build_directory:
constants.SetBuildDirectory(args.build_directory)
if args.output_directory:
- constants.SetOutputDirectort(args.output_directory)
+ constants.SetOutputDirectory(args.output_directory)
if args.adb_path:
constants.SetAdbPath(args.adb_path)
# Some things such as Forwarder require ADB to be in the environment path.
@@ -867,18 +868,19 @@
Returns:
A list of attached devices.
"""
- attached_devices = []
-
- attached_devices = android_commands.GetAttachedDevices()
+ attached_devices = device_utils.DeviceUtils.HealthyDevices()
if test_device:
- assert test_device in attached_devices, (
- 'Did not find device %s among attached device. Attached devices: %s'
- % (test_device, ', '.join(attached_devices)))
- attached_devices = [test_device]
+ test_device = [d for d in attached_devices if d == test_device]
+ if not test_device:
+ raise device_errors.DeviceUnreachableError(
+ 'Did not find device %s among attached device. Attached devices: %s'
+ % (test_device, ', '.join(attached_devices)))
+ return test_device
- assert attached_devices, 'No devices attached.'
-
- return sorted(attached_devices)
+ else:
+ if not attached_devices:
+ raise device_errors.NoDevicesError()
+ return sorted(attached_devices)
def RunTestsCommand(args, parser):
diff --git a/build/apk_test.gypi b/build/apk_test.gypi
index 792d92c..3a66e3b 100644
--- a/build/apk_test.gypi
+++ b/build/apk_test.gypi
@@ -22,6 +22,7 @@
'<(DEPTH)/base/base.gyp:base_java',
'<(DEPTH)/build/android/pylib/device/commands/commands.gyp:chromium_commands',
'<(DEPTH)/build/android/pylib/remote/device/dummy/dummy.gyp:remote_device_dummy_apk',
+ '<(DEPTH)/testing/android/appurify_support.gyp:appurify_support_java',
'<(DEPTH)/tools/android/android_tools.gyp:android_tools',
],
'conditions': [
diff --git a/build/common.gypi b/build/common.gypi
index c5a8fac..a406248 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -173,6 +173,7 @@
# The system root for cross-compiles. Default: none.
'sysroot%': '',
+ 'use_sysroot%': 0,
'chroot_cmd%': '',
# The system libdir used for this ABI.
@@ -416,9 +417,6 @@
# See https://code.google.com/p/sawbuck/wiki/SyzyASanHowTo
'syzyasan%': 0,
- # Enable crash reporting via Kasko.
- 'kasko%': 0,
-
# Enable building with LSan (Clang's -fsanitize=leak option).
# -fsanitize=leak only works with clang, but lsan=1 implies clang=1
# See https://sites.google.com/a/chromium.org/dev/developers/testing/leaksanitizer
@@ -941,7 +939,7 @@
'sysroot%': '<!(cd <(DEPTH) && pwd -P)/chrome/installer/linux/debian_wheezy_arm-sysroot',
}], # OS=="linux" and target_arch=="arm" and chromeos==0
- ['OS=="linux" and branding=="Chrome" and buildtype=="Official" and chromeos==0', {
+ ['OS=="linux" and ((branding=="Chrome" and buildtype=="Official" and chromeos==0) or use_sysroot==1)' , {
'conditions': [
['target_arch=="x64"', {
'sysroot%': '<!(cd <(DEPTH) && pwd -P)/chrome/installer/linux/debian_wheezy_amd64-sysroot',
@@ -1011,6 +1009,15 @@
}, {
'sas_dll_path%': '<(DEPTH)/third_party/platformsdk_win7/files/redist/x86',
}],
+
+ # Enable crash reporting via Kasko.
+ ['OS=="win" and target_arch=="ia32"', {
+ # TODO(erikwright): This should be disabled after a single ship on Canary channel.
+ 'kasko%': 1,
+ }, {
+ 'kasko%': 0,
+ }],
+
],
# Setting this to '0' will cause V8's startup snapshot to be
@@ -1688,7 +1695,7 @@
'android_ndk_absolute_root%': '<(android_ndk_absolute_root)',
'android_sdk_root%': '<(android_sdk_root)',
'android_sdk_version%': '<(android_sdk_version)',
- 'android_stlport_root': '<(android_ndk_root)/sources/cxx-stl/stlport',
+ 'android_libcpp_root': '<(android_ndk_root)/sources/cxx-stl/llvm-libc++',
'host_os%': '<(host_os)',
'android_sdk%': '<(android_sdk_root)/platforms/android-<(android_sdk_version)',
@@ -1764,9 +1771,9 @@
'android_sdk%': '<(android_sdk)',
'android_sdk_jar%': '<(android_sdk)/android.jar',
- 'android_stlport_root': '<(android_stlport_root)',
- 'android_stlport_include': '<(android_stlport_root)/stlport',
- 'android_stlport_libs_dir': '<(android_stlport_root)/libs/<(android_app_abi)',
+ 'android_libcpp_root': '<(android_libcpp_root)',
+ 'android_libcpp_include': '<(android_libcpp_root)/libcxx/include',
+ 'android_libcpp_libs_dir': '<(android_libcpp_root)/libs/<(android_app_abi)',
'host_os%': '<(host_os)',
# Location of the "objcopy" binary, used by both gyp and scripts.
@@ -1929,9 +1936,14 @@
},{
'winsdk_arch%': '<(target_arch)',
}],
- ['component=="shared_library"', {
+ ['component=="shared_library" or MSVS_VERSION == "2015"', {
+ # TODO(scottmg): The allocator shimming doesn't work on the 2015 CRT
+ # and we are hoping to be able to remove it if an additional feature
+ # lands in the 2015 CRT API. For now, don't shim and revisit once
+ # VS2015 is RTM: http://crbug.com/481611.
'win_use_allocator_shim%': 0,
- },{
+ }],
+ ['component=="static_library"', {
# Turn on multiple dll by default on Windows when in static_library.
'chrome_multiple_dll%': 1,
}],
@@ -2168,17 +2180,23 @@
],
},
'clang_dynlib_flags%': '-Xclang -load -Xclang <(clang_lib_path) ',
+ 'clang_plugin_args%': '',
}, { # OS == "win"
# On Windows, the plugin is built directly into clang, so there's
# no need to load it dynamically.
'clang_dynlib_flags%': '',
+
+ # Don't error on plugin warnings on Windows until pre-existing warnings
+ # are cleaned up. https://crbug.com/467287
+ 'clang_plugin_args%': '-Xclang -plugin-arg-find-bad-constructs -Xclang warn-only',
}]
],
},
# If you change these, also change build/config/clang/BUILD.gn.
'clang_chrome_plugins_flags%':
'<(clang_dynlib_flags)'
- '-Xclang -add-plugin -Xclang find-bad-constructs',
+ '-Xclang -add-plugin -Xclang find-bad-constructs '
+ '<(clang_plugin_args)',
}],
['asan==1 or msan==1 or lsan==1 or tsan==1', {
'clang%': 1,
@@ -4085,9 +4103,6 @@
'cflags!': [
'-fstack-protector', # stack protector is always enabled on arm64.
],
- 'ldflags': [
- '-fuse-ld=gold',
- ],
}],
],
}],
@@ -4630,9 +4645,9 @@
# Figure this out early since it needs symbols from libgcc.a, so it
# has to be before that in the set of libraries.
['component=="shared_library"', {
- 'android_stlport_library': 'stlport_shared',
+ 'android_libcpp_library': 'c++_shared',
}, {
- 'android_stlport_library': 'stlport_static',
+ 'android_libcpp_library': 'c++_static',
}],
],
@@ -4712,17 +4727,17 @@
'-finline-limit=64',
'<@(release_extra_cflags)',
'--sysroot=<(android_ndk_sysroot)',
- # NOTE: The stlport header include paths below are specified in
+ # NOTE: The libc++ header include paths below are specified in
# cflags rather than include_dirs because they need to come
# after include_dirs.
# The include ordering here is important; change with caution.
- '-isystem<(android_stlport_include)',
+ '-isystem<(android_libcpp_include)',
+ '-isystem<(android_ndk_root)/sources/cxx-stl/llvm-libc++abi/libcxxabi/include',
+ '-isystem<(android_ndk_root)/sources/android/support/include',
],
'defines': [
'ANDROID',
'__GNU_SOURCE=1', # Necessary for clone()
- 'USE_STLPORT=1',
- '_STLP_USE_PTR_SPECIALIZATIONS=1',
'CHROME_BUILD_ID="<(chrome_build_id)"',
# The NDK has these things, but doesn't define the constants
# to say that it does. Define them here instead.
@@ -4735,11 +4750,11 @@
'-Wl,--no-undefined',
'--sysroot=<(android_ndk_sysroot)',
'-nostdlib',
- '-L<(android_stlport_libs_dir)',
- # Don't allow visible symbols from libgcc or stlport to be
+ '-L<(android_libcpp_libs_dir)',
+ # Don't allow visible symbols from libgcc or libc++ to be
# re-exported.
'-Wl,--exclude-libs=libgcc.a',
- '-Wl,--exclude-libs=libstlport_static.a',
+ '-Wl,--exclude-libs=libc++_static.a',
# Don't allow visible symbols from libraries that contain
# assembly code with symbols that aren't hidden properly.
# http://crbug.com/448386
@@ -4752,7 +4767,8 @@
'-Wl,--exclude-libs=libvpx.a',
],
'libraries': [
- '-l<(android_stlport_library)',
+ '-l<(android_libcpp_library)',
+ '-latomic',
# Manually link the libgcc.a that the cross compiler uses.
'<!(<(android_toolchain)/*-gcc -print-libgcc-file-name)',
'-lc',
@@ -4772,6 +4788,11 @@
],
}],
['clang==1', {
+ 'libraries!': [
+ # Clang with libc++ does not require an explicit atomic
+ # library reference.
+ '-latomic',
+ ],
'cflags': [
# Work around incompatibilities between bionic and clang
# headers.
@@ -5119,6 +5140,22 @@
}],
],
},
+ 'configurations': {
+ 'Release_Base': {
+ 'conditions': [
+ ['branding=="Chrome" and buildtype=="Official"', {
+ 'xcode_settings': {
+ 'OTHER_CFLAGS': [
+ # The Google Chrome Framework dSYM generated by dsymutil has
+ # grown larger than 4GB, which dsymutil can't handle. Reduce
+ # the amount of debug symbols.
+ '-fno-standalone-debug', # See http://crbug.com/479841
+ ]
+ },
+ }],
+ ],
+ }, # configuration "Release"
+ }, # configurations
'xcode_settings': {
'GCC_DYNAMIC_NO_PIC': 'NO', # No -mdynamic-no-pic
# (Equivalent to -fPIC)
@@ -5136,16 +5173,6 @@
# specified or not.
'-fno-strict-aliasing', # See http://crbug.com/32204.
],
- 'conditions': [
- ['branding=="Chrome" and buildtype=="Official"', {
- 'OTHER_CFLAGS': [
- # The Google Chrome Framework dSYM generated by dsymutil has
- # grown larger than 4GB, which dsymutil can't handle. Reduce
- # the amount of debug symbols.
- '-gline-tables-only', # See http://crbug.com/479841
- ]
- }],
- ],
},
'target_conditions': [
['_type=="executable"', {
@@ -5769,13 +5796,20 @@
'AdditionalOptions': [
'-fsanitize-coverage=<(sanitizer_coverage)',
],
- 'defines': [
- 'SANITIZER_COVERAGE',
- ],
},
}],
],
},
+ 'conditions': [
+ ['sanitizer_coverage!=0', {
+ # TODO(asan/win): Move this down into the general
+ # win-target_defaults section once the 64-bit asan runtime
+ # exists. See crbug.com/345874.
+ 'defines': [
+ 'SANITIZER_COVERAGE',
+ ],
+ }],
+ ],
},
'x64_Base': {
'msvs_settings': {
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn
index 22cb45a..1bd666b 100644
--- a/build/config/BUILD.gn
+++ b/build/config/BUILD.gn
@@ -3,6 +3,7 @@
# found in the LICENSE file.
import("//build/config/allocator.gni")
+import("//build/config/chrome_build.gni")
import("//build/config/crypto.gni")
import("//build/config/features.gni")
import("//build/config/ui.gni")
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index 455ec0d..2274c0e 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -66,11 +66,13 @@
# Selects the desired build flavor. Official builds get additional
# processing to prepare for release. Normally you will want to develop and
# test with this flag off.
+ # TODO(brettw) move to chrome_build.gni when DEPS are updated.
is_official_build = false
# Select the desired branding flavor. False means normal Chromium branding,
# true means official Google Chrome branding (requires extra Google-internal
# resources).
+ # TODO(brettw) move to chrome_build.gni when DEPS are updated.
is_chrome_branded = false
# Compile for Address Sanitizer to find memory bugs.
diff --git a/build/config/android/config.gni b/build/config/android/config.gni
index 77ee311..093e8b3 100644
--- a/build/config/android/config.gni
+++ b/build/config/android/config.gni
@@ -157,12 +157,12 @@
android_gdbserver =
"$android_ndk_root/prebuilt/$android_prebuilt_arch/gdbserver/gdbserver"
- # stlport stuff --------------------------------------------------------------
+ # libc++ stuff ---------------------------------------------------------------
if (component_mode == "shared_library") {
- android_stlport_library = "stlport_shared"
+ android_libcpp_library = "c++_shared"
} else {
- android_stlport_library = "stlport_static"
+ android_libcpp_library = "c++_static"
}
# ABI ------------------------------------------------------------------------
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 39b2f39..b1b23b0 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -1555,8 +1555,8 @@
android_apk(target_name) {
final_apk_path = "$root_build_dir/${apk_name}_apk/${apk_name}-debug.apk"
java_files = [
- "//testing/android/native_test/java/src/org/chromium/native_test/ChromeNativeTestActivity.java",
- "//testing/android/native_test/java/src/org/chromium/native_test/ChromeNativeTestInstrumentationTestRunner.java",
+ "//testing/android/native_test/java/src/org/chromium/native_test/NativeTestActivity.java",
+ "//testing/android/native_test/java/src/org/chromium/native_test/NativeTestInstrumentationTestRunner.java",
]
android_manifest = "//testing/android/native_test/java/AndroidManifest.xml"
native_libs = [ unittests_binary ]
@@ -1566,6 +1566,7 @@
deps = [
"//base:base_java",
"//build/android/pylib/remote/device/dummy:remote_device_dummy_apk",
+ "//testing/android/appurify_support:appurify_support_java",
]
if (defined(invoker.deps)) {
deps += invoker.deps
diff --git a/build/config/chrome_build.gni b/build/config/chrome_build.gni
new file mode 100644
index 0000000..e2ff123
--- /dev/null
+++ b/build/config/chrome_build.gni
@@ -0,0 +1,22 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+declare_args() {
+ # Selects the desired build flavor. Official builds get additional
+ # processing to prepare for release. Normally you will want to develop and
+ # test with this flag off.
+ # TODO(brettw) move here from BUILDCONFIG.gn when DEPS are updated.
+ #is_official_build = false
+
+ # Select the desired branding flavor. False means normal Chromium branding,
+ # true means official Google Chrome branding (requires extra Google-internal
+ # resources).
+ # TODO(brettw) move here from BUILDCONFIG.gn when DEPS are updated.
+ #is_chrome_branded = false
+
+ # Break chrome.dll into multple pieces based on process type. Only available
+ # on Windows.
+ # TODO(brettw) make this work. When it does, the declaration should be:
+ is_multi_dll_chrome = is_win && !is_component_build
+}
diff --git a/build/config/clang/BUILD.gn b/build/config/clang/BUILD.gn
index 3d96500..e79a7b9 100644
--- a/build/config/clang/BUILD.gn
+++ b/build/config/clang/BUILD.gn
@@ -31,6 +31,16 @@
]
}
+ if (is_win) {
+ # Don't error on plugin warnings on Windows until pre-existing warnings
+ # are cleaned up. https://crbug.com/467287
+ cflags += [
+ "-Xclang",
+ "-plugin-arg-find-bad-constructs",
+ "-Xclang warn-only",
+ ]
+ }
+
cflags += [
"-Xclang",
"-add-plugin",
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index c217154..ad94705 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -3,6 +3,7 @@
# found in the LICENSE file.
import("//build/config/android/config.gni")
+import("//build/config/chrome_build.gni")
if (current_cpu == "arm") {
import("//build/config/arm.gni")
}
@@ -461,10 +462,10 @@
ldflags += [
"-Wl,--no-undefined",
- # Don't allow visible symbols from libgcc or stlport to be
+ # Don't allow visible symbols from libgcc or libc++ to be
# re-exported.
"-Wl,--exclude-libs=libgcc.a",
- "-Wl,--exclude-libs=libstlport_static.a",
+ "-Wl,--exclude-libs=libc++_static.a",
# Don't allow visible symbols from libraries that contain
# assembly code with symbols that aren't hidden properly.
@@ -546,7 +547,7 @@
]
}
- # Stlport setup. Android uses a different (smaller) version of the STL.
+ # Android standard library setup.
if (is_android) {
if (is_clang) {
# Work around incompatibilities between bionic and clang headers.
@@ -556,11 +557,7 @@
]
}
- defines += [
- "USE_STLPORT=1",
- "_STLP_USE_PTR_SPECIALIZATIONS=1",
- "__GNU_SOURCE=1", # Necessary for clone().
- ]
+ defines += [ "__GNU_SOURCE=1" ] # Necessary for clone().
# TODO(jdduke) Re-enable on mips after resolving linking
# issues with libc++ (crbug.com/456380).
@@ -569,45 +566,48 @@
}
ldflags += [ "-nostdlib" ]
- # NOTE: The stlport header include paths below are specified in cflags
+ # NOTE: The libc++ header include paths below are specified in cflags
# rather than include_dirs because they need to come after include_dirs.
# Think of them like system headers, but don't use '-isystem' because the
# arm-linux-androideabi-4.4.3 toolchain (circa Gingerbread) will exhibit
# strange errors. The include ordering here is important; change with
# caution.
- android_stlport_root = "$android_ndk_root/sources/cxx-stl/stlport"
+ android_libcpp_root = "$android_ndk_root/sources/cxx-stl/llvm-libc++"
- cflags += [ "-isystem" +
- rebase_path("$android_stlport_root/stlport", root_build_dir) ]
- lib_dirs += [ "$android_stlport_root/libs/$android_app_abi" ]
+ cflags += [
+ "-isystem" +
+ rebase_path("$android_libcpp_root/libcxx/include", root_build_dir),
+ "-isystem" + rebase_path(
+ "$android_ndk_root/sources/cxx-stl/llvm-libc++abi/libcxxabi/include",
+ root_build_dir),
+ "-isystem" +
+ rebase_path("$android_ndk_root/sources/android/support/include",
+ root_build_dir),
+ ]
+
+ lib_dirs += [ "$android_libcpp_root/libs/$android_app_abi" ]
if (component_mode == "shared_library") {
- libs += [ "stlport_shared" ]
+ android_libcpp_library = "c++_shared"
} else {
- libs += [ "stlport_static" ]
- }
-
- if (current_cpu == "mipsel") {
- libs += [
- # ld linker is used for mips Android, and ld does not accept library
- # absolute path prefixed by "-l"; Since libgcc does not exist in mips
- # sysroot the proper library will be linked.
- # TODO(gordanac): Remove once gold linker is used for mips Android.
- "gcc",
- ]
- } else {
- libs += [
- # Manually link the libgcc.a that the cross compiler uses. This is
- # absolute because the linker will look inside the sysroot if it's not.
- rebase_path(android_libgcc_file),
- ]
+ android_libcpp_library = "c++_static"
}
libs += [
+ "$android_libcpp_library",
+
+ # Manually link the libgcc.a that the cross compiler uses. This is
+ # absolute because the linker will look inside the sysroot if it's not.
+ rebase_path(android_libgcc_file),
"c",
"dl",
"m",
]
+
+ # Clang with libc++ does not require an explicit atomic library reference.
+ if (!is_clang) {
+ libs += [ "atomic" ]
+ }
}
}
diff --git a/build/config/features.gni b/build/config/features.gni
index dd7b081..290c1d6 100644
--- a/build/config/features.gni
+++ b/build/config/features.gni
@@ -11,6 +11,7 @@
#
# See also build/config/ui.gni
+import("//build/config/chrome_build.gni")
if (is_android) {
import("//build/config/android/config.gni")
}
@@ -32,8 +33,8 @@
# the commented out logic.
# Eventually we want this to be:
# enable_nacl = !is_ios && !is_android
- enable_nacl =
- (is_linux && !is_chromeos && !is_debug && current_cpu == "x64") || is_nacl
+ enable_nacl = (is_linux && !is_chromeos && !is_component_build &&
+ current_cpu == "x64") || is_nacl
enable_nacl_untrusted = enable_nacl
enable_pnacl = enable_nacl_untrusted
@@ -84,6 +85,20 @@
# Enables browser side Content Decryption Modules. Required for embedders
# (e.g. Android and ChromeCast) that use a browser side CDM.
enable_browser_cdms = is_android
+
+ # Variable safe_browsing is used to control the build time configuration for
+ # safe browsing feature. Safe browsing can be compiled in 3 different levels:
+ # 0 disables it, 1 enables it fully, and 2 enables only UI and reporting
+ # features without enabling phishing and malware detection. This is useful to
+ # integrate a third party phishing/malware detection to existing safe browsing
+ # logic.
+ if (is_android) {
+ safe_browsing_mode = 2
+ } else if (is_ios) {
+ safe_browsing_mode = 0
+ } else {
+ safe_browsing_mode = 1
+ }
}
# Additional dependent variables -----------------------------------------------
@@ -133,19 +148,6 @@
enable_extensions = !is_android && !is_ios
-# Variable safe_browsing is used to control the build time configuration for
-# safe browsing feature. Safe browsing can be compiled in 3 different levels: 0
-# disables it, 1 enables it fully, and 2 enables only UI and reporting features
-# without enabling phishing and malware detection. This is useful to integrate
-# a third party phishing/malware detection to existing safe browsing logic.
-if (is_android) {
- safe_browsing_mode = 2
-} else if (is_ios) {
- safe_browsing_mode = 0
-} else {
- safe_browsing_mode = 1
-}
-
enable_task_manager = !is_ios && !is_android
use_cups = is_desktop_linux || is_mac
diff --git a/build/config/mac/mac_sdk.gni b/build/config/mac/mac_sdk.gni
index 44995a3..600085e 100644
--- a/build/config/mac/mac_sdk.gni
+++ b/build/config/mac/mac_sdk.gni
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//build/config/chrome_build.gni")
+
declare_args() {
# Minimum supported version of the Mac SDK.
mac_sdk_min = "10.6"
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn
index 63728d9..3972a5c 100644
--- a/build/config/sanitizers/BUILD.gn
+++ b/build/config/sanitizers/BUILD.gn
@@ -22,11 +22,18 @@
}
source_set("options_sources") {
- visibility = [ ":deps" ]
+ visibility = [
+ ":deps",
+ "//:gn_visibility",
+ ]
sources = [
"//build/sanitizers/sanitizer_options.cc",
]
+ if (is_asan) {
+ sources += [ "//build/sanitizers/asan_suppressions.cc" ]
+ }
+
if (is_tsan) {
sources += [ "//build/sanitizers/tsan_suppressions.cc" ]
}
diff --git a/build/config/sysroot.gni b/build/config/sysroot.gni
index 057971d..e5a9c2b 100644
--- a/build/config/sysroot.gni
+++ b/build/config/sysroot.gni
@@ -5,6 +5,8 @@
# This header file defines the "sysroot" variable which is the absolute path
# of the sysroot. If no sysroot applies, the variable will be an empty string.
+import("//build/config/chrome_build.gni")
+
declare_args() {
# The absolute path of the sysroot that is applied when compiling using
# the target toolchain.
diff --git a/build/gn_migration.gypi b/build/gn_migration.gypi
index 58e7ff5..4257cc0 100644
--- a/build/gn_migration.gypi
+++ b/build/gn_migration.gypi
@@ -2,36 +2,40 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-# This file defines three targets that we are using to
-# track the progress of the GYP->GN migration:
+# This file defines five targets that we are using to track the progress of the
+# GYP->GN migration:
#
-# If you run 'ninja gn_build gyp_remaining gyp_groups', and then
-# run 'ninja', the second ninja invocation should do nothing. This
-# indicates that everything built by a ninja build is in fact
-# listed in one of these targets.
+# 'both_gn_and_gyp' lists what GN is currently capable of building and should
+# match the 'both_gn_and_gyp' target in //BUILD.gn.
#
-# 'gn_all' lists what GN is currently capable of building and should
-# match the 'gn_all' target in //BUILD.gn.
+# 'gyp_all' Should include everything built when building "all"; i.e., if you
+# type 'ninja gyp_all' and then 'ninja all', the second build should do
+# nothing. 'gyp_all' should just depend on the other four targets.
+#
+# 'gyp_only' lists any targets that are not meant to be ported over to the GN
+# build.
#
# 'gyp_remaining' lists all of the targets that still need to be converted,
-# i.e., all of the other (non-empty) targets that a GYP build
-# will build.
+# i.e., all of the other (non-empty) targets that a GYP build will build.
#
-# 'gyp_groups' lists any empty (group) targets in the GYP build that
-# are not picked up by gn_all or gyp_remaining; this is a
-# separate target to ensure that when we build it, only
-# stamp targets file are we don't accidentally pick up something
-# not listed in one of the other two targets.
-#
-# TODO(GYP), TODO(dpranke) Add a build step to the bot that enforces the
-# above contracts.
+# TODO(GYP): crbug.com/481694. Add a build step to the bot that enforces the
+# above contracts.
{
'targets': [
{
- # This target should mirror the structure of //:gn_all
- # as closely as possible, for ease of comparison.
- 'target_name': 'gn_all',
+ 'target_name': 'gyp_all',
+ 'type': 'none',
+ 'dependencies': [
+ 'both_gn_and_gyp',
+ 'gyp_only',
+ 'gyp_remaining',
+ ]
+ },
+ {
+ # This target should mirror the structure of //:both_gn_and_gyp
+ # in src/BUILD.gn as closely as possible, for ease of comparison.
+ 'target_name': 'both_gn_and_gyp',
'type': 'none',
'dependencies': [
'../base/base.gyp:base_i18n_perftests',
@@ -98,6 +102,7 @@
'../media/media.gyp:ffmpeg_regression_tests', # TODO(GYP) this should be conditional on media_use_ffmpeg
'../media/media.gyp:media_perftests',
'../media/media.gyp:media_unittests',
+ '../media/midi/midi.gyp:midi_unittests',
'../media/cast/cast.gyp:cast_benchmarks',
'../media/cast/cast.gyp:cast_unittests',
'../media/cast/cast.gyp:generate_barcode_video',
@@ -197,6 +202,7 @@
'../ui/display/display.gyp:display_unittests',
'../ui/events/events.gyp:events_unittests',
'../ui/gfx/gfx_tests.gyp:gfx_unittests',
+ '../ui/gl/gl_tests.gyp:gl_unittests',
'../ui/message_center/message_center.gyp:message_center_unittests',
'../ui/snapshot/snapshot.gyp:snapshot_unittests',
'../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
@@ -460,6 +466,7 @@
['OS=="win"', {
'dependencies': [
'../base/base.gyp:pe_image_test',
+ '../chrome/chrome.gyp:crash_service',
'../chrome_elf/chrome_elf.gyp:chrome_elf_unittests',
'../chrome_elf/chrome_elf.gyp:dll_hash_main',
'../components/components.gyp:wifi_test',
@@ -521,6 +528,7 @@
'../gpu/gpu.gyp:gpu_unittests_run',
'../media/cast/cast.gyp:cast_unittests_run',
'../media/media.gyp:media_unittests_run',
+ '../media/midi/midi.gyp:midi_unittests_run',
'../net/net.gyp:net_unittests_run',
'../sql/sql.gyp:sql_unittests_run',
'../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests_run',
@@ -606,7 +614,6 @@
'../chrome/chrome.gyp:app_installer',
'../chrome/chrome.gyp:app_installer_unittests',
'../chrome/chrome.gyp:app_shim',
- '../chrome/chrome.gyp:crash_service',
'../chrome/chrome.gyp:gcapi_dll',
'../chrome/chrome.gyp:gcapi_test',
'../chrome/chrome.gyp:installer_util_unittests',
@@ -666,39 +673,6 @@
}],
],
},
- {
- # This target, when built, should cause no actual work
- # to be done, just update a bunch of stamp files.
- 'target_name': 'gyp_groups',
- 'type': 'none',
- 'dependencies': [
- 'All',
- 'blink_tests',
- 'chromium_builder_asan',
- 'chromium_builder_chromedriver',
- 'chromium_builder_perf',
- 'chromium_builder_tests',
- 'chromium_builder_webrtc',
- 'chromium_gpu_builder',
- 'chromium_gpu_debug_builder',
- ],
- 'conditions': [
- ['use_aura==1', {
- 'dependencies': [
- 'aura_builder',
- ]
- }],
- ['OS=="win"', {
- 'dependencies': [
- 'chromium_builder',
- 'chromium_builder_dbg_drmemory_win',
- 'chromium_builder_nacl_sdk',
- 'chromium_builder_lkgr_drmemory_win',
- 'chromium_builder_dbg_tsan_win',
- ],
- }],
- ],
- },
]
}
diff --git a/build/gyp_chromium b/build/gyp_chromium
index 4ed15ba..736062e 100755
--- a/build/gyp_chromium
+++ b/build/gyp_chromium
@@ -254,16 +254,18 @@
else:
args.append(os.path.join(script_dir, 'all.gyp'))
+ supplemental_includes = GetSupplementalFiles()
+ gyp_vars_dict = GetGypVars(supplemental_includes)
# There shouldn't be a circular dependency relationship between .gyp files,
# but in Chromium's .gyp files, on non-Mac platforms, circular relationships
# currently exist. The check for circular dependencies is currently
- # bypassed on other platforms, but is left enabled on the Mac, where a
- # violation of the rule causes Xcode to misbehave badly.
+ # bypassed on other platforms, but is left enabled on iOS, where a violation
+ # of the rule causes Xcode to misbehave badly.
# TODO(mark): Find and kill remaining circular dependencies, and remove this
# option. http://crbug.com/35878.
# TODO(tc): Fix circular dependencies in ChromiumOS then add linux2 to the
# list.
- if sys.platform not in ('darwin',):
+ if gyp_vars_dict.get('OS') != 'ios':
args.append('--no-circular-check')
# We explicitly don't support the make gyp generator (crbug.com/348686). Be
@@ -285,9 +287,6 @@
if syntax_check and int(syntax_check):
args.append('--check')
- supplemental_includes = GetSupplementalFiles()
- gyp_vars_dict = GetGypVars(supplemental_includes)
-
# TODO(dmikurube): Remove these checks and messages after a while.
if ('linux_use_tcmalloc' in gyp_vars_dict or
'android_use_tcmalloc' in gyp_vars_dict):
diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh
index 6473794..2a2d50b 100755
--- a/build/install-build-deps.sh
+++ b/build/install-build-deps.sh
@@ -73,11 +73,11 @@
fi
lsb_release=$(lsb_release --codename --short)
-ubuntu_codenames="(precise|trusty|utopic)"
+ubuntu_codenames="(precise|trusty|utopic|vivid)"
if [ 0 -eq "${do_unsupported-0}" ] && [ 0 -eq "${do_quick_check-0}" ] ; then
if [[ ! $lsb_release =~ $ubuntu_codenames ]]; then
- echo "ERROR: Only Ubuntu 12.04 (precise), 14.04 (trusty) and " \
- "14.10 (utopic) are currently supported" >&2
+ echo "ERROR: Only Ubuntu 12.04 (precise), 14.04 (trusty), " \
+ "14.10 (utopic) and 15.04 (vivid) are currently supported" >&2
exit 1
fi
diff --git a/build/ios/grit_whitelist.txt b/build/ios/grit_whitelist.txt
index 18239b7..e25efbc 100644
--- a/build/ios/grit_whitelist.txt
+++ b/build/ios/grit_whitelist.txt
@@ -100,6 +100,7 @@
IDR_TOOLBAR_SHADOW_FULL_BLEED
IDR_TRANSLATE_JS
IDR_UBER_UTILS_JS
+IDR_WEBUI_CSS_TEXT_DEFAULTS
IDR_WEBUI_I18N_TEMPLATE_JS
IDR_WEBUI_I18N_TEMPLATE_POLYMER_JS
IDR_WEBUI_JSTEMPLATE_JS
diff --git a/build/isolate.gypi b/build/isolate.gypi
index 7b050e2..10033da 100644
--- a/build/isolate.gypi
+++ b/build/isolate.gypi
@@ -88,6 +88,7 @@
# once support for user-defined config variables is added.
'--config-variable',
'internal_gles2_conform_tests=<(internal_gles2_conform_tests)',
+ '--config-variable', 'kasko=<(kasko)',
'--config-variable', 'libpeer_target_type=<(libpeer_target_type)',
'--config-variable', 'lsan=<(lsan)',
'--config-variable', 'msan=<(msan)',
diff --git a/build/json_schema_api.gni b/build/json_schema_api.gni
index 68a9fdd..aa6365b 100644
--- a/build/json_schema_api.gni
+++ b/build/json_schema_api.gni
@@ -46,7 +46,10 @@
# If any deps are specified they will be inherited by the static library
# target.
#
-# The static library target also inherits the visibility and output_name
+# generate_static_library [optional, defaults to false]
+# Produces a static library instead of a source_set.
+#
+# The generated library target also inherits the visibility and output_name
# of its invoker.
template("json_schema_api") {
@@ -75,7 +78,6 @@
visibility = target_visibility
}
- sources = invoker.sources
root_namespace = invoker.root_namespace
compiler_root = "//tools/json_schema_compiler"
@@ -97,6 +99,7 @@
schema_generator_name = target_name + "_schema_generator"
action_foreach(schema_generator_name) {
script = compiler_script
+ sources = invoker.sources
inputs = compiler_sources
outputs = [
"$target_gen_dir/{{source_name_part}}.cc",
@@ -127,7 +130,7 @@
bundle_generator_schema_name = target_name + "_bundle_generator_schema"
action(bundle_generator_schema_name) {
script = compiler_script
- inputs = compiler_sources + sources + uncompiled_sources
+ inputs = compiler_sources + invoker.sources + uncompiled_sources
outputs = [
"$target_gen_dir/generated_schemas.cc",
"$target_gen_dir/generated_schemas.h",
@@ -138,7 +141,7 @@
"--namespace=$root_namespace",
"--generator=cpp-bundle-schema",
"--include-rules=$schema_include_rules",
- ] + rebase_path(sources, root_build_dir) +
+ ] + rebase_path(invoker.sources, root_build_dir) +
rebase_path(uncompiled_sources, root_build_dir)
}
}
@@ -157,7 +160,7 @@
target_name + "_bundle_generator_registration"
action(bundle_generator_registration_name) {
script = compiler_script
- inputs = compiler_sources + sources + uncompiled_sources
+ inputs = compiler_sources + invoker.sources + uncompiled_sources
outputs = [
"$root_gen_dir/$impl_dir/generated_api_registration.cc",
"$root_gen_dir/$impl_dir/generated_api_registration.h",
@@ -169,43 +172,69 @@
"--generator=cpp-bundle-registration",
"--impl-dir=" + rebase_path(impl_dir, "//"),
"--include-rules=$schema_include_rules",
- ] + rebase_path(sources, root_build_dir) +
+ ] + rebase_path(invoker.sources, root_build_dir) +
rebase_path(uncompiled_sources, root_build_dir)
}
}
- source_set(target_name) {
- sources = []
- deps = []
- public_deps = []
+ # Compute the contents of the library/source set.
+ lib_sources = invoker.sources
+ lib_deps = []
+ lib_public_deps = []
+ lib_extra_configs = []
- if (schemas) {
- sources += get_target_outputs(":$schema_generator_name")
- public_deps += [ ":$schema_generator_name" ]
- deps += [ "//tools/json_schema_compiler:generated_api_util" ]
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
- }
+ if (schemas) {
+ lib_sources += get_target_outputs(":$schema_generator_name")
+ lib_public_deps += [ ":$schema_generator_name" ]
+ lib_deps += [ "//tools/json_schema_compiler:generated_api_util" ]
+ lib_extra_configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+ }
- if (bundle) {
- sources += get_target_outputs(":$bundle_generator_schema_name")
- deps += [ ":$bundle_generator_schema_name" ]
- }
+ if (bundle) {
+ lib_sources += get_target_outputs(":$bundle_generator_schema_name")
+ lib_deps += [ ":$bundle_generator_schema_name" ]
+ }
- if (bundle_registration) {
- sources += get_target_outputs(":$bundle_generator_registration_name")
- deps += [ ":$bundle_generator_registration_name" ]
- }
+ if (bundle_registration) {
+ lib_sources += get_target_outputs(":$bundle_generator_registration_name")
+ lib_deps += [ ":$bundle_generator_registration_name" ]
+ }
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- public_configs = [ ":$generated_config_name" ]
+ if (defined(invoker.deps)) {
+ lib_deps += invoker.deps
+ }
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
+ # Generate either a static library or a source set.
+ if (defined(invoker.generate_static_library) &&
+ invoker.generate_static_library) {
+ static_library(target_name) {
+ sources = lib_sources
+ deps = lib_deps
+ public_deps = lib_public_deps
+ configs += lib_extra_configs
+ public_configs = [ ":$generated_config_name" ]
+
+ if (defined(invoker.visibility)) {
+ visibility = invoker.visibility
+ }
+ if (defined(invoker.output_name)) {
+ output_name = invoker.output_name
+ }
}
- if (defined(invoker.output_name)) {
- output_name = invoker.output_name
+ } else {
+ source_set(target_name) {
+ sources = lib_sources
+ deps = lib_deps
+ public_deps = lib_public_deps
+ configs += lib_extra_configs
+ public_configs = [ ":$generated_config_name" ]
+
+ if (defined(invoker.visibility)) {
+ visibility = invoker.visibility
+ }
+ if (defined(invoker.output_name)) {
+ output_name = invoker.output_name
+ }
}
}
}
diff --git a/build/sanitizers/lsan_suppressions.cc b/build/sanitizers/lsan_suppressions.cc
index a076ba0..f9aae3e 100644
--- a/build/sanitizers/lsan_suppressions.cc
+++ b/build/sanitizers/lsan_suppressions.cc
@@ -66,6 +66,9 @@
"leak:gin/object_template_builder.h\n"
"leak:gin::internal::Dispatcher\n"
"leak:blink::LocalDOMWindow::getComputedStyle\n"
+// This should really be RemoteDOMWindow::create, but symbolization is
+// weird in release builds. https://crbug.com/484760
+"leak:blink::RemoteFrame::create\n"
// http://crbug.com/356785
"leak:content::RenderViewImplTest_DecideNavigationPolicyForWebUI_Test::TestBody\n"
diff --git a/build/sanitizers/tsan_suppressions.cc b/build/sanitizers/tsan_suppressions.cc
index 352b41f..e053a16 100644
--- a/build/sanitizers/tsan_suppressions.cc
+++ b/build/sanitizers/tsan_suppressions.cc
@@ -157,6 +157,9 @@
"race:PrepareTextureMailbox\n"
"race:cc::LayerTreeHost::PaintLayerContents\n"
+// http://crbug.com/476529
+"deadlock:cc::VideoLayerImpl::WillDraw\n"
+
// http://crbug.com/328826
"race:gLCDOrder\n"
"race:gLCDOrientation\n"
@@ -295,9 +298,6 @@
// https://crbug.com/430533
"race:TileTaskGraphRunner::Run\n"
-// https://crbug.com/437044
-"race:SkEventTracer\n"
-
// https://crbug.com/448203
"race:blink::RemoteFrame::detach\n"
diff --git a/build/secondary/tools/grit/grit_rule.gni b/build/secondary/tools/grit/grit_rule.gni
index 09a04c1..35bbed3 100644
--- a/build/secondary/tools/grit/grit_rule.gni
+++ b/build/secondary/tools/grit/grit_rule.gni
@@ -75,6 +75,7 @@
# # You can also put deps here if the grit source depends on generated
# # files.
# }
+import("//build/config/chrome_build.gni")
import("//build/config/crypto.gni")
import("//build/config/features.gni")
import("//build/config/ui.gni")