Merge from Chromium at DEPS revision 40.0.2214.27
This commit was generated by merge_to_master.py.
Change-Id: I06ac150d0c1fb3d00586f2e69a583e7c2f82ce93
diff --git a/android_webview/browser/aw_browser_context.cc b/android_webview/browser/aw_browser_context.cc
index c386ad5..ebe8b4b 100644
--- a/android_webview/browser/aw_browser_context.cc
+++ b/android_webview/browser/aw_browser_context.cc
@@ -11,7 +11,9 @@
#include "android_webview/browser/jni_dependency_factory.h"
#include "android_webview/browser/net/aw_url_request_context_getter.h"
#include "android_webview/browser/net/init_native_callback.h"
+#include "base/base_paths_android.h"
#include "base/bind.h"
+#include "base/path_service.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/pref_service_factory.h"
@@ -28,6 +30,7 @@
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "net/cookies/cookie_store.h"
+#include "net/proxy/proxy_config_service_android.h"
#include "net/proxy/proxy_service.h"
using base::FilePath;
@@ -43,13 +46,34 @@
void HandleReadError(PersistentPrefStore::PrefReadError error) {
}
+void DeleteDirRecursively(const base::FilePath& path) {
+ if (!base::DeleteFile(path, true)) {
+ // Deleting a non-existent file is considered successful, so this will
+ // trigger only in case of real errors.
+ LOG(WARNING) << "Failed to delete " << path.AsUTF8Unsafe();
+ }
+}
+
AwBrowserContext* g_browser_context = NULL;
+net::ProxyConfigService* CreateProxyConfigService() {
+ net::ProxyConfigServiceAndroid* config_service =
+ static_cast<net::ProxyConfigServiceAndroid*>(
+ net::ProxyService::CreateSystemProxyConfigService(
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
+ nullptr /* Ignored on Android */ ));
+ config_service->set_exclude_pac_url(true);
+ return config_service;
+}
+
} // namespace
// Data reduction proxy is disabled by default.
bool AwBrowserContext::data_reduction_proxy_enabled_ = false;
+// Delete the legacy cache dir (in the app data dir) in 10 seconds after init.
+int AwBrowserContext::legacy_cache_removal_delay_ms_ = 10000;
+
AwBrowserContext::AwBrowserContext(
const FilePath path,
JniDependencyFactory* native_factory)
@@ -102,6 +126,11 @@
proxy_settings->SetDataReductionProxyEnabled(data_reduction_proxy_enabled_);
}
+// static
+void AwBrowserContext::SetLegacyCacheRemovalDelayForTest(int delay_ms) {
+ legacy_cache_removal_delay_ms_ = delay_ms;
+}
+
void AwBrowserContext::PreMainMessageLoopRun() {
cookie_store_ = CreateCookieStore(this);
data_reduction_proxy_settings_.reset(
@@ -112,10 +141,7 @@
data_reduction_proxy_config_service(
new DataReductionProxyConfigService(
scoped_ptr<net::ProxyConfigService>(
- net::ProxyService::CreateSystemProxyConfigService(
- BrowserThread::GetMessageLoopProxyForThread(
- BrowserThread::IO),
- NULL /* Ignored on Android */)).Pass()));
+ CreateProxyConfigService()).Pass()));
if (data_reduction_proxy_settings_.get()) {
data_reduction_proxy_configurator_.reset(
new data_reduction_proxy::DataReductionProxyConfigTracker(
@@ -127,8 +153,24 @@
data_reduction_proxy_configurator_.get());
}
+ FilePath cache_path;
+ const FilePath fallback_cache_dir =
+ GetPath().Append(FILE_PATH_LITERAL("Cache"));
+ if (PathService::Get(base::DIR_CACHE, &cache_path)) {
+ cache_path = cache_path.Append(
+ FILE_PATH_LITERAL("org.chromium.android_webview"));
+ // Delay the legacy dir removal to not impact startup performance.
+ BrowserThread::PostDelayedTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&DeleteDirRecursively, fallback_cache_dir),
+ base::TimeDelta::FromMilliseconds(legacy_cache_removal_delay_ms_));
+ } else {
+ cache_path = fallback_cache_dir;
+ LOG(WARNING) << "Failed to get cache directory for Android WebView. "
+ << "Using app data directory as a fallback.";
+ }
url_request_context_getter_ =
- new AwURLRequestContextGetter(GetPath(),
+ new AwURLRequestContextGetter(cache_path,
cookie_store_.get(),
data_reduction_proxy_config_service.Pass());
diff --git a/android_webview/browser/aw_browser_context.h b/android_webview/browser/aw_browser_context.h
index 3f49765..66ac213 100644
--- a/android_webview/browser/aw_browser_context.h
+++ b/android_webview/browser/aw_browser_context.h
@@ -65,6 +65,7 @@
content::WebContents* web_contents);
static void SetDataReductionProxyEnabled(bool enabled);
+ static void SetLegacyCacheRemovalDelayForTest(int delay_ms);
// Maps to BrowserMainParts::PreMainMessageLoopRun.
void PreMainMessageLoopRun();
@@ -120,6 +121,10 @@
void CreateDataReductionProxyStatisticsIfNecessary();
static bool data_reduction_proxy_enabled_;
+ // Delay, in milliseconds, before removing the legacy cache dir.
+ // This is non-const for testing purposes.
+ static int legacy_cache_removal_delay_ms_;
+
// The file path where data for this context is persisted.
base::FilePath context_storage_path_;
diff --git a/android_webview/browser/net/aw_url_request_context_getter.cc b/android_webview/browser/net/aw_url_request_context_getter.cc
index 1c74bd0..b600a46 100644
--- a/android_webview/browser/net/aw_url_request_context_getter.cc
+++ b/android_webview/browser/net/aw_url_request_context_getter.cc
@@ -175,10 +175,10 @@
} // namespace
AwURLRequestContextGetter::AwURLRequestContextGetter(
- const base::FilePath& partition_path, net::CookieStore* cookie_store,
+ const base::FilePath& cache_path, net::CookieStore* cookie_store,
scoped_ptr<data_reduction_proxy::DataReductionProxyConfigService>
config_service)
- : partition_path_(partition_path),
+ : cache_path_(cache_path),
cookie_store_(cookie_store),
net_log_(new net::NetLog()) {
data_reduction_proxy_config_service_ = config_service.Pass();
@@ -200,14 +200,14 @@
#if !defined(DISABLE_FTP_SUPPORT)
builder.set_ftp_enabled(false); // Android WebView does not support ftp yet.
#endif
- if (data_reduction_proxy_config_service_.get()) {
- builder.set_proxy_config_service(
- data_reduction_proxy_config_service_.release());
- } else {
- builder.set_proxy_config_service(
- net::ProxyService::CreateSystemProxyConfigService(
- GetNetworkTaskRunner(), NULL /* Ignored on Android */ ));
- }
+ DCHECK(data_reduction_proxy_config_service_.get());
+ // Android provides a local HTTP proxy that handles all the proxying.
+ // Create the proxy without a resolver since we rely on this local HTTP proxy.
+ // TODO(sgurun) is this behavior guaranteed through SDK?
+ builder.set_proxy_service(
+ net::ProxyService::CreateWithoutProxyResolver(
+ data_reduction_proxy_config_service_.release(),
+ net_log_.get()));
builder.set_accept_language(net::HttpUtil::GenerateAcceptLanguageHeader(
AwContentBrowserClient::GetAcceptLangsImpl()));
builder.set_net_log(net_log_.get());
@@ -226,7 +226,7 @@
new net::HttpCache::DefaultBackend(
net::DISK_CACHE,
net::CACHE_BACKEND_SIMPLE,
- partition_path_.Append(FILE_PATH_LITERAL("Cache")),
+ cache_path_,
20 * 1024 * 1024, // 20M
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)));
diff --git a/android_webview/browser/net/aw_url_request_context_getter.h b/android_webview/browser/net/aw_url_request_context_getter.h
index 25cfaae..b8afdf8 100644
--- a/android_webview/browser/net/aw_url_request_context_getter.h
+++ b/android_webview/browser/net/aw_url_request_context_getter.h
@@ -35,7 +35,7 @@
class AwURLRequestContextGetter : public net::URLRequestContextGetter {
public:
AwURLRequestContextGetter(
- const base::FilePath& partition_path,
+ const base::FilePath& cache_path,
net::CookieStore* cookie_store,
scoped_ptr<data_reduction_proxy::DataReductionProxyConfigService>
config_service);
@@ -72,7 +72,7 @@
void InitializeURLRequestContext();
- const base::FilePath partition_path_;
+ const base::FilePath cache_path_;
scoped_refptr<net::CookieStore> cookie_store_;
scoped_ptr<net::NetLog> net_log_;
scoped_ptr<net::URLRequestContext> url_request_context_;
diff --git a/android_webview/browser/scoped_app_gl_state_restore.cc b/android_webview/browser/scoped_app_gl_state_restore.cc
index 43bd8aa..2fa1b11 100644
--- a/android_webview/browser/scoped_app_gl_state_restore.cc
+++ b/android_webview/browser/scoped_app_gl_state_restore.cc
@@ -294,6 +294,9 @@
glGetVertexAttribfv(
i, GL_CURRENT_VERTEX_ATTRIB, vertex_attrib_[i].current_vertex_attrib);
}
+
+ // Android 5.0.0 specific qualcomm workaround. See crbug.com/434570.
+ glBindRenderbufferEXT(GL_RENDERBUFFER, 0);
DCHECK(ClearGLErrors(false, NULL));
}
diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
index a38451d..f13ecac 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
@@ -20,7 +20,8 @@
* Wrapper for the steps needed to initialize the java and native sides of webview chromium.
*/
public abstract class AwBrowserProcess {
- private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "webview";
+ public static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "webview";
+
private static final String TAG = "AwBrowserProcess";
/**
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index 60b976e..7f0dc03 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -276,6 +276,8 @@
private final InternalAccessDelegate mInitialInternalAccessAdapter;
private final AwViewMethods mInitialAwViewMethods;
private FullScreenView mFullScreenView;
+ /** Whether the initial container view was focused when we entered fullscreen */
+ private boolean mWasInitialContainerViewFocused;
private FullScreenTransitionsState(ViewGroup initialContainerView,
InternalAccessDelegate initialInternalAccessAdapter,
@@ -285,8 +287,14 @@
mInitialAwViewMethods = initialAwViewMethods;
}
- private void enterFullScreen(FullScreenView fullScreenView) {
+ private void enterFullScreen(FullScreenView fullScreenView,
+ boolean wasInitialContainerViewFocused) {
mFullScreenView = fullScreenView;
+ mWasInitialContainerViewFocused = wasInitialContainerViewFocused;
+ }
+
+ private boolean wasInitialContainerViewFocused() {
+ return mWasInitialContainerViewFocused;
}
private void exitFullScreen() {
@@ -663,8 +671,14 @@
// In fullscreen mode FullScreenView owns the AwViewMethodsImpl and AwContents
// a NullAwViewMethods.
- FullScreenView fullScreenView = new FullScreenView(mContext, mAwViewMethods);
- mFullScreenTransitionsState.enterFullScreen(fullScreenView);
+ FullScreenView fullScreenView = new FullScreenView(mContext, mAwViewMethods, this);
+ fullScreenView.setFocusable(true);
+ fullScreenView.setFocusableInTouchMode(true);
+ boolean wasInitialContainerViewFocused = mContainerView.isFocused();
+ if (wasInitialContainerViewFocused) {
+ fullScreenView.requestFocus();
+ }
+ mFullScreenTransitionsState.enterFullScreen(fullScreenView, wasInitialContainerViewFocused);
mAwViewMethods = new NullAwViewMethods(this, mInternalAccessAdapter, mContainerView);
mContainerView.removeOnLayoutChangeListener(mLayoutChangeListener);
fullScreenView.addOnLayoutChangeListener(mLayoutChangeListener);
@@ -715,6 +729,10 @@
setInternalAccessAdapter(mFullScreenTransitionsState.getInitialInternalAccessDelegate());
setContainerView(initialContainerView);
+ // Return focus to the WebView.
+ if (mFullScreenTransitionsState.wasInitialContainerViewFocused()) {
+ mContainerView.requestFocus();
+ }
mFullScreenTransitionsState.exitFullScreen();
}
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
index 7800965..dab4274 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
@@ -81,6 +81,10 @@
nativeRegisterCrashHandler(version);
}
+ public static void setLegacyCacheRemovalDelayForTest(long timeoutMs) {
+ nativeSetLegacyCacheRemovalDelayForTest(timeoutMs);
+ }
+
//--------------------------------------------------------------------------------------------
// Native methods
//--------------------------------------------------------------------------------------------
@@ -90,4 +94,5 @@
private static native String nativeGetUnreachableWebDataUrl();
private static native void nativeSetRecordFullDocument(boolean recordFullDocument);
private static native void nativeRegisterCrashHandler(String version);
+ private static native void nativeSetLegacyCacheRemovalDelayForTest(long timeoutMs);
}
diff --git a/android_webview/java/src/org/chromium/android_webview/FullScreenView.java b/android_webview/java/src/org/chromium/android_webview/FullScreenView.java
index 3dd0f3d..1eb96a4 100644
--- a/android_webview/java/src/org/chromium/android_webview/FullScreenView.java
+++ b/android_webview/java/src/org/chromium/android_webview/FullScreenView.java
@@ -23,11 +23,14 @@
public class FullScreenView extends FrameLayout {
private AwViewMethods mAwViewMethods;
+ private final AwContents mAwContents;
private InternalAccessAdapter mInternalAccessAdapter;
- public FullScreenView(Context context, AwViewMethods awViewMethods) {
+ public FullScreenView(Context context, AwViewMethods awViewMethods,
+ AwContents awContents) {
super(context);
setAwViewMethods(awViewMethods);
+ mAwContents = awContents;
mInternalAccessAdapter = new InternalAccessAdapter();
}
@@ -73,6 +76,12 @@
@Override
public boolean dispatchKeyEvent(final KeyEvent event) {
+ if (event.getKeyCode() == KeyEvent.KEYCODE_BACK
+ && event.getAction() == KeyEvent.ACTION_UP
+ && mAwContents.isFullScreen()) {
+ mAwContents.requestExitFullscreen();
+ return true;
+ }
return mAwViewMethods.dispatchKeyEvent(event);
}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
index 5881f20..da731d2 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
@@ -5,6 +5,7 @@
package org.chromium.android_webview.test;
import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -130,6 +131,37 @@
@MediumTest
@Feature({"AndroidWebView"})
+ public void testOnShowAndHideCustomViewWithBackKey_video() throws Throwable {
+ doTestOnShowAndHideCustomViewWithBackKey(VIDEO_TEST_URL);
+ }
+
+ @MediumTest
+ @Feature({"AndroidWebView"})
+ public void testOnShowAndHideCustomViewWithBackKey_videoInsideDiv()
+ throws Throwable {
+ doTestOnShowAndHideCustomViewWithBackKey(VIDEO_INSIDE_DIV_TEST_URL);
+ }
+
+ public void doTestOnShowAndHideCustomViewWithBackKey(String videoTestUrl) throws Throwable {
+ doOnShowCustomViewTest(videoTestUrl);
+
+ // The key event should not be propagated to mTestContainerView (the original container
+ // view).
+ mTestContainerView.setOnKeyListener(new View.OnKeyListener() {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ fail("mTestContainerView received key event");
+ return false;
+ }
+ });
+
+ sendKeys(KeyEvent.KEYCODE_BACK);
+ mContentsClient.waitForCustomViewHidden();
+ assertFalse(mContentsClient.wasOnUnhandledKeyUpEventCalled());
+ }
+
+ @MediumTest
+ @Feature({"AndroidWebView"})
public void testOnShowCustomViewAndPlayWithHtmlControl_video() throws Throwable {
doTestOnShowCustomViewAndPlayWithHtmlControl(VIDEO_TEST_URL);
}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
index 2e2c500..6bcbd44 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
@@ -49,16 +49,20 @@
protected void setUp() throws Exception {
super.setUp();
if (needsBrowserProcessStarted()) {
- final Context context = getActivity();
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- AwBrowserProcess.start(context);
- }
- });
+ startBrowserProcess();
}
}
+ protected void startBrowserProcess() throws Exception {
+ final Context context = getActivity();
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ AwBrowserProcess.start(context);
+ }
+ });
+ }
+
/* Override this to return false if the test doesn't want the browser startup sequence to
* be run automatically.
*/
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/FullScreenVideoTestAwContentsClient.java b/android_webview/javatests/src/org/chromium/android_webview/test/FullScreenVideoTestAwContentsClient.java
index 2143c46..6d1c06b 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/FullScreenVideoTestAwContentsClient.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/FullScreenVideoTestAwContentsClient.java
@@ -6,6 +6,7 @@
import android.app.Activity;
import android.view.Gravity;
+import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
@@ -26,6 +27,7 @@
public static final long WAITING_SECONDS = scaleTimeout(20);
private CallbackHelper mOnShowCustomViewCallbackHelper = new CallbackHelper();
private CallbackHelper mOnHideCustomViewCallbackHelper = new CallbackHelper();
+ private CallbackHelper mOnUnhandledKeyUpEventCallbackHelper = new CallbackHelper();
private final Activity mActivity;
private final boolean mAllowHardwareAcceleration;
@@ -69,6 +71,17 @@
return mExitCallback;
}
+ @Override
+ public void onUnhandledKeyEvent(KeyEvent event) {
+ if (event.getAction() == KeyEvent.ACTION_UP) {
+ mOnUnhandledKeyUpEventCallbackHelper.notifyCalled();
+ }
+ }
+
+ public boolean wasOnUnhandledKeyUpEventCalled() {
+ return mOnUnhandledKeyUpEventCallbackHelper.getCallCount() > 0;
+ }
+
public View getCustomView() {
return mCustomView;
}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/HttpCacheTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/HttpCacheTest.java
new file mode 100644
index 0000000..8b28508
--- /dev/null
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/HttpCacheTest.java
@@ -0,0 +1,112 @@
+// Copyright 2014 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.
+
+package org.chromium.android_webview.test;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.android_webview.AwBrowserProcess;
+import org.chromium.android_webview.AwContents;
+import org.chromium.android_webview.AwContentsStatics;
+import org.chromium.base.PathUtils;
+import org.chromium.base.test.util.Feature;
+import org.chromium.net.test.util.TestWebServer;
+
+import java.io.File;
+
+/**
+ * Test suite for the HTTP cache.
+ */
+public class HttpCacheTest extends AwTestBase {
+
+ @Override
+ protected boolean needsBrowserProcessStarted() {
+ return false;
+ }
+
+ @SmallTest
+ @Feature({"AndroidWebView"})
+ public void testHttpCacheIsInsideCacheDir() throws Exception {
+ File webViewCacheDir = new File(
+ getInstrumentation().getTargetContext().getCacheDir().getPath(),
+ "org.chromium.android_webview");
+ deleteDirectory(webViewCacheDir);
+
+ startBrowserProcess();
+ final TestAwContentsClient contentClient = new TestAwContentsClient();
+ final AwTestContainerView testContainerView =
+ createAwTestContainerViewOnMainSync(contentClient);
+ final AwContents awContents = testContainerView.getAwContents();
+
+ TestWebServer httpServer = null;
+ try {
+ httpServer = TestWebServer.start();
+ final String pageUrl = "/page.html";
+ final String pageHtml = "<body>Hello, World!</body>";
+ final String fullPageUrl = httpServer.setResponse(pageUrl, pageHtml, null);
+ loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), fullPageUrl);
+ assertEquals(1, httpServer.getRequestCount(pageUrl));
+ } finally {
+ if (httpServer != null) {
+ httpServer.shutdown();
+ }
+ }
+
+ assertTrue(webViewCacheDir.isDirectory());
+ assertTrue(webViewCacheDir.list().length > 0);
+ }
+
+ private void deleteDirectory(File dir) throws Exception {
+ if (!dir.exists())
+ return;
+ assertTrue(dir.isDirectory());
+ Process rmrf = Runtime.getRuntime().exec("rm -rf " + dir.getAbsolutePath());
+ rmrf.waitFor();
+ assertFalse(dir.exists());
+ }
+
+ @SmallTest
+ @Feature({"AndroidWebView"})
+ public void testLegacyHttpCacheDirIsRemovedOnStartup() throws Exception {
+ PathUtils.setPrivateDataDirectorySuffix(AwBrowserProcess.PRIVATE_DATA_DIRECTORY_SUFFIX);
+ File webViewLegacyCacheDir = new File(
+ PathUtils.getDataDirectory(getInstrumentation().getTargetContext()), "Cache");
+ if (!webViewLegacyCacheDir.isDirectory()) {
+ assertTrue(webViewLegacyCacheDir.mkdir());
+ assertTrue(webViewLegacyCacheDir.isDirectory());
+ }
+ File dummyCacheFile = File.createTempFile("test", null, webViewLegacyCacheDir);
+ assertTrue(dummyCacheFile.exists());
+
+ // Set up JNI bindings.
+ AwBrowserProcess.loadLibrary();
+ // No delay before removing the legacy cache files.
+ AwContentsStatics.setLegacyCacheRemovalDelayForTest(0);
+
+ startBrowserProcess();
+ final TestAwContentsClient contentClient = new TestAwContentsClient();
+ final AwTestContainerView testContainerView =
+ createAwTestContainerViewOnMainSync(contentClient);
+ final AwContents awContents = testContainerView.getAwContents();
+
+ // Do some page loading to make sure that FILE thread has processed
+ // our directory removal task.
+ TestWebServer httpServer = null;
+ try {
+ httpServer = TestWebServer.start();
+ final String pageUrl = "/page.html";
+ final String pageHtml = "<body>Hello, World!</body>";
+ final String fullPageUrl = httpServer.setResponse(pageUrl, pageHtml, null);
+ loadUrlSync(awContents, contentClient.getOnPageFinishedHelper(), fullPageUrl);
+ assertEquals(1, httpServer.getRequestCount(pageUrl));
+ } finally {
+ if (httpServer != null) {
+ httpServer.shutdown();
+ }
+ }
+
+ assertFalse(webViewLegacyCacheDir.exists());
+ assertFalse(dummyCacheFile.exists());
+ }
+}
diff --git a/android_webview/native/aw_contents_statics.cc b/android_webview/native/aw_contents_statics.cc
index ee61de6..e09fcb8 100644
--- a/android_webview/native/aw_contents_statics.cc
+++ b/android_webview/native/aw_contents_statics.cc
@@ -96,6 +96,11 @@
ConvertJavaStringToUTF8(env, version));
}
+// static
+void SetLegacyCacheRemovalDelayForTest(JNIEnv*, jclass, jlong delay_ms) {
+ AwBrowserContext::SetLegacyCacheRemovalDelayForTest(delay_ms);
+}
+
bool RegisterAwContentsStatics(JNIEnv* env) {
return RegisterNativesImpl(env);
}
diff --git a/base/android/java/src/org/chromium/base/SystemMessageHandler.java b/base/android/java/src/org/chromium/base/SystemMessageHandler.java
index 10f8d55..fd3dc5a 100644
--- a/base/android/java/src/org/chromium/base/SystemMessageHandler.java
+++ b/base/android/java/src/org/chromium/base/SystemMessageHandler.java
@@ -5,12 +5,9 @@
package org.chromium.base;
import android.os.Handler;
-import android.os.Looper;
import android.os.Message;
-import android.os.MessageQueue;
import android.util.Log;
-import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -25,23 +22,31 @@
private long mMessagePumpDelegateNative = 0;
private long mDelayedScheduledTimeTicks = 0;
- // The following members are used to detect and trace the presence of sync
- // barriers in Android's MessageQueue. Note that this detection is
- // experimental, temporary and intended only for diagnostic purposes.
- private MessageQueue mMessageQueue;
- private Field mMessageQueueMessageField;
- private Field mMessageTargetField;
- private boolean mQueueHasSyncBarrier;
- private long mSyncBarrierTraceId;
+ // Reflected API for marking a message as asynchronous. This is a workaround
+ // to provide fair Chromium task dispatch when served by the Android UI
+ // thread's Looper, avoiding stalls when the Looper has a sync barrier.
+ // Note: Use of this API is experimental and likely to evolve in the future.
+ private Method mMessageMethodSetAsynchronous;
private SystemMessageHandler(long messagePumpDelegateNative) {
mMessagePumpDelegateNative = messagePumpDelegateNative;
- tryEnableSyncBarrierDetection();
+
+ try {
+ Class<?> messageClass = Class.forName("android.os.Message");
+ mMessageMethodSetAsynchronous = messageClass.getMethod(
+ "setAsynchronous", new Class[]{boolean.class});
+ } catch (ClassNotFoundException e) {
+ Log.e(TAG, "Failed to find android.os.Message class:" + e);
+ } catch (NoSuchMethodException e) {
+ Log.e(TAG, "Failed to load Message.setAsynchronous method:" + e);
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Exception while loading Message.setAsynchronous method: " + e);
+ }
+
}
@Override
public void handleMessage(Message msg) {
- updateWhetherQueueHasBlockingSyncBarrier();
if (msg.what == DELAYED_SCHEDULED_WORK) {
mDelayedScheduledTimeTicks = 0;
}
@@ -51,9 +56,7 @@
@SuppressWarnings("unused")
@CalledByNative
private void scheduleWork() {
- updateWhetherQueueHasBlockingSyncBarrier();
- if (mQueueHasSyncBarrier) TraceEvent.instant("SystemMessageHandler:immediateWorkBlocked");
- sendEmptyMessage(SCHEDULED_WORK);
+ sendMessage(obtainAsyncMessage(SCHEDULED_WORK));
}
@SuppressWarnings("unused")
@@ -63,97 +66,39 @@
removeMessages(DELAYED_SCHEDULED_WORK);
}
mDelayedScheduledTimeTicks = delayedTimeTicks;
- updateWhetherQueueHasBlockingSyncBarrier();
- if (mQueueHasSyncBarrier) TraceEvent.instant("SystemMessageHandler:delayedWorkBlocked");
- sendEmptyMessageDelayed(DELAYED_SCHEDULED_WORK, millis);
+ sendMessageDelayed(obtainAsyncMessage(DELAYED_SCHEDULED_WORK), millis);
}
@SuppressWarnings("unused")
@CalledByNative
private void removeAllPendingMessages() {
- updateWhetherQueueHasBlockingSyncBarrier();
removeMessages(SCHEDULED_WORK);
removeMessages(DELAYED_SCHEDULED_WORK);
}
- private void updateWhetherQueueHasBlockingSyncBarrier() {
- if (mMessageQueue == null) return;
- // As barrier detection is only used for tracing, early out when tracing
- // is disabled to avoid any potential performance penalties.
- if (!TraceEvent.enabled()) {
- mQueueHasSyncBarrier = false;
- return;
+ private Message obtainAsyncMessage(int what) {
+ Message msg = Message.obtain();
+ msg.what = what;
+ if (mMessageMethodSetAsynchronous != null) {
+ // If invocation fails, assume this is indicative of future
+ // failures, and avoid log spam by nulling the reflected method.
+ try {
+ mMessageMethodSetAsynchronous.invoke(msg, true);
+ } catch (IllegalAccessException e) {
+ Log.e(TAG, "Illegal access to asynchronous message creation, disabling.");
+ mMessageMethodSetAsynchronous = null;
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Illegal argument for asynchronous message creation, disabling.");
+ mMessageMethodSetAsynchronous = null;
+ } catch (InvocationTargetException e) {
+ Log.e(TAG, "Invocation exception during asynchronous message creation, disabling.");
+ mMessageMethodSetAsynchronous = null;
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Runtime exception during asynchronous message creation, disabling.");
+ mMessageMethodSetAsynchronous = null;
+ }
}
- Message queueHead = (Message) getField(mMessageQueue, mMessageQueueMessageField);
- setqueueHasSyncBarrier(isSyncBarrierMessage(queueHead));
- }
-
- private boolean isSyncBarrierMessage(Message message) {
- if (message == null) return false;
- // Sync barrier messages have null targets.
- return getField(message, mMessageTargetField) == null;
- }
-
- private void tryEnableSyncBarrierDetection() {
- assert mMessageQueue == null;
-
- boolean success = false;
- try {
- Method getQueueMethod = Looper.class.getMethod("getQueue", new Class[]{});
- mMessageQueue = (MessageQueue) getQueueMethod.invoke(getLooper());
-
- mMessageQueueMessageField = mMessageQueue.getClass().getDeclaredField("mMessages");
- mMessageQueueMessageField.setAccessible(true);
-
- mMessageTargetField = Message.class.getDeclaredField("target");
- mMessageTargetField.setAccessible(true);
-
- mSyncBarrierTraceId = hashCode();
-
- success = true;
- } catch (NoSuchMethodException e) {
- Log.e(TAG, "Failed to load method: " + e);
- } catch (NoSuchFieldException e) {
- Log.e(TAG, "Failed to load field: " + e);
- } catch (InvocationTargetException e) {
- Log.e(TAG, "Failed invocation: " + e);
- } catch (IllegalAccessException e) {
- Log.e(TAG, "Illegal access to reflected invocation: " + e);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Illegal argument to reflected invocation: " + e);
- } catch (RuntimeException e) {
- Log.e(TAG, e.toString());
- } finally {
- if (!success) disableSyncBarrierDetection();
- }
- }
-
- private void disableSyncBarrierDetection() {
- Log.e(TAG, "Unexpected error with sync barrier detection, disabling.");
- mMessageQueue = null;
- mMessageQueueMessageField = null;
- mMessageTargetField = null;
- setqueueHasSyncBarrier(false);
- }
-
- private void setqueueHasSyncBarrier(boolean queueHasSyncBarrier) {
- if (queueHasSyncBarrier == mQueueHasSyncBarrier) return;
- mQueueHasSyncBarrier = queueHasSyncBarrier;
- if (mQueueHasSyncBarrier) {
- TraceEvent.startAsync("SyncBarrier", mSyncBarrierTraceId);
- } else {
- TraceEvent.finishAsync("SyncBarrier", mSyncBarrierTraceId);
- }
- }
-
- private Object getField(Object object, Field field) {
- try {
- return field.get(object);
- } catch (IllegalAccessException e) {
- Log.e(TAG, "Failed field access: " + e);
- disableSyncBarrierDetection();
- }
- return null;
+ return msg;
}
@CalledByNative
diff --git a/base/files/file_unittest.cc b/base/files/file_unittest.cc
index 9f57974..3bc2db6 100644
--- a/base/files/file_unittest.cc
+++ b/base/files/file_unittest.cc
@@ -476,7 +476,7 @@
EXPECT_NE(file.file_.file_memory_checksum_,
implicit_cast<unsigned int>(file.GetPlatformFile()));
file.file_.file_memory_checksum_ = file.GetPlatformFile();
- EXPECT_DEATH(file.IsValid(), "corrupted fd memory");
+ EXPECT_DEATH(file.IsValid(), "");
file.file_.UpdateChecksum(); // Do not crash on File::~File().
}
@@ -485,7 +485,7 @@
// Test that changing the file descriptor value is detected.
base::File file;
file.file_.file_.reset(17);
- EXPECT_DEATH(file.IsValid(), "corrupted fd memory");
+ EXPECT_DEATH(file.IsValid(), "");
// Do not crash on File::~File().
ignore_result(file.file_.file_.release());
@@ -496,7 +496,7 @@
// Test that GetPlatformFile() checks for corruption.
base::File file;
file.file_.file_memory_checksum_ = file.GetPlatformFile();
- EXPECT_DEATH(file.GetPlatformFile(), "corrupted fd memory");
+ EXPECT_DEATH(file.GetPlatformFile(), "");
file.file_.UpdateChecksum(); // Do not crash on File::~File().
}
@@ -505,7 +505,7 @@
// Test that the base::File destructor checks for corruption.
scoped_ptr<base::File> file(new File());
file->file_.file_memory_checksum_ = file->GetPlatformFile();
- EXPECT_DEATH(file.reset(), "corrupted fd memory");
+ EXPECT_DEATH(file.reset(), "");
// Do not crash on this thread's destructor call.
file->file_.UpdateChecksum();
@@ -515,7 +515,7 @@
// Test that the base::File constructor checks for corruption.
base::File file;
file.file_.file_memory_checksum_ = file.GetPlatformFile();
- EXPECT_DEATH(File f(file.Pass()), "corrupted fd memory");
+ EXPECT_DEATH(File f(file.Pass()), "");
file.file_.UpdateChecksum(); // Do not crash on File::~File().
}
@@ -525,10 +525,10 @@
base::File file;
file.file_.file_.reset(17); // A fake open FD value.
- EXPECT_DEATH(file.Seek(File::FROM_BEGIN, 0), "corrupted fd memory");
- EXPECT_DEATH(file.Read(0, NULL, 0), "corrupted fd memory");
- EXPECT_DEATH(file.ReadAtCurrentPos(NULL, 0), "corrupted fd memory");
- EXPECT_DEATH(file.Write(0, NULL, 0), "corrupted fd memory");
+ EXPECT_DEATH(file.Seek(File::FROM_BEGIN, 0), "");
+ EXPECT_DEATH(file.Read(0, NULL, 0), "");
+ EXPECT_DEATH(file.ReadAtCurrentPos(NULL, 0), "");
+ EXPECT_DEATH(file.Write(0, NULL, 0), "");
ignore_result(file.file_.file_.release());
file.file_.UpdateChecksum();
diff --git a/build/config/features.gni b/build/config/features.gni
index a395b40..5060d5e 100644
--- a/build/config/features.gni
+++ b/build/config/features.gni
@@ -77,9 +77,8 @@
use_seccomp_bpf = (is_linux || is_android) &&
(cpu_arch == "x86" || cpu_arch == "x64" || cpu_arch == "arm")
-# Enable notifications everywhere except Android/iOS.
-# Android is http://crbug.com/115320
-enable_notifications = !is_android && !is_ios
+# Enable notifications everywhere except iOS.
+enable_notifications = !is_ios
# TODO(brettw) this should be moved to net and only dependents get this define.
disable_ftp_support = is_ios
diff --git a/build/util/LASTCHANGE b/build/util/LASTCHANGE
index e136404..be6e68b 100644
--- a/build/util/LASTCHANGE
+++ b/build/util/LASTCHANGE
@@ -1 +1 @@
-LASTCHANGE=3e349d1753f4
+LASTCHANGE=472e9e85cdec
diff --git a/build/util/LASTCHANGE.blink b/build/util/LASTCHANGE.blink
index db6b90c..730df68 100644
--- a/build/util/LASTCHANGE.blink
+++ b/build/util/LASTCHANGE.blink
@@ -1 +1 @@
-LASTCHANGE=185475
+LASTCHANGE=186261
diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc
index 1ebb1cf..ec843a5 100644
--- a/cc/resources/picture_pile.cc
+++ b/cc/resources/picture_pile.cc
@@ -188,21 +188,30 @@
gfx::Rect interest_rect_over_tiles =
tiling_.ExpandRectToTileBounds(interest_rect);
+ gfx::Size min_tiling_size(
+ std::min(tiling_size().width(), old_tiling_size.width()),
+ std::min(tiling_size().height(), old_tiling_size.height()));
+ gfx::Size max_tiling_size(
+ std::max(tiling_size().width(), old_tiling_size.width()),
+ std::max(tiling_size().height(), old_tiling_size.height()));
+
if (old_tiling_size != layer_size) {
has_any_recordings_ = false;
- // Drop recordings that are outside the new layer bounds or that changed
- // size.
+ // Drop recordings that are outside the new or old layer bounds or that
+ // changed size. Newly exposed areas are considered invalidated.
+ // Previously exposed areas that are now outside of bounds also need to
+ // be invalidated, as they may become part of raster when scale < 1.
std::vector<PictureMapKey> to_erase;
int min_toss_x = tiling_.num_tiles_x();
- if (tiling_size().width() > old_tiling_size.width()) {
+ if (max_tiling_size.width() > min_tiling_size.width()) {
min_toss_x =
- tiling_.FirstBorderTileXIndexFromSrcCoord(old_tiling_size.width());
+ tiling_.FirstBorderTileXIndexFromSrcCoord(min_tiling_size.width());
}
int min_toss_y = tiling_.num_tiles_y();
- if (tiling_size().height() > old_tiling_size.height()) {
+ if (max_tiling_size.height() > min_tiling_size.height()) {
min_toss_y =
- tiling_.FirstBorderTileYIndexFromSrcCoord(old_tiling_size.height());
+ tiling_.FirstBorderTileYIndexFromSrcCoord(min_tiling_size.height());
}
for (PictureMap::const_iterator it = picture_map_.begin();
it != picture_map_.end();
@@ -221,20 +230,22 @@
// If a recording is dropped and not re-recorded below, invalidate that
// full recording to cause any raster tiles that would use it to be
// dropped.
- // If the recording will be replaced below, just invalidate newly exposed
- // areas to force raster tiles that include the old recording to know
- // there is new recording to display.
- gfx::Rect old_tiling_rect_over_tiles =
- tiling_.ExpandRectToTileBounds(gfx::Rect(old_tiling_size));
+ // If the recording will be replaced below, invalidate newly exposed
+ // areas and previously exposed areas to force raster tiles that include the
+ // old recording to know there is new recording to display.
+ gfx::Rect min_tiling_rect_over_tiles =
+ tiling_.ExpandRectToTileBounds(gfx::Rect(min_tiling_size));
if (min_toss_x < tiling_.num_tiles_x()) {
// The bounds which we want to invalidate are the tiles along the old
- // edge of the pile. We'll call this bounding box the OLD EDGE RECT.
+ // edge of the pile when expanding, or the new edge of the pile when
+ // shrinking. In either case, it's the difference of the two, so we'll
+ // call this bounding box the DELTA EDGE RECT.
//
- // In the picture below, the old edge rect would be the bounding box
- // of tiles {h,i,j}. |min_toss_x| would be equal to the horizontal index
- // of the same tiles.
+ // In the picture below, the delta edge rect would be the bounding box of
+ // tiles {h,i,j}. |min_toss_x| would be equal to the horizontal index of
+ // the same tiles.
//
- // old pile edge-v new pile edge-v
+ // min pile edge-v max pile edge-v
// ---------------+ - - - - - - - -+
// mmppssvvyybbeeh|h .
// mmppssvvyybbeeh|h .
@@ -242,33 +253,33 @@
// nnqqttwwzzccffi|i .
// oorruuxxaaddggj|j .
// oorruuxxaaddggj|j .
- // ---------------+ - - - - - - - -+ <- old pile edge
+ // ---------------+ - - - - - - - -+ <- min pile edge
// .
- // - - - - - - - - - - - - - - - -+ <- new pile edge
+ // - - - - - - - - - - - - - - - -+ <- max pile edge
//
// If you were to slide a vertical beam from the left edge of the
- // old edge rect toward the right, it would either hit the right edge
- // of the old edge rect, or the interest rect (expanded to the bounds
+ // delta edge rect toward the right, it would either hit the right edge
+ // of the delta edge rect, or the interest rect (expanded to the bounds
// of the tiles it touches). The same is true for a beam parallel to
- // any of the four edges, sliding accross the old edge rect. We use
+ // any of the four edges, sliding across the delta edge rect. We use
// the union of these four rectangles generated by these beams to
- // determine which part of the old edge rect is outside of the expanded
+ // determine which part of the delta edge rect is outside of the expanded
// interest rect.
//
- // Case 1: Intersect rect is outside the old edge rect. It can be
+ // Case 1: Intersect rect is outside the delta edge rect. It can be
// either on the left or the right. The |left_rect| and |right_rect|,
// cover this case, one will be empty and one will cover the full
- // old edge rect. In the picture below, |left_rect| would cover the
- // old edge rect, and |right_rect| would be empty.
+ // delta edge rect. In the picture below, |left_rect| would cover the
+ // delta edge rect, and |right_rect| would be empty.
// +----------------------+ |^^^^^^^^^^^^^^^|
- // |===> OLD EDGE RECT | | |
+ // |===> DELTA EDGE RECT | | |
// |===> | | INTEREST RECT |
// |===> | | |
// |===> | | |
// +----------------------+ |vvvvvvvvvvvvvvv|
//
- // Case 2: Interest rect is inside the old edge rect. It will always
- // fill the entire old edge rect horizontally since the old edge rect
+ // Case 2: Interest rect is inside the delta edge rect. It will always
+ // fill the entire delta edge rect horizontally since the old edge rect
// is a single tile wide, and the interest rect has been expanded to the
// bounds of the tiles it touches. In this case the |left_rect| and
// |right_rect| will be empty, but the case is handled by the |top_rect|
@@ -285,19 +296,19 @@
// | |
// +-----------------+
// | |
- // | OLD EDGE RECT |
+ // | DELTA EDGE RECT |
// +-----------------+
//
// Lastly, we need to consider tiles inside the expanded interest rect.
// For those tiles, we want to invalidate exactly the newly exposed
- // pixels. In the picture below the tiles in the old edge rect have been
- // resized and the area covered by periods must be invalidated. The
+ // pixels. In the picture below the tiles in the delta edge rect have
+ // been resized and the area covered by periods must be invalidated. The
// |exposed_rect| will cover exactly that area.
- // v-old pile edge
+ // v-min pile edge
// +---------+-------+
// | ........|
// | ........|
- // | OLD EDGE.RECT..|
+ // | DELTA EDGE.RECT.|
// | ........|
// | ........|
// | ........|
@@ -308,18 +319,18 @@
int left = tiling_.TilePositionX(min_toss_x);
int right = left + tiling_.TileSizeX(min_toss_x);
- int top = old_tiling_rect_over_tiles.y();
- int bottom = old_tiling_rect_over_tiles.bottom();
+ int top = min_tiling_rect_over_tiles.y();
+ int bottom = min_tiling_rect_over_tiles.bottom();
int left_until = std::min(interest_rect_over_tiles.x(), right);
int right_until = std::max(interest_rect_over_tiles.right(), left);
int top_until = std::min(interest_rect_over_tiles.y(), bottom);
int bottom_until = std::max(interest_rect_over_tiles.bottom(), top);
- int exposed_left = old_tiling_size.width();
- int exposed_left_until = tiling_size().width();
+ int exposed_left = min_tiling_size.width();
+ int exposed_left_until = max_tiling_size.width();
int exposed_top = top;
- int exposed_bottom = tiling_size().height();
+ int exposed_bottom = max_tiling_size.height();
DCHECK_GE(exposed_left, left);
gfx::Rect left_rect(left, top, left_until - left, bottom - top);
@@ -339,23 +350,23 @@
}
if (min_toss_y < tiling_.num_tiles_y()) {
// The same thing occurs here as in the case above, but the invalidation
- // rect is the bounding box around the bottom row of tiles in the old
+ // rect is the bounding box around the bottom row of tiles in the min
// pile. This would be tiles {o,r,u,x,a,d,g,j} in the above picture.
int top = tiling_.TilePositionY(min_toss_y);
int bottom = top + tiling_.TileSizeY(min_toss_y);
- int left = old_tiling_rect_over_tiles.x();
- int right = old_tiling_rect_over_tiles.right();
+ int left = min_tiling_rect_over_tiles.x();
+ int right = min_tiling_rect_over_tiles.right();
int top_until = std::min(interest_rect_over_tiles.y(), bottom);
int bottom_until = std::max(interest_rect_over_tiles.bottom(), top);
int left_until = std::min(interest_rect_over_tiles.x(), right);
int right_until = std::max(interest_rect_over_tiles.right(), left);
- int exposed_top = old_tiling_size.height();
- int exposed_top_until = tiling_size().height();
+ int exposed_top = min_tiling_size.height();
+ int exposed_top_until = max_tiling_size.height();
int exposed_left = left;
- int exposed_right = tiling_size().width();
+ int exposed_right = max_tiling_size.width();
DCHECK_GE(exposed_top, top);
gfx::Rect left_rect(left, top, left_until - left, bottom - top);
diff --git a/cc/resources/picture_pile_unittest.cc b/cc/resources/picture_pile_unittest.cc
index 60a1f0b..00b1b0c 100644
--- a/cc/resources/picture_pile_unittest.cc
+++ b/cc/resources/picture_pile_unittest.cc
@@ -621,7 +621,8 @@
grow_down_tiling_size,
CornerSinglePixelRect(corner, grow_down_tiling_size));
- // We should have lost the recordings in the bottom row.
+ // We should have lost all of the recordings in the bottom row as none of them
+ // are in the current interest rect (which is either the above or below it).
EXPECT_EQ(6, pile_.tiling().num_tiles_x());
EXPECT_EQ(8, pile_.tiling().num_tiles_y());
for (int i = 0; i < 6; ++i) {
@@ -650,7 +651,8 @@
base_tiling_size,
CornerSinglePixelRect(corner, base_tiling_size));
- // We should have lost the recordings that are now outside the tiling only.
+ // When shrinking, we should have lost all the recordings in the bottom row
+ // not touching the interest rect.
EXPECT_EQ(6, pile_.tiling().num_tiles_x());
EXPECT_EQ(6, pile_.tiling().num_tiles_y());
for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
@@ -658,12 +660,49 @@
TestPicturePile::PictureMapKey key(i, j);
TestPicturePile::PictureMap& map = pile_.picture_map();
TestPicturePile::PictureMap::iterator it = map.find(key);
- EXPECT_EQ(j < 6, it != map.end() && it->second.GetPicture());
+ bool expect_tile;
+ switch (corner) {
+ case TOP_LEFT:
+ case TOP_RIGHT:
+ expect_tile = j < 5;
+ break;
+ case BOTTOM_LEFT:
+ // The interest rect in the bottom left tile means we'll record it.
+ expect_tile = j < 5 || (j == 5 && i == 0);
+ break;
+ case BOTTOM_RIGHT:
+ // The interest rect in the bottom right tile means we'll record it.
+ expect_tile = j < 5 || (j == 5 && i == 5);
+ break;
+ }
+ EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture());
}
}
- // No invalidation when shrinking.
- expected_invalidation.Clear();
+ // When shrinking, the previously exposed region is invalidated.
+ expected_invalidation = SubtractRegions(gfx::Rect(grow_down_tiling_size),
+ gfx::Rect(base_tiling_size));
+ // The whole bottom row of tiles (except any with the interest rect) are
+ // dropped.
+ gfx::Rect bottom_row_minus_existing_corner = gfx::UnionRects(
+ pile_.tiling().TileBounds(0, 5), pile_.tiling().TileBounds(5, 5));
+ switch (corner) {
+ case TOP_LEFT:
+ case TOP_RIGHT:
+ // No tiles are kept in the changed region because it doesn't
+ // intersect with the interest rect.
+ break;
+ case BOTTOM_LEFT:
+ bottom_row_minus_existing_corner.Subtract(
+ pile_.tiling().TileBounds(0, 5));
+ break;
+ case BOTTOM_RIGHT:
+ bottom_row_minus_existing_corner.Subtract(
+ pile_.tiling().TileBounds(5, 5));
+ break;
+ }
+
+ expected_invalidation.Union(bottom_row_minus_existing_corner);
EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
invalidation.Clear();
@@ -673,7 +712,9 @@
grow_right_tiling_size,
CornerSinglePixelRect(corner, grow_right_tiling_size));
- // We should have lost the recordings in the right column.
+ // We should have lost all of the recordings in the right column as none of
+ // them are in the current interest rect (which is either entirely left or
+ // right of it).
EXPECT_EQ(8, pile_.tiling().num_tiles_x());
EXPECT_EQ(6, pile_.tiling().num_tiles_y());
for (int i = 0; i < 6; ++i) {
@@ -702,7 +743,8 @@
base_tiling_size,
CornerSinglePixelRect(corner, base_tiling_size));
- // We should have lost the recordings that are now outside the tiling only.
+ // When shrinking, we should have lost all the recordings in the right column
+ // not touching the interest rect.
EXPECT_EQ(6, pile_.tiling().num_tiles_x());
EXPECT_EQ(6, pile_.tiling().num_tiles_y());
for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
@@ -710,12 +752,48 @@
TestPicturePile::PictureMapKey key(i, j);
TestPicturePile::PictureMap& map = pile_.picture_map();
TestPicturePile::PictureMap::iterator it = map.find(key);
- EXPECT_EQ(i < 6, it != map.end() && it->second.GetPicture());
+ bool expect_tile;
+ switch (corner) {
+ case TOP_LEFT:
+ case BOTTOM_LEFT:
+ // No tiles are kept in the changed region because it doesn't
+ // intersect with the interest rect.
+ expect_tile = i < 5;
+ break;
+ case TOP_RIGHT:
+ // The interest rect in the top right tile means we'll record it.
+ expect_tile = i < 5 || (j == 0 && i == 5);
+ break;
+ case BOTTOM_RIGHT:
+ // The interest rect in the bottom right tile means we'll record it.
+ expect_tile = i < 5 || (j == 5 && i == 5);
+ break;
+ }
+ EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture());
}
}
- // No invalidation when shrinking.
- expected_invalidation.Clear();
+ // When shrinking, the previously exposed region is invalidated.
+ expected_invalidation = SubtractRegions(gfx::Rect(grow_right_tiling_size),
+ gfx::Rect(base_tiling_size));
+ // The whole right column of tiles (except for ones with the interest rect)
+ // are dropped.
+ gfx::Rect right_column_minus_existing_corner = gfx::UnionRects(
+ pile_.tiling().TileBounds(5, 0), pile_.tiling().TileBounds(5, 5));
+ switch (corner) {
+ case TOP_LEFT:
+ case BOTTOM_LEFT:
+ break;
+ case TOP_RIGHT:
+ right_column_minus_existing_corner.Subtract(
+ pile_.tiling().TileBounds(5, 0));
+ break;
+ case BOTTOM_RIGHT:
+ right_column_minus_existing_corner.Subtract(
+ pile_.tiling().TileBounds(5, 5));
+ break;
+ }
+ expected_invalidation.Union(right_column_minus_existing_corner);
EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
invalidation.Clear();
@@ -740,7 +818,7 @@
// We invalidated all new pixels in the recording.
expected_invalidation = SubtractRegions(gfx::Rect(grow_both_tiling_size),
gfx::Rect(base_tiling_size));
- // But the new pixels don't cover the whole right_column.
+ // But the new pixels don't cover the whole right column or bottom row.
Region right_column_and_bottom_row =
UnionRegions(gfx::UnionRects(pile_.tiling().TileBounds(5, 0),
pile_.tiling().TileBounds(5, 5)),
@@ -753,9 +831,11 @@
invalidation.Clear();
UpdateWholePile();
- UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect());
+ UpdateAndExpandInvalidation(&invalidation, base_tiling_size,
+ CornerSinglePixelRect(corner, base_tiling_size));
- // We should have lost the recordings that are now outside the tiling only.
+ // We should have lost the recordings in the right column and bottom row,
+ // except where it intersects the interest rect.
EXPECT_EQ(6, pile_.tiling().num_tiles_x());
EXPECT_EQ(6, pile_.tiling().num_tiles_y());
for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
@@ -763,12 +843,54 @@
TestPicturePile::PictureMapKey key(i, j);
TestPicturePile::PictureMap& map = pile_.picture_map();
TestPicturePile::PictureMap::iterator it = map.find(key);
- EXPECT_EQ(i < 6 && j < 6, it != map.end() && it->second.GetPicture());
+ bool expect_tile;
+ switch (corner) {
+ case TOP_LEFT:
+ expect_tile = i < 5 && j < 5;
+ break;
+ case TOP_RIGHT:
+ // The interest rect in the top right tile means we'll record it.
+ expect_tile = (i < 5 && j < 5) || (j == 0 && i == 5);
+ break;
+ case BOTTOM_LEFT:
+ // The interest rect in the bottom left tile means we'll record it.
+ expect_tile = (i < 5 && j < 5) || (j == 5 && i == 0);
+ break;
+ case BOTTOM_RIGHT:
+ // The interest rect in the bottom right tile means we'll record it.
+ expect_tile = (i < 5 && j < 5) || (j == 5 && i == 5);
+ break;
+ }
+ EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture())
+ << i << "," << j;
}
}
- // No invalidation when shrinking.
- expected_invalidation.Clear();
+ // We invalidated all previous pixels in the recording.
+ expected_invalidation = SubtractRegions(gfx::Rect(grow_both_tiling_size),
+ gfx::Rect(base_tiling_size));
+ // The whole right column and bottom row of tiles (except for ones with the
+ // interest rect) are dropped.
+ Region right_column_and_bottom_row_minus_existing_corner =
+ right_column_and_bottom_row;
+ switch (corner) {
+ case TOP_LEFT:
+ break;
+ case BOTTOM_LEFT:
+ right_column_and_bottom_row_minus_existing_corner.Subtract(
+ pile_.tiling().TileBounds(0, 5));
+ break;
+ case TOP_RIGHT:
+ right_column_and_bottom_row_minus_existing_corner.Subtract(
+ pile_.tiling().TileBounds(5, 0));
+ break;
+ case BOTTOM_RIGHT:
+ right_column_and_bottom_row_minus_existing_corner.Subtract(
+ pile_.tiling().TileBounds(5, 5));
+ break;
+ }
+ expected_invalidation.Union(
+ right_column_and_bottom_row_minus_existing_corner);
EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
invalidation.Clear();
}
@@ -808,261 +930,228 @@
}
}
- UpdateAndExpandInvalidation(
- &invalidation,
- grow_down_tiling_size,
- CornerSinglePixelRect(corner, grow_down_tiling_size));
+ // In this test (unlike the large resize test), as all growing and shrinking
+ // happens within tiles, the resulting invalidation is symmetrical, so use
+ // this enum to repeat the test both ways.
+ enum ChangeDirection { GROW, SHRINK, LAST_DIRECTION = SHRINK };
- // We should have lost the recordings in the bottom row that do not intersect
- // the interest rect.
- EXPECT_EQ(6, pile_.tiling().num_tiles_x());
- EXPECT_EQ(6, pile_.tiling().num_tiles_y());
- for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
- for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
- TestPicturePile::PictureMapKey key(i, j);
- TestPicturePile::PictureMap& map = pile_.picture_map();
- TestPicturePile::PictureMap::iterator it = map.find(key);
- bool expect_tile;
+ // Grow downward.
+ for (int dir = 0; dir <= LAST_DIRECTION; ++dir) {
+ gfx::Size new_tiling_size =
+ dir == GROW ? grow_down_tiling_size : base_tiling_size;
+ UpdateWholePile();
+ UpdateAndExpandInvalidation(&invalidation, new_tiling_size,
+ CornerSinglePixelRect(corner, new_tiling_size));
+
+ // We should have lost the recordings in the bottom row that do not
+ // intersect the interest rect.
+ EXPECT_EQ(6, pile_.tiling().num_tiles_x());
+ EXPECT_EQ(6, pile_.tiling().num_tiles_y());
+ for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
+ for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
+ TestPicturePile::PictureMapKey key(i, j);
+ TestPicturePile::PictureMap& map = pile_.picture_map();
+ TestPicturePile::PictureMap::iterator it = map.find(key);
+ bool expect_tile;
+ switch (corner) {
+ case TOP_LEFT:
+ case TOP_RIGHT:
+ expect_tile = j < 5;
+ break;
+ case BOTTOM_LEFT:
+ // The interest rect in the bottom left tile means we'll record it.
+ expect_tile = j < 5 || (j == 5 && i == 0);
+ break;
+ case BOTTOM_RIGHT:
+ // The interest rect in the bottom right tile means we'll record it.
+ expect_tile = j < 5 || (j == 5 && i == 5);
+ break;
+ }
+ EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture());
+ }
+ }
+
+ // We invalidated the bottom row outside the new interest rect. The tile
+ // that insects the interest rect in invalidated only on its newly
+ // exposed or previously exposed pixels.
+ if (dir == GROW) {
+ // Only calculate the expected invalidation while growing, as the tile
+ // bounds post-growing is the newly exposed / previously exposed sizes.
+ // Post-shrinking, the tile bounds are smaller, so can't be used.
switch (corner) {
case TOP_LEFT:
case TOP_RIGHT:
- expect_tile = j < 5;
+ expected_invalidation = gfx::UnionRects(
+ pile_.tiling().TileBounds(0, 5), pile_.tiling().TileBounds(5, 5));
break;
case BOTTOM_LEFT:
- // The interest rect in the bottom left tile means we'll record it.
- expect_tile = j < 5 || (j == 5 && i == 0);
+ expected_invalidation = gfx::UnionRects(
+ pile_.tiling().TileBounds(1, 5), pile_.tiling().TileBounds(5, 5));
+ expected_invalidation.Union(SubtractRects(
+ pile_.tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size)));
break;
case BOTTOM_RIGHT:
- // The interest rect in the bottom right tile means we'll record it.
- expect_tile = j < 5 || (j == 5 && i == 5);
+ expected_invalidation = gfx::UnionRects(
+ pile_.tiling().TileBounds(0, 5), pile_.tiling().TileBounds(4, 5));
+ expected_invalidation.Union(SubtractRects(
+ pile_.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size)));
break;
}
- EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture());
}
+ EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
+ invalidation.Clear();
}
- // We invalidated the bottom row outside the new interest rect. The tile that
- // insects the interest rect in invalidated only on its new pixels.
- switch (corner) {
- case TOP_LEFT:
- case TOP_RIGHT:
- expected_invalidation = gfx::UnionRects(pile_.tiling().TileBounds(0, 5),
- pile_.tiling().TileBounds(5, 5));
- break;
- case BOTTOM_LEFT:
- expected_invalidation = gfx::UnionRects(pile_.tiling().TileBounds(1, 5),
- pile_.tiling().TileBounds(5, 5));
- expected_invalidation.Union(SubtractRects(pile_.tiling().TileBounds(0, 5),
- gfx::Rect(base_tiling_size)));
- break;
- case BOTTOM_RIGHT:
- expected_invalidation = gfx::UnionRects(pile_.tiling().TileBounds(0, 5),
- pile_.tiling().TileBounds(4, 5));
- expected_invalidation.Union(SubtractRects(pile_.tiling().TileBounds(5, 5),
- gfx::Rect(base_tiling_size)));
- break;
- }
- EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
- invalidation.Clear();
+ // Grow right.
+ for (int dir = 0; dir <= LAST_DIRECTION; ++dir) {
+ gfx::Size new_tiling_size =
+ dir == GROW ? grow_right_tiling_size : base_tiling_size;
+ UpdateWholePile();
+ UpdateAndExpandInvalidation(&invalidation, new_tiling_size,
+ CornerSinglePixelRect(corner, new_tiling_size));
- UpdateWholePile();
- UpdateAndExpandInvalidation(&invalidation,
- base_tiling_size,
- CornerSinglePixelRect(corner, base_tiling_size));
-
- // We should have lost nothing.
- EXPECT_EQ(6, pile_.tiling().num_tiles_x());
- EXPECT_EQ(6, pile_.tiling().num_tiles_y());
- for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
- for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
- TestPicturePile::PictureMapKey key(i, j);
- TestPicturePile::PictureMap& map = pile_.picture_map();
- TestPicturePile::PictureMap::iterator it = map.find(key);
- EXPECT_TRUE(it != map.end() && it->second.GetPicture());
+ // We should have lost the recordings in the right column.
+ EXPECT_EQ(6, pile_.tiling().num_tiles_x());
+ EXPECT_EQ(6, pile_.tiling().num_tiles_y());
+ for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
+ for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
+ TestPicturePile::PictureMapKey key(i, j);
+ TestPicturePile::PictureMap& map = pile_.picture_map();
+ TestPicturePile::PictureMap::iterator it = map.find(key);
+ bool expect_tile;
+ switch (corner) {
+ case TOP_LEFT:
+ case BOTTOM_LEFT:
+ expect_tile = i < 5;
+ break;
+ case TOP_RIGHT:
+ // The interest rect in the top right tile means we'll record it.
+ expect_tile = i < 5 || (j == 0 && i == 5);
+ break;
+ case BOTTOM_RIGHT:
+ // The interest rect in the bottom right tile means we'll record it.
+ expect_tile = i < 5 || (j == 5 && i == 5);
+ break;
+ }
+ EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture());
+ }
}
- }
- // We invalidated nothing.
- expected_invalidation.Clear();
- EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
- invalidation.Clear();
-
- UpdateWholePile();
- UpdateAndExpandInvalidation(
- &invalidation,
- grow_right_tiling_size,
- CornerSinglePixelRect(corner, grow_right_tiling_size));
-
- // We should have lost the recordings in the right column.
- EXPECT_EQ(6, pile_.tiling().num_tiles_x());
- EXPECT_EQ(6, pile_.tiling().num_tiles_y());
- for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
- for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
- TestPicturePile::PictureMapKey key(i, j);
- TestPicturePile::PictureMap& map = pile_.picture_map();
- TestPicturePile::PictureMap::iterator it = map.find(key);
- bool expect_tile;
+ // We invalidated the right column outside the new interest rect. The tile
+ // that insects the interest rect in invalidated only on its new or
+ // previously exposed pixels.
+ if (dir == GROW) {
+ // Calculate the expected invalidation the first time through the loop.
switch (corner) {
case TOP_LEFT:
case BOTTOM_LEFT:
- expect_tile = i < 5;
+ expected_invalidation = gfx::UnionRects(
+ pile_.tiling().TileBounds(5, 0), pile_.tiling().TileBounds(5, 5));
break;
case TOP_RIGHT:
- // The interest rect in the top right tile means we'll record it.
- expect_tile = i < 5 || (j == 0 && i == 5);
+ expected_invalidation = gfx::UnionRects(
+ pile_.tiling().TileBounds(5, 1), pile_.tiling().TileBounds(5, 5));
+ expected_invalidation.Union(SubtractRects(
+ pile_.tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size)));
break;
case BOTTOM_RIGHT:
- // The interest rect in the bottom right tile means we'll record it.
- expect_tile = i < 5 || (j == 5 && i == 5);
+ expected_invalidation = gfx::UnionRects(
+ pile_.tiling().TileBounds(5, 0), pile_.tiling().TileBounds(5, 4));
+ expected_invalidation.Union(SubtractRects(
+ pile_.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size)));
break;
}
- EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture());
}
+ EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
+ invalidation.Clear();
}
- // We invalidated the right column outside the new interest rect. The tile
- // that insects the interest rect in invalidated only on its new pixels.
- switch (corner) {
- case TOP_LEFT:
- case BOTTOM_LEFT:
- expected_invalidation = gfx::UnionRects(pile_.tiling().TileBounds(5, 0),
- pile_.tiling().TileBounds(5, 5));
- break;
- case TOP_RIGHT:
- expected_invalidation = gfx::UnionRects(pile_.tiling().TileBounds(5, 1),
- pile_.tiling().TileBounds(5, 5));
- expected_invalidation.Union(SubtractRects(pile_.tiling().TileBounds(5, 0),
- gfx::Rect(base_tiling_size)));
- break;
- case BOTTOM_RIGHT:
- expected_invalidation = gfx::UnionRects(pile_.tiling().TileBounds(5, 0),
- pile_.tiling().TileBounds(5, 4));
- expected_invalidation.Union(SubtractRects(pile_.tiling().TileBounds(5, 5),
- gfx::Rect(base_tiling_size)));
- break;
- }
- EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
- invalidation.Clear();
+ // Grow both.
+ for (int dir = 0; dir <= LAST_DIRECTION; ++dir) {
+ gfx::Size new_tiling_size =
+ dir == GROW ? grow_both_tiling_size : base_tiling_size;
+ UpdateWholePile();
+ UpdateAndExpandInvalidation(&invalidation, new_tiling_size,
+ CornerSinglePixelRect(corner, new_tiling_size));
- UpdateWholePile();
- UpdateAndExpandInvalidation(&invalidation,
- base_tiling_size,
- CornerSinglePixelRect(corner, base_tiling_size));
-
- // We should have lost nothing.
- EXPECT_EQ(6, pile_.tiling().num_tiles_x());
- EXPECT_EQ(6, pile_.tiling().num_tiles_y());
- for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
- for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
- TestPicturePile::PictureMapKey key(i, j);
- TestPicturePile::PictureMap& map = pile_.picture_map();
- TestPicturePile::PictureMap::iterator it = map.find(key);
- EXPECT_TRUE(it != map.end() && it->second.GetPicture());
+ // We should have lost the recordings in the right column and bottom row.
+ // The tile that insects the interest rect in invalidated only on its new
+ // or previously exposed pixels.
+ EXPECT_EQ(6, pile_.tiling().num_tiles_x());
+ EXPECT_EQ(6, pile_.tiling().num_tiles_y());
+ for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
+ for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
+ TestPicturePile::PictureMapKey key(i, j);
+ TestPicturePile::PictureMap& map = pile_.picture_map();
+ TestPicturePile::PictureMap::iterator it = map.find(key);
+ bool expect_tile;
+ switch (corner) {
+ case TOP_LEFT:
+ expect_tile = i < 5 && j < 5;
+ break;
+ case TOP_RIGHT:
+ // The interest rect in the top right tile means we'll record it.
+ expect_tile = (i < 5 && j < 5) || (j == 0 && i == 5);
+ break;
+ case BOTTOM_LEFT:
+ // The interest rect in the bottom left tile means we'll record it.
+ expect_tile = (i < 5 && j < 5) || (j == 5 && i == 0);
+ break;
+ case BOTTOM_RIGHT:
+ // The interest rect in the bottom right tile means we'll record it.
+ expect_tile = (i < 5 && j < 5) || (j == 5 && i == 5);
+ break;
+ }
+ EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture())
+ << i << "," << j;
+ }
}
- }
- // We invalidated nothing.
- expected_invalidation.Clear();
- EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
- invalidation.Clear();
-
- UpdateWholePile();
- UpdateAndExpandInvalidation(
- &invalidation,
- grow_both_tiling_size,
- CornerSinglePixelRect(corner, grow_both_tiling_size));
-
- // We should have lost the recordings in the right column and bottom row. The
- // tile that insects the interest rect in invalidated only on its new pixels.
- EXPECT_EQ(6, pile_.tiling().num_tiles_x());
- EXPECT_EQ(6, pile_.tiling().num_tiles_y());
- for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
- for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
- TestPicturePile::PictureMapKey key(i, j);
- TestPicturePile::PictureMap& map = pile_.picture_map();
- TestPicturePile::PictureMap::iterator it = map.find(key);
- bool expect_tile;
+ // We invalidated the right column and the bottom row outside the new
+ // interest rect. The tile that insects the interest rect in invalidated
+ // only on its new or previous exposed pixels.
+ if (dir == GROW) {
+ // Calculate the expected invalidation the first time through the loop.
switch (corner) {
case TOP_LEFT:
- expect_tile = i < 5 && j < 5;
+ expected_invalidation = gfx::UnionRects(
+ pile_.tiling().TileBounds(5, 0), pile_.tiling().TileBounds(5, 5));
+ expected_invalidation.Union(
+ gfx::UnionRects(pile_.tiling().TileBounds(0, 5),
+ pile_.tiling().TileBounds(5, 5)));
break;
case TOP_RIGHT:
- // The interest rect in the top right tile means we'll record it.
- expect_tile = (i < 5 && j < 5) || (j == 0 && i == 5);
+ expected_invalidation = gfx::UnionRects(
+ pile_.tiling().TileBounds(5, 1), pile_.tiling().TileBounds(5, 5));
+ expected_invalidation.Union(
+ gfx::UnionRects(pile_.tiling().TileBounds(0, 5),
+ pile_.tiling().TileBounds(5, 5)));
+ expected_invalidation.Union(SubtractRects(
+ pile_.tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size)));
break;
case BOTTOM_LEFT:
- // The interest rect in the bottom left tile means we'll record it.
- expect_tile = (i < 5 && j < 5) || (j == 5 && i == 0);
+ expected_invalidation = gfx::UnionRects(
+ pile_.tiling().TileBounds(5, 0), pile_.tiling().TileBounds(5, 5));
+ expected_invalidation.Union(
+ gfx::UnionRects(pile_.tiling().TileBounds(1, 5),
+ pile_.tiling().TileBounds(5, 5)));
+ expected_invalidation.Union(SubtractRects(
+ pile_.tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size)));
break;
case BOTTOM_RIGHT:
- // The interest rect in the bottom right tile means we'll record it.
- expect_tile = (i < 5 && j < 5) || (j == 5 && i == 5);
+ expected_invalidation = gfx::UnionRects(
+ pile_.tiling().TileBounds(5, 0), pile_.tiling().TileBounds(5, 4));
+ expected_invalidation.Union(
+ gfx::UnionRects(pile_.tiling().TileBounds(0, 5),
+ pile_.tiling().TileBounds(4, 5)));
+ expected_invalidation.Union(SubtractRegions(
+ pile_.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size)));
break;
}
- EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture())
- << i << "," << j;
}
+ EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
+ invalidation.Clear();
}
-
- // We invalidated the right column and the bottom row outside the new interest
- // rect. The tile that insects the interest rect in invalidated only on its
- // new pixels.
- switch (corner) {
- case TOP_LEFT:
- expected_invalidation = gfx::UnionRects(pile_.tiling().TileBounds(5, 0),
- pile_.tiling().TileBounds(5, 5));
- expected_invalidation.Union(gfx::UnionRects(
- pile_.tiling().TileBounds(0, 5), pile_.tiling().TileBounds(5, 5)));
- break;
- case TOP_RIGHT:
- expected_invalidation = gfx::UnionRects(pile_.tiling().TileBounds(5, 1),
- pile_.tiling().TileBounds(5, 5));
- expected_invalidation.Union(gfx::UnionRects(
- pile_.tiling().TileBounds(0, 5), pile_.tiling().TileBounds(5, 5)));
- expected_invalidation.Union(SubtractRects(pile_.tiling().TileBounds(5, 0),
- gfx::Rect(base_tiling_size)));
- break;
- case BOTTOM_LEFT:
- expected_invalidation = gfx::UnionRects(pile_.tiling().TileBounds(5, 0),
- pile_.tiling().TileBounds(5, 5));
- expected_invalidation.Union(gfx::UnionRects(
- pile_.tiling().TileBounds(1, 5), pile_.tiling().TileBounds(5, 5)));
- expected_invalidation.Union(SubtractRects(pile_.tiling().TileBounds(0, 5),
- gfx::Rect(base_tiling_size)));
- break;
- case BOTTOM_RIGHT:
- expected_invalidation = gfx::UnionRects(pile_.tiling().TileBounds(5, 0),
- pile_.tiling().TileBounds(5, 4));
- expected_invalidation.Union(gfx::UnionRects(
- pile_.tiling().TileBounds(0, 5), pile_.tiling().TileBounds(4, 5)));
- expected_invalidation.Union(SubtractRegions(
- pile_.tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size)));
- break;
- }
- EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
- invalidation.Clear();
-
- UpdateWholePile();
- UpdateAndExpandInvalidation(&invalidation,
- base_tiling_size,
- CornerSinglePixelRect(corner, base_tiling_size));
-
- // We should have lost nothing.
- EXPECT_EQ(6, pile_.tiling().num_tiles_x());
- EXPECT_EQ(6, pile_.tiling().num_tiles_y());
- for (int i = 0; i < pile_.tiling().num_tiles_x(); ++i) {
- for (int j = 0; j < pile_.tiling().num_tiles_y(); ++j) {
- TestPicturePile::PictureMapKey key(i, j);
- TestPicturePile::PictureMap& map = pile_.picture_map();
- TestPicturePile::PictureMap::iterator it = map.find(key);
- EXPECT_TRUE(it != map.end() && it->second.GetPicture());
- }
- }
-
- // We invalidated nothing.
- expected_invalidation.Clear();
- EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
- invalidation.Clear();
}
INSTANTIATE_TEST_CASE_P(
@@ -1139,8 +1228,11 @@
}
}
- // No invalidation when shrinking.
- EXPECT_EQ(Region().ToString(), invalidation.ToString());
+ // We invalidated the previously exposed pixels on the bottom row of tiles.
+ expected_invalidation = SubtractRegions(gfx::Rect(grow_down_tiling_size),
+ gfx::Rect(base_tiling_size));
+ EXPECT_TRUE(expected_invalidation.Contains(bottom_row_new_pixels));
+ EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
invalidation.Clear();
UpdateWholePile();
@@ -1185,8 +1277,11 @@
}
}
- // No invalidation when shrinking.
- EXPECT_EQ(Region().ToString(), invalidation.ToString());
+ // We invalidated the previously exposed pixels on the right column of tiles.
+ expected_invalidation = SubtractRegions(gfx::Rect(grow_right_tiling_size),
+ gfx::Rect(base_tiling_size));
+ EXPECT_TRUE(expected_invalidation.Contains(right_column_new_pixels));
+ EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
invalidation.Clear();
UpdateWholePile();
@@ -1235,8 +1330,13 @@
}
}
- // No invalidation when shrinking.
- EXPECT_EQ(Region().ToString(), invalidation.ToString());
+ // We invalidated the previously exposed pixels on the bottom row and right
+ // column of tiles.
+ expected_invalidation = SubtractRegions(gfx::Rect(grow_both_tiling_size),
+ gfx::Rect(base_tiling_size));
+ EXPECT_TRUE(
+ expected_invalidation.Contains(bottom_row_and_right_column_new_pixels));
+ EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
invalidation.Clear();
}
@@ -1304,8 +1404,10 @@
}
}
- // No invalidation when shrinking.
- EXPECT_EQ(Region().ToString(), invalidation.ToString());
+ // We invalidated the previously exposed pixels.
+ expected_invalidation = SubtractRegions(gfx::Rect(grow_down_tiling_size),
+ gfx::Rect(base_tiling_size));
+ EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
invalidation.Clear();
UpdateWholePile();
@@ -1345,8 +1447,10 @@
}
}
- // No invalidation when shrinking.
- EXPECT_EQ(Region().ToString(), invalidation.ToString());
+ // We invalidated the previously exposed pixels.
+ expected_invalidation = SubtractRegions(gfx::Rect(grow_right_tiling_size),
+ gfx::Rect(base_tiling_size));
+ EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
invalidation.Clear();
UpdateWholePile();
@@ -1386,8 +1490,10 @@
}
}
- // No invalidation when shrinking.
- EXPECT_EQ(Region().ToString(), invalidation.ToString());
+ // We invalidated the previously exposed pixels.
+ expected_invalidation = SubtractRegions(gfx::Rect(grow_both_tiling_size),
+ gfx::Rect(base_tiling_size));
+ EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
invalidation.Clear();
}
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 00be57f..9bee07e 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -2653,7 +2653,18 @@
bool consume_by_top_controls = ShouldTopControlsConsumeScroll(scroll_delta);
- for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
+ // There's an edge case where the outer viewport isn't scrollable when the
+ // scroll starts, however, as the top controls show the outer viewport becomes
+ // scrollable. Therefore, always try scrolling the outer viewport before the
+ // inner.
+ // TODO(bokan): Move the top controls logic out of the loop since the scroll
+ // that causes the outer viewport to become scrollable will still be applied
+ // to the inner viewport.
+ LayerImpl* start_layer = CurrentlyScrollingLayer();
+ if (start_layer == InnerViewportScrollLayer() && OuterViewportScrollLayer())
+ start_layer = OuterViewportScrollLayer();
+
+ for (LayerImpl* layer_impl = start_layer;
layer_impl;
layer_impl = layer_impl->parent()) {
if (!layer_impl->scrollable())
@@ -2708,40 +2719,49 @@
}
}
+ // Scrolls should bubble perfectly between the outer and inner viewports.
+ bool allow_unrestricted_bubbling_for_current_layer =
+ layer_impl == OuterViewportScrollLayer();
+ bool allow_bubbling_for_current_layer =
+ allow_unrestricted_bubbling_for_current_layer || should_bubble_scrolls_;
+
// If the layer wasn't able to move, try the next one in the hierarchy.
bool did_move_layer_x = std::abs(applied_delta.x()) > kEpsilon;
bool did_move_layer_y = std::abs(applied_delta.y()) > kEpsilon;
did_scroll_x |= did_move_layer_x;
did_scroll_y |= did_move_layer_y;
if (!did_move_layer_x && !did_move_layer_y) {
- // Scrolls should always bubble between the outer and inner viewports
- if (should_bubble_scrolls_ || !did_lock_scrolling_layer_ ||
- layer_impl == OuterViewportScrollLayer())
+ if (allow_bubbling_for_current_layer || !did_lock_scrolling_layer_)
continue;
else
break;
}
did_lock_scrolling_layer_ = true;
- if (!should_bubble_scrolls_) {
+ if (!allow_bubbling_for_current_layer) {
active_tree_->SetCurrentlyScrollingLayer(layer_impl);
break;
}
- // If the applied delta is within 45 degrees of the input delta, bail out to
- // make it easier to scroll just one layer in one direction without
- // affecting any of its parents.
- float angle_threshold = 45;
- if (MathUtil::SmallestAngleBetweenVectors(
- applied_delta, pending_delta) < angle_threshold) {
- pending_delta = gfx::Vector2dF();
- break;
- }
+ if (allow_unrestricted_bubbling_for_current_layer) {
+ pending_delta -= applied_delta;
+ } else {
+ // If the applied delta is within 45 degrees of the input delta, bail out
+ // to make it easier to scroll just one layer in one direction without
+ // affecting any of its parents.
+ float angle_threshold = 45;
+ if (MathUtil::SmallestAngleBetweenVectors(applied_delta, pending_delta) <
+ angle_threshold) {
+ pending_delta = gfx::Vector2dF();
+ break;
+ }
- // Allow further movement only on an axis perpendicular to the direction in
- // which the layer moved.
- gfx::Vector2dF perpendicular_axis(-applied_delta.y(), applied_delta.x());
- pending_delta = MathUtil::ProjectVector(pending_delta, perpendicular_axis);
+ // Allow further movement only on an axis perpendicular to the direction
+ // in which the layer moved.
+ gfx::Vector2dF perpendicular_axis(-applied_delta.y(), applied_delta.x());
+ pending_delta =
+ MathUtil::ProjectVector(pending_delta, perpendicular_axis);
+ }
if (gfx::ToRoundedVector2d(pending_delta).IsZero())
break;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 45d636a..adc11d0 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -2328,6 +2328,8 @@
const gfx::Size& outer_viewport_size,
const gfx::Size& scroll_layer_size) {
CreateHostImpl(settings_, CreateOutputSurface());
+ host_impl_->SetTopControlsLayoutHeight(
+ settings_.top_controls_height);
scoped_ptr<LayerImpl> root =
LayerImpl::Create(host_impl_->active_tree(), 1);
@@ -2373,8 +2375,6 @@
outer_viewport_scroll_layer_id);
host_impl_->SetViewportSize(inner_viewport_size);
- host_impl_->SetTopControlsLayoutHeight(
- settings_.top_controls_height);
LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer();
EXPECT_EQ(inner_viewport_size, root_clip_ptr->bounds());
}
@@ -2411,6 +2411,81 @@
inner_viewport_scroll_layer->FixedContainerSizeDelta());
}
+// In this test, the outer viewport is initially unscrollable. We test that a
+// scroll initiated on the inner viewport, causing the top controls to show and
+// thus making the outer viewport scrollable, still scrolls the outer viewport.
+TEST_F(LayerTreeHostImplTopControlsTest,
+ TopControlsOuterViewportBecomesScrollable) {
+ SetupTopControlsAndScrollLayerWithVirtualViewport(
+ gfx::Size(10, 50), gfx::Size(10, 50), gfx::Size(10, 100));
+ DrawFrame();
+
+ LayerImpl *inner_scroll =
+ host_impl_->active_tree()->InnerViewportScrollLayer();
+ LayerImpl *inner_container =
+ host_impl_->active_tree()->InnerViewportContainerLayer();
+ LayerImpl *outer_scroll =
+ host_impl_->active_tree()->OuterViewportScrollLayer();
+ LayerImpl *outer_container =
+ host_impl_->active_tree()->OuterViewportContainerLayer();
+
+ // Need SetDrawsContent so ScrollBegin's hit test finds an actual layer.
+ outer_scroll->SetDrawsContent(true);
+ host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 1.f, 2.f);
+
+ EXPECT_EQ(InputHandler::ScrollStarted,
+ host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, 50.f));
+
+ // The entire scroll delta should have been used to hide the top controls.
+ // The viewport layers should be resized back to their full sizes.
+ EXPECT_EQ(0.f,
+ host_impl_->active_tree()->total_top_controls_content_offset());
+ EXPECT_EQ(0.f, inner_scroll->TotalScrollOffset().y());
+ EXPECT_EQ(100.f, inner_container->BoundsForScrolling().height());
+ EXPECT_EQ(100.f, outer_container->BoundsForScrolling().height());
+
+ // The inner viewport should be scrollable by 50px * page_scale.
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, 100.f));
+ EXPECT_EQ(50.f, inner_scroll->TotalScrollOffset().y());
+ EXPECT_EQ(0.f, outer_scroll->TotalScrollOffset().y());
+ EXPECT_EQ(gfx::ScrollOffset(), outer_scroll->MaxScrollOffset());
+
+ host_impl_->ScrollEnd();
+
+ EXPECT_EQ(InputHandler::ScrollStarted,
+ host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
+ EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), inner_scroll);
+
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -50.f));
+
+ // The entire scroll delta should have been used to show the top controls.
+ // The outer viewport should be resized to accomodate and scrolled to the
+ // bottom of the document to keep the viewport in place.
+ EXPECT_EQ(50.f,
+ host_impl_->active_tree()->total_top_controls_content_offset());
+ EXPECT_EQ(50.f, outer_container->BoundsForScrolling().height());
+ EXPECT_EQ(50.f, inner_container->BoundsForScrolling().height());
+ EXPECT_EQ(25.f, outer_scroll->TotalScrollOffset().y());
+ EXPECT_EQ(25.f, inner_scroll->TotalScrollOffset().y());
+
+ // Now when we continue scrolling, make sure the outer viewport gets scrolled
+ // since it wasn't scrollable when the scroll began.
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -20.f));
+ EXPECT_EQ(15.f, outer_scroll->TotalScrollOffset().y());
+ EXPECT_EQ(25.f, inner_scroll->TotalScrollOffset().y());
+
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -30.f));
+ EXPECT_EQ(0.f, outer_scroll->TotalScrollOffset().y());
+ EXPECT_EQ(25.f, inner_scroll->TotalScrollOffset().y());
+
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -50.f));
+ host_impl_->ScrollEnd();
+
+ EXPECT_EQ(0.f, outer_scroll->TotalScrollOffset().y());
+ EXPECT_EQ(0.f, inner_scroll->TotalScrollOffset().y());
+}
+
// Test that the fixed position container delta is appropriately adjusted
// by the top controls showing/hiding and page scale doesn't affect it.
TEST_F(LayerTreeHostImplTopControlsTest, FixedContainerDelta) {
@@ -7412,6 +7487,49 @@
}
}
+TEST_F(LayerTreeHostImplVirtualViewportTest,
+ DiagonalScrollBubblesPerfectlyToInner) {
+ gfx::Size content_size = gfx::Size(100, 160);
+ gfx::Size outer_viewport = gfx::Size(50, 80);
+ gfx::Size inner_viewport = gfx::Size(25, 40);
+
+ SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
+
+ LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
+ LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
+ DrawFrame();
+ {
+ gfx::Vector2dF inner_expected;
+ gfx::Vector2dF outer_expected;
+ EXPECT_VECTOR_EQ(inner_expected, inner_scroll->TotalScrollOffset());
+ EXPECT_VECTOR_EQ(outer_expected, outer_scroll->TotalScrollOffset());
+
+ // Make sure the scroll goes to the outer viewport first.
+ EXPECT_EQ(InputHandler::ScrollStarted,
+ host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
+ EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->FlingScrollBegin());
+
+ // Scroll near the edge of the outer viewport.
+ gfx::Vector2d scroll_delta(inner_viewport.width(), inner_viewport.height());
+ host_impl_->ScrollBy(gfx::Point(), scroll_delta);
+ outer_expected += scroll_delta;
+
+ EXPECT_VECTOR_EQ(inner_expected, inner_scroll->TotalScrollOffset());
+ EXPECT_VECTOR_EQ(outer_expected, outer_scroll->TotalScrollOffset());
+
+ // Now diagonal scroll across the outer viewport boundary in a single event.
+ // The entirety of the scroll should be consumed, as bubbling between inner
+ // and outer viewport layers is perfect.
+ host_impl_->ScrollBy(gfx::Point(), gfx::ScaleVector2d(scroll_delta, 2));
+ outer_expected += scroll_delta;
+ inner_expected += scroll_delta;
+ host_impl_->ScrollEnd();
+
+ EXPECT_VECTOR_EQ(inner_expected, inner_scroll->TotalScrollOffset());
+ EXPECT_VECTOR_EQ(outer_expected, outer_scroll->TotalScrollOffset());
+ }
+}
+
class LayerTreeHostImplWithImplicitLimitsTest : public LayerTreeHostImplTest {
public:
virtual void SetUp() override {
diff --git a/chrome/VERSION b/chrome/VERSION
index ab00d16..c703e46 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
MAJOR=40
MINOR=0
BUILD=2214
-PATCH=10
+PATCH=27
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml
index a30be4a..63a870f 100644
--- a/chrome/android/java/res/values-v17/styles.xml
+++ b/chrome/android/java/res/values-v17/styles.xml
@@ -38,6 +38,9 @@
<item name="android:textAlignment">viewStart</item>
<item name="android:textStyle">bold</item>
<item name="android:paddingTop">10dp</item>
+ <!-- These aren't really clickable, this is just a hack to make labels
+ accessibility focusable. -->
+ <item name="android:clickable">true</item>
</style>
<style name="OverflowMenuThemeBase" parent="Theme.AppCompat.Light">
<item name="android:popupBackground">@null</item>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/NotificationUIManager.java b/chrome/android/java/src/org/chromium/chrome/browser/NotificationUIManager.java
new file mode 100644
index 0000000..1e029ef
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/NotificationUIManager.java
@@ -0,0 +1,122 @@
+// Copyright 2014 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.
+
+package org.chromium.chrome.browser;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Bitmap;
+
+import org.chromium.base.CalledByNative;
+
+/**
+ * Provides the ability for the NotificationUIManagerAndroid to talk to the Android platform
+ * notification manager.
+ *
+ * This class should only be used on the UI thread.
+ */
+public class NotificationUIManager extends BroadcastReceiver {
+ private static final String EXTRA_NOTIFICATION_ID = "notification_id";
+
+ private static final String ACTION_CLICK_NOTIFICATION =
+ "org.chromium.chrome.browser.CLICK_NOTIFICATION";
+ private static final String ACTION_CLOSE_NOTIFICATION =
+ "org.chromium.chrome.browser.CLOSE_NOTIFICATION";
+
+ private final long mNativeNotificationManager;
+
+ private final Context mAppContext;
+ private final NotificationManager mNotificationManager;
+
+ private int mLastNotificationId;
+
+ private NotificationUIManager(long nativeNotificationManager, Context context) {
+ super();
+
+ mNativeNotificationManager = nativeNotificationManager;
+ mAppContext = context.getApplicationContext();
+
+ mNotificationManager = (NotificationManager)
+ mAppContext.getSystemService(Context.NOTIFICATION_SERVICE);
+
+ mLastNotificationId = 0;
+
+ // Register this instance as a broadcast receiver, which will be used for handling
+ // clicked-on and rejected notifications.
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_CLICK_NOTIFICATION);
+ filter.addAction(ACTION_CLOSE_NOTIFICATION);
+
+ // TODO(peter): Notification events should be received by an intent receiver that does not
+ // require Chrome to be running all the time.
+ mAppContext.registerReceiver(this, filter);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (!intent.hasExtra(EXTRA_NOTIFICATION_ID))
+ return;
+
+ String notificationId = intent.getStringExtra(EXTRA_NOTIFICATION_ID);
+ if (ACTION_CLICK_NOTIFICATION.equals(intent.getAction())) {
+ nativeOnNotificationClicked(mNativeNotificationManager, notificationId);
+ } else if (ACTION_CLOSE_NOTIFICATION.equals(intent.getAction())) {
+ nativeOnNotificationClosed(mNativeNotificationManager, notificationId);
+ }
+ }
+
+ private PendingIntent getPendingIntent(String notificationId, int platformId, String action) {
+ Intent intent = new Intent(action);
+ intent.putExtra(EXTRA_NOTIFICATION_ID, notificationId);
+
+ return PendingIntent.getBroadcast(mAppContext, platformId, intent, 0);
+ }
+
+ /**
+ * Displays a notification with the given |notificationId|, |title|, |body| and |icon|.
+ *
+ * @returns The id using which the notification can be identified.
+ */
+ @CalledByNative
+ private int displayNotification(String notificationId, String title, String body, Bitmap icon) {
+ Notification notification = new Notification.Builder(mAppContext)
+ .setContentTitle(title)
+ .setContentText(body)
+ .setLargeIcon(icon)
+ .setSmallIcon(android.R.drawable.ic_menu_myplaces)
+ .setContentIntent(getPendingIntent(
+ notificationId, mLastNotificationId, ACTION_CLICK_NOTIFICATION))
+ .setDeleteIntent(getPendingIntent(
+ notificationId, mLastNotificationId, ACTION_CLOSE_NOTIFICATION))
+ .build();
+
+ mNotificationManager.notify(mLastNotificationId, notification);
+
+ return mLastNotificationId++;
+ }
+
+ /**
+ * Closes the notification identified by |platformId|.
+ */
+ @CalledByNative
+ private void closeNotification(int platformId) {
+ mNotificationManager.cancel(platformId);
+ }
+
+ @CalledByNative
+ private static NotificationUIManager create(long nativeNotificationManager, Context context) {
+ return new NotificationUIManager(nativeNotificationManager, context);
+ }
+
+ private native void nativeOnNotificationClicked(
+ long nativeNotificationUIManagerAndroid, String notificationId);
+
+ private native void nativeOnNotificationClosed(
+ long nativeNotificationUIManagerAndroid, String notificationId);
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/Tab.java
index 38abe1c..3c59f3b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/Tab.java
@@ -366,8 +366,10 @@
mContext = context;
mApplicationContext = context != null ? context.getApplicationContext() : null;
mWindowAndroid = window;
- if (mContext != null)
- mNumPixel16DP = (int) DeviceDisplayInfo.create(mContext).getDIPScale() * 16;
+ if (mContext != null) {
+ mNumPixel16DP = (int) (DeviceDisplayInfo.create(mContext).getDIPScale() * 16);
+ }
+ if (mNumPixel16DP == 0) mNumPixel16DP = 16;
}
/**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java b/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java
index 21405d1..b47547f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java
@@ -204,7 +204,7 @@
return R.drawable.permission_location;
case ContentSettingsType.CONTENT_SETTINGS_TYPE_MEDIASTREAM:
return R.drawable.permission_media;
- case ContentSettingsType.CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
+ case ContentSettingsType.CONTENT_SETTINGS_TYPE_PUSH_MESSAGING:
return R.drawable.permission_push_notification;
case ContentSettingsType.CONTENT_SETTINGS_TYPE_POPUPS:
return R.drawable.permission_popups;
@@ -291,7 +291,8 @@
schemeColorId = getSchemeColorId(securityLevel);
}
- sb.append(parsedUrl.toString());
+ String parsedUrlString = parsedUrl.toString();
+ sb.append(parsedUrlString);
final ForegroundColorSpan schemeColorSpan = new ForegroundColorSpan(
mContext.getResources().getColor(schemeColorId));
sb.setSpan(schemeColorSpan, 0, parsedUrl.getScheme().length(),
@@ -301,12 +302,26 @@
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
- // The domain is everything after the scheme until the end of the origin.
+ // The domain does not include the '://'.
+ String originToDisplay = UrlUtilities.getOriginForDisplay(parsedUrl, false);
+ int originBegin = parsedUrlString.indexOf(originToDisplay,
+ parsedUrl.getScheme().length());
+ int originEnd = originBegin + originToDisplay.length();
+
+ // In some cases (e.g. 'about:blank') UrlUtilities.getOriginForDisplay will return the
+ // entire URL. In these cases originBegin will now be -1.
+ if (originBegin < 0) {
+ originBegin = parsedUrl.getScheme().length();
+ // Don't include the ':' in the origin for highlighting if present (it should always
+ // be there but check to be sure).
+ if (originBegin < parsedUrlString.length()) originBegin++;
+
+ originEnd = parsedUrlString.length();
+ }
+
final ForegroundColorSpan domainColorSpan = new ForegroundColorSpan(
mContext.getResources().getColor(R.color.website_settings_popup_url_domain));
- sb.setSpan(domainColorSpan, parsedUrl.getScheme().length(),
- UrlUtilities.getOriginForDisplay(parsedUrl, true).length(),
- Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+ sb.setSpan(domainColorSpan, originBegin, originEnd, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mUrlTitle.setText(sb);
} else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java
index 57b4241..04bb254 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java
@@ -38,8 +38,6 @@
* - Disabled items are grayed out.
*/
public class AppMenu implements OnItemClickListener, OnKeyListener {
- /** Whether or not to show the software menu button in the menu. */
- private static final boolean SHOW_SW_MENU_BUTTON = true;
private static final float LAST_ITEM_SHOW_FRACTION = 0.5f;
@@ -154,13 +152,11 @@
sizingPadding.bottom = originalPadding.bottom;
}
- boolean showMenuButton = !mIsByHardwareButton;
- if (!SHOW_SW_MENU_BUTTON) showMenuButton = false;
// A List adapter for visible items in the Menu. The first row is added as a header to the
// list view.
mAdapter = new AppMenuAdapter(
this, menuItems, LayoutInflater.from(context),
- showMenuButton, menuButtonStartPaddingPx);
+ false, menuButtonStartPaddingPx);
mPopup.setAdapter(mAdapter);
setMenuHeight(menuItems.size(), visibleDisplayFrame, screenHeight, sizingPadding);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java
index 3de993b..9bf78d4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java
@@ -15,7 +15,6 @@
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
-import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
@@ -314,12 +313,15 @@
return convertView;
}
- private void setupImageButton(ImageButton button, final MenuItem item) {
+ private void setupImageButton(TintedImageButton button, final MenuItem item) {
// Store and recover the level of image as button.setimageDrawable
// resets drawable to default level.
int currentLevel = item.getIcon().getLevel();
button.setImageDrawable(item.getIcon());
item.getIcon().setLevel(currentLevel);
+ if (item.isChecked()) {
+ button.setTint(button.getResources().getColorStateList(R.color.button_tint_menu));
+ }
button.setEnabled(item.isEnabled());
button.setFocusable(item.isEnabled());
button.setContentDescription(item.getTitleCondensed());
@@ -449,4 +451,4 @@
public TextView title;
public TintedImageButton button;
}
-}
\ No newline at end of file
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java
index fdb15ae..56ba021 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java
@@ -339,6 +339,14 @@
}
/**
+ * @return whether the Contextual Search feature is disabled by policy.
+ */
+ public boolean isContextualSearchDisabledByPolicy() {
+ return nativeGetContextualSearchPreferenceIsManaged()
+ && isContextualSearchDisabled();
+ }
+
+ /**
* @return whether the Contextual Search feature is uninitialized (preference unset by the
* user).
*/
@@ -705,6 +713,7 @@
private native void nativeSetPathValuesForAboutChrome();
private native void nativeSetContextualSearchPreference(String preference);
private native String nativeGetContextualSearchPreference();
+ private native boolean nativeGetContextualSearchPreferenceIsManaged();
private native boolean nativeGetSearchSuggestEnabled();
private native void nativeSetSearchSuggestEnabled(boolean enabled);
private native boolean nativeGetSearchSuggestManaged();
diff --git a/chrome/app/OWNERS b/chrome/app/OWNERS
index 7f71ab8..81113aa 100644
--- a/chrome/app/OWNERS
+++ b/chrome/app/OWNERS
@@ -1,7 +1,7 @@
cpu@chromium.org
-per-file address_input_strings.grd*=estade@chromium.org
-per-file address_input_strings.grd*=rouslan@chromium.org
+per-file address_input_strings*=estade@chromium.org
+per-file address_input_strings*=rouslan@chromium.org
per-file bookmarks_strings.grdp=*
per-file chromeos_strings.grdp=*
per-file chromium_strings.grd=*
diff --git a/chrome/app/address_input_strings.grd b/chrome/app/address_input_strings.grd
index d0f003d..a349d68 100644
--- a/chrome/app/address_input_strings.grd
+++ b/chrome/app/address_input_strings.grd
@@ -130,59 +130,7 @@
<!-- Chromium translations. -->
<translations>
- <file path="resources/address_input_strings_am.xtb" lang="am" />
- <file path="resources/address_input_strings_ar.xtb" lang="ar" />
- <file path="resources/address_input_strings_bg.xtb" lang="bg" />
- <file path="resources/address_input_strings_bn.xtb" lang="bn" />
- <file path="resources/address_input_strings_ca.xtb" lang="ca" />
- <file path="resources/address_input_strings_cs.xtb" lang="cs" />
- <file path="resources/address_input_strings_da.xtb" lang="da" />
- <file path="resources/address_input_strings_de.xtb" lang="de" />
- <file path="resources/address_input_strings_el.xtb" lang="el" />
- <file path="resources/address_input_strings_en-GB.xtb" lang="en-GB" />
- <file path="resources/address_input_strings_es.xtb" lang="es" />
- <file path="resources/address_input_strings_es-419.xtb" lang="es-419" />
- <file path="resources/address_input_strings_et.xtb" lang="et" />
- <file path="resources/address_input_strings_fa.xtb" lang="fa" />
- <file path="resources/address_input_strings_fi.xtb" lang="fi" />
- <file path="resources/address_input_strings_fil.xtb" lang="fil" />
- <file path="resources/address_input_strings_fr.xtb" lang="fr" />
- <file path="resources/address_input_strings_gu.xtb" lang="gu" />
- <file path="resources/address_input_strings_hi.xtb" lang="hi" />
- <file path="resources/address_input_strings_hr.xtb" lang="hr" />
- <file path="resources/address_input_strings_hu.xtb" lang="hu" />
- <file path="resources/address_input_strings_id.xtb" lang="id" />
- <file path="resources/address_input_strings_it.xtb" lang="it" />
- <!-- The translation console uses 'iw' for Hebrew, but we use 'he'. -->
- <file path="resources/address_input_strings_iw.xtb" lang="he" />
- <file path="resources/address_input_strings_ja.xtb" lang="ja" />
- <file path="resources/address_input_strings_kn.xtb" lang="kn" />
- <file path="resources/address_input_strings_ko.xtb" lang="ko" />
- <file path="resources/address_input_strings_lt.xtb" lang="lt" />
- <file path="resources/address_input_strings_lv.xtb" lang="lv" />
- <file path="resources/address_input_strings_ml.xtb" lang="ml" />
- <file path="resources/address_input_strings_mr.xtb" lang="mr" />
- <file path="resources/address_input_strings_ms.xtb" lang="ms" />
- <file path="resources/address_input_strings_nl.xtb" lang="nl" />
- <file path="resources/address_input_strings_no.xtb" lang="no" />
- <file path="resources/address_input_strings_pl.xtb" lang="pl" />
- <file path="resources/address_input_strings_pt-BR.xtb" lang="pt-BR" />
- <file path="resources/address_input_strings_pt-PT.xtb" lang="pt-PT" />
- <file path="resources/address_input_strings_ro.xtb" lang="ro" />
- <file path="resources/address_input_strings_ru.xtb" lang="ru" />
- <file path="resources/address_input_strings_sk.xtb" lang="sk" />
- <file path="resources/address_input_strings_sl.xtb" lang="sl" />
- <file path="resources/address_input_strings_sr.xtb" lang="sr" />
- <file path="resources/address_input_strings_sv.xtb" lang="sv" />
- <file path="resources/address_input_strings_sw.xtb" lang="sw" />
- <file path="resources/address_input_strings_ta.xtb" lang="ta" />
- <file path="resources/address_input_strings_te.xtb" lang="te" />
- <file path="resources/address_input_strings_th.xtb" lang="th" />
- <file path="resources/address_input_strings_tr.xtb" lang="tr" />
- <file path="resources/address_input_strings_uk.xtb" lang="uk" />
- <file path="resources/address_input_strings_vi.xtb" lang="vi" />
- <file path="resources/address_input_strings_zh-CN.xtb" lang="zh-CN" />
- <file path="resources/address_input_strings_zh-TW.xtb" lang="zh-TW" />
+ <part file="address_input_strings_translations.grdp" />
</translations>
<release seq="1" allow_pseudo="false">
<messages fallback_to_english="true">
diff --git a/chrome/app/address_input_strings_android.grd b/chrome/app/address_input_strings_android.grd
new file mode 100644
index 0000000..a428258
--- /dev/null
+++ b/chrome/app/address_input_strings_android.grd
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2014 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.
+-->
+<grit base_dir="." latest_public_release="0" current_release="1"
+ source_lang_id="en" enc_check="möl">
+ <outputs>
+ <!-- On Android, output all strings into Android's xml string format. -->
+ <output filename="values-am/address_input_strings.xml" lang="am" type="android" />
+ <output filename="values-ar/address_input_strings.xml" lang="ar" type="android" />
+ <output filename="values-bg/address_input_strings.xml" lang="bg" type="android" />
+ <output filename="values-ca/address_input_strings.xml" lang="ca" type="android" />
+ <output filename="values-cs/address_input_strings.xml" lang="cs" type="android" />
+ <output filename="values-da/address_input_strings.xml" lang="da" type="android" />
+ <output filename="values-de/address_input_strings.xml" lang="de" type="android" />
+ <output filename="values-el/address_input_strings.xml" lang="el" type="android" />
+ <output filename="values/address_input_strings.xml" lang="en" type="android" />
+ <output filename="values-en-rGB/address_input_strings.xml" lang="en-GB" type="android" />
+ <output filename="values-es/address_input_strings.xml" lang="es" type="android" />
+ <output filename="values-es-rUS/address_input_strings.xml" lang="es-419" type="android" />
+ <output filename="values-fa/address_input_strings.xml" lang="fa" type="android" />
+ <output filename="values-fi/address_input_strings.xml" lang="fi" type="android" />
+ <output filename="values-tl/address_input_strings.xml" lang="fil" type="android" />
+ <output filename="values-fr/address_input_strings.xml" lang="fr" type="android" />
+ <output filename="values-hi/address_input_strings.xml" lang="hi" type="android" />
+ <output filename="values-hr/address_input_strings.xml" lang="hr" type="android" />
+ <output filename="values-hu/address_input_strings.xml" lang="hu" type="android" />
+ <output filename="values-in/address_input_strings.xml" lang="id" type="android" />
+ <output filename="values-it/address_input_strings.xml" lang="it" type="android" />
+ <output filename="values-iw/address_input_strings.xml" lang="he" type="android" />
+ <output filename="values-ja/address_input_strings.xml" lang="ja" type="android" />
+ <output filename="values-ko/address_input_strings.xml" lang="ko" type="android" />
+ <output filename="values-lt/address_input_strings.xml" lang="lt" type="android" />
+ <output filename="values-lv/address_input_strings.xml" lang="lv" type="android" />
+ <output filename="values-nl/address_input_strings.xml" lang="nl" type="android" />
+ <output filename="values-nb/address_input_strings.xml" lang="no" type="android" />
+ <output filename="values-pl/address_input_strings.xml" lang="pl" type="android" />
+ <output filename="values-pt-rBR/address_input_strings.xml" lang="pt-BR" type="android" />
+ <output filename="values-pt-rPT/address_input_strings.xml" lang="pt-PT" type="android" />
+ <output filename="values-ro/address_input_strings.xml" lang="ro" type="android" />
+ <output filename="values-ru/address_input_strings.xml" lang="ru" type="android" />
+ <output filename="values-sk/address_input_strings.xml" lang="sk" type="android" />
+ <output filename="values-sl/address_input_strings.xml" lang="sl" type="android" />
+ <output filename="values-sr/address_input_strings.xml" lang="sr" type="android" />
+ <output filename="values-sv/address_input_strings.xml" lang="sv" type="android" />
+ <output filename="values-sw/address_input_strings.xml" lang="sw" type="android" />
+ <output filename="values-th/address_input_strings.xml" lang="th" type="android" />
+ <output filename="values-tr/address_input_strings.xml" lang="tr" type="android" />
+ <output filename="values-uk/address_input_strings.xml" lang="uk" type="android" />
+ <output filename="values-vi/address_input_strings.xml" lang="vi" type="android" />
+ <output filename="values-zh-rCN/address_input_strings.xml" lang="zh-CN" type="android" />
+ <output filename="values-zh-rTW/address_input_strings.xml" lang="zh-TW" type="android" />
+ </outputs>
+
+ <!-- Chromium translations. -->
+ <translations>
+ <part file="address_input_strings_translations.grdp" />
+ </translations>
+ <release seq="1" allow_pseudo="false">
+ <messages fallback_to_english="true">
+ <part file="address_input_strings.grdp" />
+ </messages>
+ </release>
+</grit>
diff --git a/chrome/app/address_input_strings_translations.grdp b/chrome/app/address_input_strings_translations.grdp
new file mode 100644
index 0000000..50605e6
--- /dev/null
+++ b/chrome/app/address_input_strings_translations.grdp
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2014 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.
+-->
+<grit-part>
+ <file path="resources/address_input_strings_am.xtb" lang="am" />
+ <file path="resources/address_input_strings_ar.xtb" lang="ar" />
+ <file path="resources/address_input_strings_bg.xtb" lang="bg" />
+ <file path="resources/address_input_strings_bn.xtb" lang="bn" />
+ <file path="resources/address_input_strings_ca.xtb" lang="ca" />
+ <file path="resources/address_input_strings_cs.xtb" lang="cs" />
+ <file path="resources/address_input_strings_da.xtb" lang="da" />
+ <file path="resources/address_input_strings_de.xtb" lang="de" />
+ <file path="resources/address_input_strings_el.xtb" lang="el" />
+ <file path="resources/address_input_strings_en-GB.xtb" lang="en-GB" />
+ <file path="resources/address_input_strings_es.xtb" lang="es" />
+ <file path="resources/address_input_strings_es-419.xtb" lang="es-419" />
+ <file path="resources/address_input_strings_et.xtb" lang="et" />
+ <file path="resources/address_input_strings_fa.xtb" lang="fa" />
+ <file path="resources/address_input_strings_fi.xtb" lang="fi" />
+ <file path="resources/address_input_strings_fil.xtb" lang="fil" />
+ <file path="resources/address_input_strings_fr.xtb" lang="fr" />
+ <file path="resources/address_input_strings_gu.xtb" lang="gu" />
+ <file path="resources/address_input_strings_hi.xtb" lang="hi" />
+ <file path="resources/address_input_strings_hr.xtb" lang="hr" />
+ <file path="resources/address_input_strings_hu.xtb" lang="hu" />
+ <file path="resources/address_input_strings_id.xtb" lang="id" />
+ <file path="resources/address_input_strings_it.xtb" lang="it" />
+ <!-- The translation console uses 'iw' for Hebrew, but we use 'he'. -->
+ <file path="resources/address_input_strings_iw.xtb" lang="he" />
+ <file path="resources/address_input_strings_ja.xtb" lang="ja" />
+ <file path="resources/address_input_strings_kn.xtb" lang="kn" />
+ <file path="resources/address_input_strings_ko.xtb" lang="ko" />
+ <file path="resources/address_input_strings_lt.xtb" lang="lt" />
+ <file path="resources/address_input_strings_lv.xtb" lang="lv" />
+ <file path="resources/address_input_strings_ml.xtb" lang="ml" />
+ <file path="resources/address_input_strings_mr.xtb" lang="mr" />
+ <file path="resources/address_input_strings_ms.xtb" lang="ms" />
+ <file path="resources/address_input_strings_nl.xtb" lang="nl" />
+ <file path="resources/address_input_strings_no.xtb" lang="no" />
+ <file path="resources/address_input_strings_pl.xtb" lang="pl" />
+ <file path="resources/address_input_strings_pt-BR.xtb" lang="pt-BR" />
+ <file path="resources/address_input_strings_pt-PT.xtb" lang="pt-PT" />
+ <file path="resources/address_input_strings_ro.xtb" lang="ro" />
+ <file path="resources/address_input_strings_ru.xtb" lang="ru" />
+ <file path="resources/address_input_strings_sk.xtb" lang="sk" />
+ <file path="resources/address_input_strings_sl.xtb" lang="sl" />
+ <file path="resources/address_input_strings_sr.xtb" lang="sr" />
+ <file path="resources/address_input_strings_sv.xtb" lang="sv" />
+ <file path="resources/address_input_strings_sw.xtb" lang="sw" />
+ <file path="resources/address_input_strings_ta.xtb" lang="ta" />
+ <file path="resources/address_input_strings_te.xtb" lang="te" />
+ <file path="resources/address_input_strings_th.xtb" lang="th" />
+ <file path="resources/address_input_strings_tr.xtb" lang="tr" />
+ <file path="resources/address_input_strings_uk.xtb" lang="uk" />
+ <file path="resources/address_input_strings_vi.xtb" lang="vi" />
+ <file path="resources/address_input_strings_zh-CN.xtb" lang="zh-CN" />
+ <file path="resources/address_input_strings_zh-TW.xtb" lang="zh-TW" />
+</grit-part>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 3db4e5d..fd4a367 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -8483,6 +8483,9 @@
<message name="IDS_PRINT_PREVIEW_DPI_LABEL" desc="Print quality option label. Provides user the option to select one of the print quality options defined for the printer.">
Quality
</message>
+ <message name="IDS_PRINT_PREVIEW_NON_ISOTROPIC_DPI_ITEM_LABEL" desc="Print quality option value text in case horizontal and vertical DPI values differ.">
+ <ph name="HORIZONTAL_DPI">$1<ex>200</ex></ph>x<ph name="VERTICAL_DPI">$2<ex>100</ex></ph> dpi
+ </message>
<message name="IDS_PRINT_PREVIEW_DPI_ITEM_LABEL" desc="Print quality option value text.">
<ph name="DPI">$1<ex>300</ex></ph> dpi
</message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 0b85a66..d2682f5 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -558,6 +558,12 @@
if (is_win) {
sources += rebase_path(gypi_values.chrome_browser_win_sources,
".", "//chrome")
+ if (!is_chrome_branded) {
+ sources -= [
+ "google/did_run_updater_win.cc",
+ "google/did_run_updater_win.h",
+ ]
+ }
public_deps += [
"//ui/views",
"//ui/views/controls/webview",
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc
index aabbb57..bcfcdec 100644
--- a/chrome/browser/android/chrome_jni_registrar.cc
+++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -49,6 +49,7 @@
#include "chrome/browser/invalidation/invalidation_service_factory_android.h"
#include "chrome/browser/lifetime/application_lifetime_android.h"
#include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h"
+#include "chrome/browser/notifications/notification_ui_manager_android.h"
#include "chrome/browser/prerender/external_prerender_handler_android.h"
#include "chrome/browser/profiles/profile_android.h"
#include "chrome/browser/search_engines/template_url_service_android.h"
@@ -169,6 +170,8 @@
{ "NavigationPopup", NavigationPopup::RegisterNavigationPopup },
{ "NewTabPagePrefs",
NewTabPagePrefs::RegisterNewTabPagePrefs },
+ { "NotificationUIManager",
+ NotificationUIManagerAndroid::RegisterNotificationUIManager },
{ "OmniboxPrerender", RegisterOmniboxPrerender },
{ "OmniboxViewUtil", OmniboxViewUtil::RegisterOmniboxViewUtil },
{ "PasswordGenerationPopup",
diff --git a/chrome/browser/android/preferences/pref_service_bridge.cc b/chrome/browser/android/preferences/pref_service_bridge.cc
index eb8c975..c067640 100644
--- a/chrome/browser/android/preferences/pref_service_bridge.cc
+++ b/chrome/browser/android/preferences/pref_service_bridge.cc
@@ -541,6 +541,11 @@
Release();
}
+static jboolean GetContextualSearchPreferenceIsManaged(JNIEnv* env,
+ jobject obj) {
+ return GetPrefService()->IsManagedPreference(prefs::kContextualSearchEnabled);
+}
+
static void SetContextualSearchPreference(JNIEnv* env, jobject obj,
jstring pref) {
GetPrefService()->SetString(prefs::kContextualSearchEnabled,
diff --git a/chrome/browser/android/provider/chrome_browser_provider.cc b/chrome/browser/android/provider/chrome_browser_provider.cc
index c3bd2d6..a62de40 100644
--- a/chrome/browser/android/provider/chrome_browser_provider.cc
+++ b/chrome/browser/android/provider/chrome_browser_provider.cc
@@ -650,10 +650,12 @@
// Base class for all asynchronous blocking tasks that use the favicon service.
class FaviconServiceTask : public AsyncServiceRequest<FaviconService> {
public:
- FaviconServiceTask(FaviconService* service,
- base::CancelableTaskTracker* cancelable_tracker,
+ FaviconServiceTask(base::CancelableTaskTracker* cancelable_tracker,
Profile* profile)
- : AsyncServiceRequest<FaviconService>(service, cancelable_tracker),
+ : AsyncServiceRequest<FaviconService>(
+ FaviconServiceFactory::GetForProfile(profile,
+ Profile::EXPLICIT_ACCESS),
+ cancelable_tracker),
profile_(profile) {}
Profile* profile() const { return profile_; }
@@ -667,15 +669,18 @@
// Retrieves the favicon or touch icon for a URL from the FaviconService.
class BookmarkIconFetchTask : public FaviconServiceTask {
public:
- BookmarkIconFetchTask(FaviconService* favicon_service,
- base::CancelableTaskTracker* cancelable_tracker,
+ BookmarkIconFetchTask(base::CancelableTaskTracker* cancelable_tracker,
Profile* profile)
- : FaviconServiceTask(favicon_service, cancelable_tracker, profile) {}
+ : FaviconServiceTask(cancelable_tracker, profile) {}
favicon_base::FaviconRawBitmapResult Run(const GURL& url) {
float max_scale = ui::GetScaleForScaleFactor(
ResourceBundle::GetSharedInstance().GetMaxScaleFactor());
int desired_size_in_pixel = std::ceil(gfx::kFaviconSize * max_scale);
+
+ if (service() == NULL)
+ return favicon_base::FaviconRawBitmapResult();
+
RunAsyncRequestOnUIThreadBlocking(
base::Bind(&FaviconService::GetRawFaviconForPageURL,
base::Unretained(service()),
@@ -1162,8 +1167,6 @@
bookmark_model_ = BookmarkModelFactory::GetForProfile(profile_);
top_sites_ = profile_->GetTopSites();
service_.reset(new AndroidHistoryProviderService(profile_));
- favicon_service_.reset(FaviconServiceFactory::GetForProfile(profile_,
- Profile::EXPLICIT_ACCESS));
// Registers the notifications we are interested.
bookmark_model_->AddObserver(this);
@@ -1550,8 +1553,7 @@
return ScopedJavaLocalRef<jbyteArray>();
GURL url = GURL(ConvertJavaStringToUTF16(env, jurl));
- BookmarkIconFetchTask favicon_task(
- favicon_service_.get(), &cancelable_task_tracker_, profile_);
+ BookmarkIconFetchTask favicon_task(&cancelable_task_tracker_, profile_);
favicon_base::FaviconRawBitmapResult bitmap_result = favicon_task.Run(url);
if (!bitmap_result.is_valid() || !bitmap_result.bitmap_data.get())
diff --git a/chrome/browser/android/provider/chrome_browser_provider.h b/chrome/browser/android/provider/chrome_browser_provider.h
index 13c65a4..f0e9661 100644
--- a/chrome/browser/android/provider/chrome_browser_provider.h
+++ b/chrome/browser/android/provider/chrome_browser_provider.h
@@ -209,7 +209,6 @@
history::TopSites* top_sites_;
scoped_ptr<AndroidHistoryProviderService> service_;
- scoped_ptr<FaviconService> favicon_service_;
base::CancelableTaskTracker cancelable_task_tracker_;
diff --git a/chrome/browser/android/resource_id.h b/chrome/browser/android/resource_id.h
index 4af0fbd..9a1aa9d 100644
--- a/chrome/browser/android/resource_id.h
+++ b/chrome/browser/android/resource_id.h
@@ -17,6 +17,9 @@
DEFINE_RESOURCE_ID(IDR_INFOBAR_AUTOFILL_CC, R.drawable.infobar_autofill_cc)
DEFINE_RESOURCE_ID(IDR_INFOBAR_AUTOLOGIN,\
R.drawable.infobar_savepassword_autologin)
+// TODO(peter): Include the proper resources for the Notification infobar.
+DEFINE_RESOURCE_ID(IDR_INFOBAR_DESKTOP_NOTIFICATIONS,\
+ R.drawable.infobar_geolocation)
DEFINE_RESOURCE_ID(IDR_INFOBAR_GEOLOCATION, R.drawable.infobar_geolocation)
DEFINE_RESOURCE_ID(IDR_INFOBAR_MEDIA_STREAM_CAMERA, R.drawable.infobar_camera)
DEFINE_RESOURCE_ID(IDR_INFOBAR_MEDIA_STREAM_MIC, R.drawable.infobar_microphone)
diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc
index b5dec4f..f49471e 100644
--- a/chrome/browser/android/tab_android.cc
+++ b/chrome/browser/android/tab_android.cc
@@ -38,6 +38,7 @@
#include "chrome/browser/ui/search/search_tab_helper.h"
#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
#include "chrome/browser/ui/tab_helpers.h"
+#include "chrome/common/instant_types.h"
#include "chrome/common/url_constants.h"
#include "components/google/core/browser/google_url_tracker.h"
#include "components/google/core/browser/google_util.h"
@@ -377,18 +378,13 @@
}
void TabAndroid::OnFaviconAvailable(const gfx::Image& image) {
- ScopedJavaLocalRef<jobject> bitmap;
- SkBitmap favicon = image
- .AsImageSkia()
- .GetRepresentation(
- ResourceBundle::GetSharedInstance().GetMaxScaleFactor())
- .sk_bitmap();
+ SkBitmap favicon = image.AsImageSkia().GetRepresentation(1.0f).sk_bitmap();
+ if (favicon.empty())
+ return;
- if (!favicon.empty()) {
- bitmap = gfx::ConvertToJavaBitmap(&favicon);
- }
- JNIEnv* env = base::android::AttachCurrentThread();
- Java_Tab_onFaviconAvailable(env, weak_java_tab_.get(env).obj(), bitmap.obj());
+ JNIEnv *env = base::android::AttachCurrentThread();
+ Java_Tab_onFaviconAvailable(env, weak_java_tab_.get(env).obj(),
+ gfx::ConvertToJavaBitmap(&favicon).obj());
}
void TabAndroid::Destroy(JNIEnv* env, jobject obj) {
@@ -536,7 +532,8 @@
chrome::ExtractSearchTermsFromURL(GetProfile(), gurl);
if (!search_terms.empty() &&
prerenderer->CanCommitQuery(web_contents_.get(), search_terms)) {
- prerenderer->Commit(search_terms);
+ EmbeddedSearchRequestParams request_params(gurl);
+ prerenderer->Commit(search_terms, request_params);
if (prerenderer->UsePrerenderedPage(gurl, ¶ms))
return FULL_PRERENDERED_PAGE_LOAD;
@@ -602,7 +599,8 @@
SearchTabHelper::FromWebContents(web_contents_.get());
if (!search_terms.empty() && search_tab_helper &&
search_tab_helper->SupportsInstant()) {
- search_tab_helper->Submit(search_terms);
+ EmbeddedSearchRequestParams request_params(gurl);
+ search_tab_helper->Submit(search_terms, request_params);
return DEFAULT_PAGE_LOAD;
}
load_params.is_renderer_initiated = is_renderer_initiated;
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc
index aa39454..7ab56c5 100644
--- a/chrome/browser/chrome_browser_main_win.cc
+++ b/chrome/browser/chrome_browser_main_win.cc
@@ -59,6 +59,10 @@
#include "ui/gfx/switches.h"
#include "ui/strings/grit/app_locale_settings.h"
+#if defined(GOOGLE_CHROME_BUILD)
+#include "chrome/browser/google/did_run_updater_win.h"
+#endif
+
namespace {
typedef HRESULT (STDAPICALLTYPE* RegisterApplicationRestartProc)(
@@ -262,6 +266,10 @@
// TODO(erikwright): Remove this and the implementation of the experiment by
// September 2014.
InitializeDisableTerminateOnHeapCorruptionExperiment();
+
+#if defined(GOOGLE_CHROME_BUILD)
+ did_run_updater_.reset(new DidRunUpdater);
+#endif
}
// static
diff --git a/chrome/browser/chrome_browser_main_win.h b/chrome/browser/chrome_browser_main_win.h
index 573c1e1..3b3ea04 100644
--- a/chrome/browser/chrome_browser_main_win.h
+++ b/chrome/browser/chrome_browser_main_win.h
@@ -9,6 +9,8 @@
#include "chrome/browser/chrome_browser_main.h"
+class DidRunUpdater;
+
namespace base {
class CommandLine;
}
@@ -63,6 +65,10 @@
static void SetupInstallerUtilStrings();
private:
+#if defined(GOOGLE_CHROME_BUILD)
+ scoped_ptr<DidRunUpdater> did_run_updater_;
+#endif
+
DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainPartsWin);
};
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
index ae22c0c..f087837 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
@@ -23,6 +23,8 @@
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chromeos/chromeos_switches.h"
+#include "chromeos/network/network_handler.h"
+#include "chromeos/network/network_state_handler.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_manager.h"
#include "content/public/browser/browser_thread.h"
@@ -811,6 +813,10 @@
break;
}
+ result.has_cellular_network_access =
+ chromeos::NetworkHandler::Get()
+ ->network_state_handler()
+ ->FirstNetworkByType(chromeos::NetworkTypePattern::Mobile());
results_ = api::file_manager_private::GetDriveConnectionState::Results::
Create(result);
diff --git a/chrome/browser/chromeos/input_method/input_method_util.cc b/chrome/browser/chromeos/input_method/input_method_util.cc
index b776986..a0db58b 100644
--- a/chrome/browser/chromeos/input_method/input_method_util.cc
+++ b/chrome/browser/chromeos/input_method/input_method_util.cc
@@ -527,15 +527,17 @@
if (IsLoginKeyboard(hardware_layouts_[i]))
hardware_login_layouts_.push_back(hardware_layouts_[i]);
}
- if (hardware_layouts_.empty()) {
- // This is totally fine if it's empty. The hardware keyboard layout is
- // not stored if startup_manifest.json (OEM customization data) is not
- // present (ex. Cr48 doen't have that file).
- hardware_layouts_.push_back(GetFallbackInputMethodDescriptor().id());
- }
- if (hardware_login_layouts_.empty())
- hardware_login_layouts_.push_back(GetFallbackInputMethodDescriptor().id());
+ if (hardware_login_layouts_.empty()) {
+ // This is totally fine if |hardware_layouts_| is empty. The hardware
+ // keyboard layout is not stored if startup_manifest.json
+ // (OEM customization data) is not present (ex. Cr48 doen't have that file).
+ // So need to make sure |hardware_login_layouts_| is not empty, and
+ // |hardware_layouts_| contains at least one login layout.
+ std::string fallback_id = GetFallbackInputMethodDescriptor().id();
+ hardware_layouts_.insert(hardware_layouts_.begin(), fallback_id);
+ hardware_login_layouts_.push_back(fallback_id);
+ }
}
void InputMethodUtil::SetHardwareKeyboardLayoutForTesting(
diff --git a/chrome/browser/chromeos/input_method/input_method_util_unittest.cc b/chrome/browser/chromeos/input_method/input_method_util_unittest.cc
index 97b51b6..9f001b7 100644
--- a/chrome/browser/chromeos/input_method/input_method_util_unittest.cc
+++ b/chrome/browser/chromeos/input_method/input_method_util_unittest.cc
@@ -481,5 +481,23 @@
}
}
+// Test getting hardware input method IDs.
+TEST_F(InputMethodUtilTest, TestHardwareInputMethodIDs) {
+ util_.SetHardwareKeyboardLayoutForTesting("xkb:ru::rus");
+ std::vector<std::string> input_method_ids = util_.GetHardwareInputMethodIds();
+ std::vector<std::string> login_input_method_ids =
+ util_.GetHardwareLoginInputMethodIds();
+
+ EXPECT_EQ(2U, input_method_ids.size());
+ EXPECT_EQ(1U, login_input_method_ids.size());
+
+ EXPECT_EQ("xkb:us::eng", extension_ime_util::GetComponentIDByInputMethodID(
+ input_method_ids[0]));
+ EXPECT_EQ("xkb:ru::rus", extension_ime_util::GetComponentIDByInputMethodID(
+ input_method_ids[1]));
+ EXPECT_EQ("xkb:us::eng", extension_ime_util::GetComponentIDByInputMethodID(
+ login_input_method_ids[0]));
+}
+
} // namespace input_method
} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
index 15371f2..44e8402 100644
--- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc
+++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -463,8 +463,7 @@
}
// Tests the sign-in flow when the credentials passing API is used.
-// Disabled for flakiness/failing: https://crbug.com/430373
-IN_PROC_BROWSER_TEST_F(SamlTest, DISABLED_CredentialPassingAPI) {
+IN_PROC_BROWSER_TEST_F(SamlTest, CredentialPassingAPI) {
fake_saml_idp()->SetLoginHTMLTemplate("saml_api_login.html");
fake_saml_idp()->SetLoginAuthHTMLTemplate("saml_api_login_auth.html");
StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.cc b/chrome/browser/content_settings/tab_specific_content_settings.cc
index c4c7d8a..d15e385 100644
--- a/chrome/browser/content_settings/tab_specific_content_settings.cc
+++ b/chrome/browser/content_settings/tab_specific_content_settings.cc
@@ -511,7 +511,19 @@
TabSpecificContentSettings::MicrophoneCameraState
TabSpecificContentSettings::GetMicrophoneCameraState() const {
- return microphone_camera_state_;
+ MicrophoneCameraState state = microphone_camera_state_;
+
+ // Include capture devices in the state if there are still consumers of the
+ // approved media stream.
+ scoped_refptr<MediaStreamCaptureIndicator> media_indicator =
+ MediaCaptureDevicesDispatcher::GetInstance()->
+ GetMediaStreamCaptureIndicator();
+ if (media_indicator->IsCapturingAudio(web_contents()))
+ state |= MICROPHONE_ACCESSED;
+ if (media_indicator->IsCapturingVideo(web_contents()))
+ state |= CAMERA_ACCESSED;
+
+ return state;
}
bool TabSpecificContentSettings::IsMicrophoneCameraStateChanged() const {
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.h b/chrome/browser/content_settings/tab_specific_content_settings.h
index 063b525..707bacf 100644
--- a/chrome/browser/content_settings/tab_specific_content_settings.h
+++ b/chrome/browser/content_settings/tab_specific_content_settings.h
@@ -228,10 +228,12 @@
}
// Returns the state of the camera and microphone usage.
+ // The return value always includes all active media capture devices, on top
+ // of the devices from the last request.
MicrophoneCameraState GetMicrophoneCameraState() const;
- // Returns whether the state of the camera and microphone usage or device has
- // changed.
+ // Returns whether the camera or microphone permission or media device setting
+ // has changed since the last permission request.
bool IsMicrophoneCameraStateChanged() const;
// Returns the ContentSettingsUsagesState that controls the
diff --git a/chrome/browser/devtools/device/usb/android_usb_device.cc b/chrome/browser/devtools/device/usb/android_usb_device.cc
index 0820fac..7265654 100644
--- a/chrome/browser/devtools/device/usb/android_usb_device.cc
+++ b/chrome/browser/devtools/device/usb/android_usb_device.cc
@@ -72,6 +72,7 @@
scoped_refptr<AndroidUsbDevice> ClaimInterface(
crypto::RSAPrivateKey* rsa_key,
scoped_refptr<UsbDeviceHandle> usb_handle,
+ const base::string16& serial,
const UsbInterfaceDescriptor& interface) {
int inbound_address = 0;
int outbound_address = 0;
@@ -95,10 +96,6 @@
if (!usb_handle->ClaimInterface(interface.interface_number))
return NULL;
- base::string16 serial;
- if (!usb_handle->GetDevice()->GetSerialNumber(&serial) || serial.empty())
- return NULL;
-
return new AndroidUsbDevice(rsa_key,
usb_handle,
base::UTF16ToASCII(serial),
@@ -201,15 +198,19 @@
bool success) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
if (success) {
- const UsbConfigDescriptor& config = device->GetConfiguration();
- scoped_refptr<UsbDeviceHandle> usb_handle = device->Open();
- if (usb_handle.get()) {
- scoped_refptr<AndroidUsbDevice> android_device =
- ClaimInterface(rsa_key, usb_handle, config.interfaces[interface_id]);
- if (android_device.get())
- devices->push_back(android_device.get());
- else
- usb_handle->Close();
+ base::string16 serial;
+ if (device->GetSerialNumber(&serial) && !serial.empty()) {
+ const UsbConfigDescriptor& config = device->GetConfiguration();
+ scoped_refptr<UsbDeviceHandle> usb_handle = device->Open();
+ if (usb_handle.get()) {
+ scoped_refptr<AndroidUsbDevice> android_device =
+ ClaimInterface(rsa_key, usb_handle, serial,
+ config.interfaces[interface_id]);
+ if (android_device.get())
+ devices->push_back(android_device.get());
+ else
+ usb_handle->Close();
+ }
}
}
barrier.Run();
diff --git a/chrome/browser/extensions/api/identity/identity_api.cc b/chrome/browser/extensions/api/identity/identity_api.cc
index e5d434d..b00c414 100644
--- a/chrome/browser/extensions/api/identity/identity_api.cc
+++ b/chrome/browser/extensions/api/identity/identity_api.cc
@@ -20,6 +20,7 @@
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/chrome_signin_client_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
@@ -785,6 +786,10 @@
}
OAuth2MintTokenFlow* IdentityGetAuthTokenFunction::CreateMintTokenFlow() {
+ SigninClient* signin_client =
+ ChromeSigninClientFactory::GetForProfile(GetProfile());
+ std::string signin_scoped_device_id =
+ signin_client->GetSigninScopedDeviceId();
OAuth2MintTokenFlow* mint_token_flow = new OAuth2MintTokenFlow(
this,
OAuth2MintTokenFlow::Parameters(
@@ -792,6 +797,7 @@
oauth2_client_id_,
std::vector<std::string>(token_key_->scopes.begin(),
token_key_->scopes.end()),
+ signin_scoped_device_id,
gaia_mint_token_mode_));
return mint_token_flow;
}
diff --git a/chrome/browser/extensions/updater/extension_updater_unittest.cc b/chrome/browser/extensions/updater/extension_updater_unittest.cc
index 0d9b6d4..4fe3953 100644
--- a/chrome/browser/extensions/updater/extension_updater_unittest.cc
+++ b/chrome/browser/extensions/updater/extension_updater_unittest.cc
@@ -1687,39 +1687,49 @@
// The urls could have been fetched in either order, so use the host to
// tell them apart and note the query each used.
+ GURL url1_fetch_url;
+ GURL url2_fetch_url;
std::string url1_query;
std::string url2_query;
if (fetched_urls[0].host() == url1.host()) {
+ url1_fetch_url = fetched_urls[0];
+ url2_fetch_url = fetched_urls[1];
+
url1_query = fetched_urls[0].query();
url2_query = fetched_urls[1].query();
} else if (fetched_urls[0].host() == url2.host()) {
+ url1_fetch_url = fetched_urls[1];
+ url2_fetch_url = fetched_urls[0];
url1_query = fetched_urls[1].query();
url2_query = fetched_urls[0].query();
} else {
NOTREACHED();
}
+ std::map<std::string, ParamsMap> url1_ping_data =
+ GetPingDataFromURL(url1_fetch_url);
+ ParamsMap url1_params = ParamsMap();
+ if (!url1_ping_data.empty() && ContainsKey(url1_ping_data, id))
+ url1_params = url1_ping_data[id];
+
// First make sure the non-google query had no ping parameter.
- std::string search_string = "ping%3D";
- EXPECT_TRUE(url2_query.find(search_string) == std::string::npos);
+ EXPECT_TRUE(GetPingDataFromURL(url2_fetch_url).empty());
// Now make sure the google query had the correct ping parameter.
- bool ping_expected = false;
bool did_rollcall = false;
if (rollcall_ping_days != 0) {
- search_string += "r%253D" + base::IntToString(rollcall_ping_days);
+ ASSERT_TRUE(ContainsKey(url1_params, "r"));
+ ASSERT_EQ(1u, url1_params["r"].size());
+ EXPECT_EQ(base::IntToString(rollcall_ping_days),
+ *url1_params["r"].begin());
did_rollcall = true;
- ping_expected = true;
}
- if (active_bit && active_ping_days != 0) {
- if (did_rollcall)
- search_string += "%2526";
- search_string += "a%253D" + base::IntToString(active_ping_days);
- ping_expected = true;
+ if (active_bit && active_ping_days != 0 && did_rollcall) {
+ ASSERT_TRUE(ContainsKey(url1_params, "a"));
+ ASSERT_EQ(1u, url1_params["a"].size());
+ EXPECT_EQ(base::IntToString(active_ping_days),
+ *url1_params["a"].begin());
}
- bool ping_found = url1_query.find(search_string) != std::string::npos;
- EXPECT_EQ(ping_expected, ping_found) << "query was: " << url1_query
- << " was looking for " << search_string;
// Make sure the non-google query has no brand parameter.
const std::string brand_string = "brand%3D";
@@ -1787,14 +1797,10 @@
// This lets us run a test with some enabled and some disabled
// extensions. The |num_enabled| value specifies how many enabled extensions
// to have, and |disabled| is a vector of DisableReason bitmasks for each
- // disabled extension we want. |enable_metrics| specifies whether we should
- // have enabled/disable reason information in the ping parameter.
- void TestPingMetrics(bool enable_metrics,
- int num_enabled,
+ // disabled extension we want.
+ void TestPingMetrics(int num_enabled,
const std::vector<int>& disabled) {
ServiceForManifestTests service(prefs_.get());
- service.set_enable_metrics(enable_metrics);
-
ExtensionList enabled_extensions;
ExtensionList disabled_extensions;
@@ -1849,16 +1855,10 @@
std::map<std::string, ParamsMap> all_pings = GetPingDataFromURL(url);
// Make sure that all the enabled extensions have "e=1" in their ping
- // parameter if metrics are turned on, or don't have it if metrics are
- // off.
+ // parameter.
for (const auto& ext : enabled_extensions) {
ASSERT_TRUE(ContainsKey(all_pings, ext->id()));
ParamsMap& ping = all_pings[ext->id()];
- if (!enable_metrics) {
- EXPECT_FALSE(ContainsKey(ping, "e"));
- EXPECT_FALSE(ContainsKey(ping, "dr"));
- continue;
- }
EXPECT_FALSE(ContainsKey(ping, "dr"));
ASSERT_TRUE(ContainsKey(ping, "e")) << url;
std::set<std::string> e = ping["e"];
@@ -1877,11 +1877,6 @@
ASSERT_TRUE(ContainsKey(all_pings, ext->id())) << url;
ParamsMap& ping = all_pings[ext->id()];
- if (!enable_metrics) {
- EXPECT_FALSE(ContainsKey(ping, "e"));
- EXPECT_FALSE(ContainsKey(ping, "dr"));
- continue;
- }
ASSERT_TRUE(ContainsKey(ping, "e")) << url;
std::set<std::string> e = ping["e"];
ASSERT_EQ(1u, e.size()) << url;
@@ -2238,21 +2233,18 @@
disabled.push_back(Extension::DISABLE_USER_ACTION);
disabled.push_back(Extension::DISABLE_PERMISSIONS_INCREASE |
Extension::DISABLE_CORRUPTED);
- TestPingMetrics(true, 1, disabled);
- TestPingMetrics(false, 1, disabled);
+ TestPingMetrics(1, disabled);
}
TEST_F(ExtensionUpdaterTest, TestDisabledReasons2) {
std::vector<int> disabled;
- TestPingMetrics(true, 1, disabled);
- TestPingMetrics(false, 1, disabled);
+ TestPingMetrics(1, disabled);
}
TEST_F(ExtensionUpdaterTest, TestDisabledReasons3) {
std::vector<int> disabled;
disabled.push_back(0);
- TestPingMetrics(true, 0, disabled);
- TestPingMetrics(false, 0, disabled);
+ TestPingMetrics(0, disabled);
}
// TODO(asargent) - (http://crbug.com/12780) add tests for:
diff --git a/chrome/browser/google/did_run_updater_win.cc b/chrome/browser/google/did_run_updater_win.cc
new file mode 100644
index 0000000..b409fd0
--- /dev/null
+++ b/chrome/browser/google/did_run_updater_win.cc
@@ -0,0 +1,33 @@
+// Copyright 2014 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.
+
+#include "chrome/browser/google/did_run_updater_win.h"
+
+#include "base/base_paths.h"
+#include "base/files/file_path.h"
+#include "base/path_service.h"
+#include "chrome/installer/util/google_update_settings.h"
+#include "chrome/installer/util/install_util.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_source.h"
+#include "content/public/browser/notification_types.h"
+
+DidRunUpdater::DidRunUpdater() : system_level_(false) {
+ base::FilePath exe_path;
+ if (PathService::Get(base::FILE_EXE, &exe_path))
+ system_level_ = !InstallUtil::IsPerUserInstall(exe_path.value().c_str());
+
+ registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED,
+ content::NotificationService::AllSources());
+}
+
+DidRunUpdater::~DidRunUpdater() {
+}
+
+void DidRunUpdater::Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ GoogleUpdateSettings::UpdateDidRunState(true, system_level_);
+}
diff --git a/chrome/browser/google/did_run_updater_win.h b/chrome/browser/google/did_run_updater_win.h
new file mode 100644
index 0000000..5fb8a6e
--- /dev/null
+++ b/chrome/browser/google/did_run_updater_win.h
@@ -0,0 +1,32 @@
+// Copyright 2014 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.
+
+#ifndef CHROME_BROWSER_GOOGLE_DID_RUN_UPDATER_WIN_H_
+#define CHROME_BROWSER_GOOGLE_DID_RUN_UPDATER_WIN_H_
+
+#include "base/macros.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+
+// Updates Chrome's "did run" state periodically when the process is in use.
+// The creation of renderers is used as a proxy for "is the browser in use."
+class DidRunUpdater : public content::NotificationObserver {
+ public:
+ DidRunUpdater();
+ ~DidRunUpdater() override;
+
+ private:
+ // content::NotificationObserver:
+ void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) override;
+
+ // True if the process is running from a system-level installation.
+ bool system_level_;
+ content::NotificationRegistrar registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(DidRunUpdater);
+};
+
+#endif // CHROME_BROWSER_GOOGLE_DID_RUN_UPDATER_WIN_H_
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 24064c6..4ead3fc 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -848,7 +848,7 @@
globals->use_alternate_protocols.set(true);
} else if (spdy_trial_group.starts_with(
kSpdyFieldTrialSpdy31GroupNamePrefix)) {
- globals->next_protos = net::NextProtosSpdy4Http2();
+ globals->next_protos = net::NextProtosSpdy31();
globals->use_alternate_protocols.set(true);
} else if (spdy_trial_group.starts_with(
kSpdyFieldTrialSpdy4GroupNamePrefix)) {
diff --git a/chrome/browser/media/media_stream_devices_controller_browsertest.cc b/chrome/browser/media/media_stream_devices_controller_browsertest.cc
index b12c1b7..57fc46e 100644
--- a/chrome/browser/media/media_stream_devices_controller_browsertest.cc
+++ b/chrome/browser/media/media_stream_devices_controller_browsertest.cc
@@ -7,6 +7,8 @@
#include "base/bind.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
+#include "chrome/browser/media/media_capture_devices_dispatcher.h"
+#include "chrome/browser/media/media_stream_capture_indicator.h"
#include "chrome/browser/media/media_stream_device_permissions.h"
#include "chrome/browser/media/media_stream_devices_controller.h"
#include "chrome/browser/media/webrtc_browsertest_base.h"
@@ -396,3 +398,75 @@
EXPECT_EQ(example_audio_id(),
GetContentSettings()->media_stream_selected_audio_device());
}
+
+// Denying mic access after camera access should still show the camera as state.
+IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest,
+ DenyMicDoesNotChangeCam) {
+ // Request cam and allow
+ SetDevicePolicy(DEVICE_TYPE_VIDEO, ACCESS_ALLOWED);
+ MediaStreamDevicesController cam_controller(
+ GetWebContents(),
+ CreateRequest(std::string(), example_video_id()),
+ base::Bind(&OnMediaStreamResponse));
+ NotifyTabSpecificContentSettings(&cam_controller);
+ EXPECT_TRUE(GetContentSettings()->IsContentAllowed(
+ CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA));
+ EXPECT_FALSE(GetContentSettings()->IsContentBlocked(
+ CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA));
+ EXPECT_EQ(example_video_id(),
+ GetContentSettings()->media_stream_requested_video_device());
+ EXPECT_EQ(example_video_id(),
+ GetContentSettings()->media_stream_selected_video_device());
+ EXPECT_EQ(TabSpecificContentSettings::CAMERA_ACCESSED,
+ GetContentSettings()->GetMicrophoneCameraState());
+
+ // Simulate that an a video stream is now being captured.
+ content::MediaStreamDevice fake_video_device(
+ content::MEDIA_DEVICE_VIDEO_CAPTURE, example_video_id(),
+ example_video_id());
+ content::MediaStreamDevices video_devices(1, fake_video_device);
+ MediaCaptureDevicesDispatcher* dispatcher =
+ MediaCaptureDevicesDispatcher::GetInstance();
+ dispatcher->SetTestVideoCaptureDevices(video_devices);
+ scoped_ptr<content::MediaStreamUI> video_stream_ui =
+ dispatcher->GetMediaStreamCaptureIndicator()->
+ RegisterMediaStream(GetWebContents(), video_devices);
+ video_stream_ui->OnStarted(base::Closure());
+
+ // Request mic and deny.
+ SetDevicePolicy(DEVICE_TYPE_AUDIO, ACCESS_DENIED);
+ MediaStreamDevicesController mic_controller(
+ GetWebContents(),
+ CreateRequest(example_audio_id(), std::string()),
+ base::Bind(&OnMediaStreamResponse));
+ NotifyTabSpecificContentSettings(&mic_controller);
+ EXPECT_FALSE(GetContentSettings()->IsContentAllowed(
+ CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC));
+ EXPECT_TRUE(GetContentSettings()->IsContentBlocked(
+ CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC));
+ EXPECT_EQ(example_audio_id(),
+ GetContentSettings()->media_stream_requested_audio_device());
+ EXPECT_EQ(example_audio_id(),
+ GetContentSettings()->media_stream_selected_audio_device());
+
+ // Cam should still be included in the state.
+ EXPECT_TRUE(GetContentSettings()->IsContentAllowed(
+ CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA));
+ EXPECT_FALSE(GetContentSettings()->IsContentBlocked(
+ CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA));
+ EXPECT_EQ(example_video_id(),
+ GetContentSettings()->media_stream_requested_video_device());
+ EXPECT_EQ(example_video_id(),
+ GetContentSettings()->media_stream_selected_video_device());
+ EXPECT_EQ(TabSpecificContentSettings::MICROPHONE_ACCESSED |
+ TabSpecificContentSettings::MICROPHONE_BLOCKED |
+ TabSpecificContentSettings::CAMERA_ACCESSED,
+ GetContentSettings()->GetMicrophoneCameraState());
+
+ // After ending the camera capture, the camera permission is no longer
+ // relevant, so it should no be included in the mic/cam state.
+ video_stream_ui.reset();
+ EXPECT_EQ(TabSpecificContentSettings::MICROPHONE_ACCESSED |
+ TabSpecificContentSettings::MICROPHONE_BLOCKED,
+ GetContentSettings()->GetMicrophoneCameraState());
+}
diff --git a/chrome/browser/metrics/metrics_reporting_state.cc b/chrome/browser/metrics/metrics_reporting_state.cc
index 07dfdae..a4a61fe 100644
--- a/chrome/browser/metrics/metrics_reporting_state.cc
+++ b/chrome/browser/metrics/metrics_reporting_state.cc
@@ -62,6 +62,12 @@
g_browser_process->local_state()->SetBoolean(
prefs::kMetricsReportingEnabled, updated_pref);
#endif
+ // When a user opts in to the metrics reporting service, the previously
+ // collected data should be cleared to ensure that nothing is reported before
+ // a user opts in and all reported data is accurate.
+ if (updated_pref && metrics)
+ metrics->ClearSavedStabilityMetrics();
+
if (to_update_pref == updated_pref) {
RecordMetricsReportingHistogramValue(updated_pref ?
METRICS_REPORTING_ENABLED : METRICS_REPORTING_DISABLED);
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc
index f2e1d77..e9c0892 100644
--- a/chrome/browser/net/chrome_network_delegate.cc
+++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -326,9 +326,9 @@
// static
// TODO(megjablon): Use data_reduction_proxy_delayed_pref_service to read prefs.
// Until updated the pref values may be up to an hour behind on desktop.
-base::Value* ChromeNetworkDelegate::HistoricNetworkStatsInfoToValue() {
+base::Value* ChromeNetworkDelegate::HistoricNetworkStatsInfoToValue(
+ PrefService* prefs) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- PrefService* prefs = g_browser_process->local_state();
int64 total_received = prefs->GetInt64(
data_reduction_proxy::prefs::kHttpReceivedContentLength);
int64 total_original = prefs->GetInt64(
diff --git a/chrome/browser/net/chrome_network_delegate.h b/chrome/browser/net/chrome_network_delegate.h
index 8e5b7de..8a13b1e 100644
--- a/chrome/browser/net/chrome_network_delegate.h
+++ b/chrome/browser/net/chrome_network_delegate.h
@@ -209,7 +209,7 @@
// Creates a Value summary of the persistent state of the network session.
// The caller is responsible for deleting the returned value.
// Must be called on the UI thread.
- static base::Value* HistoricNetworkStatsInfoToValue();
+ static base::Value* HistoricNetworkStatsInfoToValue(PrefService* prefs);
// Creates a Value summary of the state of the network session. The caller is
// responsible for deleting the returned value.
diff --git a/chrome/browser/notifications/notification_ui_manager_android.cc b/chrome/browser/notifications/notification_ui_manager_android.cc
index b440197..a11aaf1 100644
--- a/chrome/browser/notifications/notification_ui_manager_android.cc
+++ b/chrome/browser/notifications/notification_ui_manager_android.cc
@@ -4,9 +4,18 @@
#include "chrome/browser/notifications/notification_ui_manager_android.h"
+#include "base/android/jni_string.h"
#include "base/logging.h"
#include "base/strings/string16.h"
#include "chrome/browser/notifications/profile_notification.h"
+#include "jni/NotificationUIManager_jni.h"
+#include "ui/gfx/android/java_bitmap.h"
+#include "ui/gfx/image/image.h"
+
+using base::android::AttachCurrentThread;
+using base::android::ConvertJavaStringToUTF8;
+using base::android::ConvertUTF16ToJavaString;
+using base::android::ConvertUTF8ToJavaString;
// static
NotificationUIManager* NotificationUIManager::Create(PrefService* local_state) {
@@ -14,9 +23,37 @@
}
NotificationUIManagerAndroid::NotificationUIManagerAndroid() {
+ java_object_.Reset(
+ Java_NotificationUIManager_create(
+ AttachCurrentThread(),
+ reinterpret_cast<intptr_t>(this),
+ base::android::GetApplicationContext()));
}
-NotificationUIManagerAndroid::~NotificationUIManagerAndroid() {
+NotificationUIManagerAndroid::~NotificationUIManagerAndroid() {}
+
+void NotificationUIManagerAndroid::OnNotificationClicked(
+ JNIEnv* env, jobject java_object, jstring notification_id) {
+ std::string id = ConvertJavaStringToUTF8(env, notification_id);
+
+ auto iter = profile_notifications_.find(id);
+ if (iter == profile_notifications_.end())
+ return;
+
+ const Notification& notification = iter->second->notification();
+ notification.delegate()->Click();
+}
+
+void NotificationUIManagerAndroid::OnNotificationClosed(
+ JNIEnv* env, jobject java_object, jstring notification_id) {
+ std::string id = ConvertJavaStringToUTF8(env, notification_id);
+
+ auto iter = profile_notifications_.find(id);
+ if (iter == profile_notifications_.end())
+ return;
+
+ const Notification& notification = iter->second->notification();
+ notification.delegate()->Close(true /** by_user **/);
}
void NotificationUIManagerAndroid::Add(const Notification& notification,
@@ -30,7 +67,25 @@
// Takes ownership of |profile_notification|.
AddProfileNotification(profile_notification);
- // TODO(peter): Display the notification on the Android system.
+ JNIEnv* env = AttachCurrentThread();
+
+ ScopedJavaLocalRef<jstring> id = ConvertUTF8ToJavaString(
+ env, profile_notification->notification().id());
+ ScopedJavaLocalRef<jstring> title = ConvertUTF16ToJavaString(
+ env, notification.title());
+ ScopedJavaLocalRef<jstring> body = ConvertUTF16ToJavaString(
+ env, notification.message());
+
+ SkBitmap icon_bitmap = notification.icon().AsBitmap();
+ ScopedJavaLocalRef<jobject> icon = gfx::ConvertToJavaBitmap(&icon_bitmap);
+
+ int platform_id = Java_NotificationUIManager_displayNotification(
+ env, java_object_.obj(), id.obj(), title.obj(), body.obj(), icon.obj());
+
+ std::string notification_id = profile_notification->notification().id();
+ platform_notifications_[notification_id] = platform_id;
+
+ notification.delegate()->Display();
}
bool NotificationUIManagerAndroid::Update(const Notification& notification,
@@ -152,9 +207,24 @@
profile_notifications_.clear();
}
+bool NotificationUIManagerAndroid::RegisterNotificationUIManager(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
void NotificationUIManagerAndroid::PlatformCloseNotification(
- ProfileNotification* notification) const {
- // TODO(peter): Remove the notification from the Android system.
+ ProfileNotification* profile_notification) {
+ std::string id = profile_notification->notification().id();
+
+ auto iterator = platform_notifications_.find(id);
+ if (iterator == platform_notifications_.end())
+ return;
+
+ int platform_id = iterator->second;
+ platform_notifications_.erase(id);
+
+ Java_NotificationUIManager_closeNotification(AttachCurrentThread(),
+ java_object_.obj(),
+ platform_id);
}
void NotificationUIManagerAndroid::AddProfileNotification(
@@ -184,3 +254,4 @@
return iter->second;
}
+
diff --git a/chrome/browser/notifications/notification_ui_manager_android.h b/chrome/browser/notifications/notification_ui_manager_android.h
index 7d37e24..d9f7f36 100644
--- a/chrome/browser/notifications/notification_ui_manager_android.h
+++ b/chrome/browser/notifications/notification_ui_manager_android.h
@@ -5,10 +5,12 @@
#ifndef CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_UI_MANAGER_ANDROID_H_
#define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_UI_MANAGER_ANDROID_H_
+#include <jni.h>
#include <map>
#include <set>
#include <string>
+#include "base/android/scoped_java_ref.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
class ProfileNotification;
@@ -20,6 +22,16 @@
NotificationUIManagerAndroid();
~NotificationUIManagerAndroid() override;
+ // Called by the Java implementation when a notification has been clicked on.
+ void OnNotificationClicked(JNIEnv* env,
+ jobject java_object,
+ jstring notification_id);
+
+ // Called by the Java implementation when a notification has been closed.
+ void OnNotificationClosed(JNIEnv* env,
+ jobject java_object,
+ jstring notification_id);
+
// NotificationUIManager implementation;
void Add(const Notification& notification, Profile* profile) override;
bool Update(const Notification& notification,
@@ -35,9 +47,11 @@
bool CancelAllByProfile(ProfileID profile_id) override;
void CancelAll() override;
+ static bool RegisterNotificationUIManager(JNIEnv* env);
+
private:
// Closes the Notification as displayed on the Android system.
- void PlatformCloseNotification(ProfileNotification* notification) const;
+ void PlatformCloseNotification(ProfileNotification* profile_notification);
// Helpers that add/remove the notification from local map.
// The local map takes ownership of profile_notification object.
@@ -51,6 +65,11 @@
// Map from a notification id to the associated ProfileNotification*.
std::map<std::string, ProfileNotification*> profile_notifications_;
+ // Map from notification id to the associated platform Id.
+ std::map<std::string, int> platform_notifications_;
+
+ base::android::ScopedJavaGlobalRef<jobject> java_object_;
+
DISALLOW_COPY_AND_ASSIGN(NotificationUIManagerAndroid);
};
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index 029008d..d6e4a3f 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -27,6 +27,10 @@
#include "components/translate/core/common/translate_pref_names.h"
#include "policy/policy_constants.h"
+#if defined(OS_ANDROID)
+#include "chrome/browser/search/contextual_search_policy_handler_android.h"
+#endif
+
#if !defined(OS_IOS)
#include "chrome/browser/net/disk_cache_dir_policy_handler.h"
#include "chrome/browser/policy/file_selection_dialogs_policy_handler.h"
@@ -575,6 +579,11 @@
handlers->AddHandler(make_scoped_ptr<ConfigurationPolicyHandler>(
new URLBlacklistPolicyHandler()));
+#if defined(OS_ANDROID)
+ handlers->AddHandler(make_scoped_ptr<ConfigurationPolicyHandler>(
+ new ContextualSearchPolicyHandlerAndroid()));
+#endif
+
#if !defined(OS_IOS)
handlers->AddHandler(make_scoped_ptr<ConfigurationPolicyHandler>(
new FileSelectionDialogsPolicyHandler()));
diff --git a/chrome/browser/resources/component_extension_resources.grd b/chrome/browser/resources/component_extension_resources.grd
index 7592e33..2779d01 100644
--- a/chrome/browser/resources/component_extension_resources.grd
+++ b/chrome/browser/resources/component_extension_resources.grd
@@ -216,6 +216,7 @@
<include name="IDR_CRYPTOTOKEN_APPROVEDORIGINS_JS" file="cryptotoken/approvedorigins.js" type="BINDATA" />
<include name="IDR_CRYPTOTOKEN_GOOGLEAPPROVEDORIGINS_JS" file="cryptotoken/googleapprovedorigins.js" type="BINDATA" />
<include name="IDR_CRYPTOTOKEN_WEBREQUESTSENDER_JS" file="cryptotoken/webrequestsender.js" type="BINDATA" />
+ <include name="IDR_CRYPTOTOKEN_WATCHDOG_JS" file="cryptotoken/watchdog.js" type="BINDATA" />
<include name="IDR_CRYPTOTOKEN_CRYPTOTOKENBACKGROUND_JS" file="cryptotoken/cryptotokenbackground.js" type="BINDATA" />
<include name="IDR_WHISPERNET_PROXY_BACKGROUND_HTML" file="whispernet_proxy/background.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_WHISPERNET_PROXY_INIT_JS" file="whispernet_proxy/js/init.js" type="BINDATA" />
diff --git a/chrome/browser/resources/cryptotoken/countdowntimer.js b/chrome/browser/resources/cryptotoken/countdowntimer.js
index d65bc2e..1ce31d0 100644
--- a/chrome/browser/resources/cryptotoken/countdowntimer.js
+++ b/chrome/browser/resources/cryptotoken/countdowntimer.js
@@ -117,18 +117,20 @@
* guaranteed, in seconds.
* @const
*/
-var MINIMUM_TIMEOUT_ATTENUATION_SECONDS = 0.5;
+var MINIMUM_TIMEOUT_ATTENUATION_SECONDS = 1;
/**
* @param {number} timeoutSeconds Timeout value in seconds.
+ * @param {number=} opt_attenuationSeconds Attenuation value in seconds.
* @return {number} The timeout value, attenuated to ensure a response can be
* given before the timeout's expiration.
- * @private
*/
-function attenuateTimeoutInSeconds_(timeoutSeconds) {
- if (timeoutSeconds < MINIMUM_TIMEOUT_ATTENUATION_SECONDS)
+function attenuateTimeoutInSeconds(timeoutSeconds, opt_attenuationSeconds) {
+ var attenuationSeconds =
+ opt_attenuationSeconds || MINIMUM_TIMEOUT_ATTENUATION_SECONDS;
+ if (timeoutSeconds < attenuationSeconds)
return 0;
- return timeoutSeconds - MINIMUM_TIMEOUT_ATTENUATION_SECONDS;
+ return timeoutSeconds - attenuationSeconds;
}
/**
@@ -138,15 +140,14 @@
var DEFAULT_REQUEST_TIMEOUT_SECONDS = 30;
/**
- * Creates a new countdown from the given request using the given timer factory,
- * attenuated to ensure a response is given prior to the countdown's expiration.
- * @param {CountdownFactory} timerFactory The factory to use.
+ * Gets the timeout value from the request, if any, substituting
+ * opt_defaultTimeoutSeconds or DEFAULT_REQUEST_TIMEOUT_SECONDS if the request
+ * does not contain a timeout value.
* @param {Object} request The request containing the timeout.
* @param {number=} opt_defaultTimeoutSeconds
- * @return {!Countdown} A countdown timer.
+ * @return {number} Timeout value, in seconds.
*/
-function createTimerForRequest(timerFactory, request,
- opt_defaultTimeoutSeconds) {
+function getTimeoutValueFromRequest(request, opt_defaultTimeoutSeconds) {
var timeoutValueSeconds;
if (request.hasOwnProperty('timeoutSeconds')) {
timeoutValueSeconds = request['timeoutSeconds'];
@@ -157,6 +158,21 @@
} else {
timeoutValueSeconds = DEFAULT_REQUEST_TIMEOUT_SECONDS;
}
- timeoutValueSeconds = attenuateTimeoutInSeconds_(timeoutValueSeconds);
+ return timeoutValueSeconds;
+}
+
+/**
+ * Creates a new countdown for the given timeout value, attenuated to ensure a
+ * response is given prior to the countdown's expiration, using the given timer
+ * factory.
+ * @param {CountdownFactory} timerFactory The factory to use.
+ * @param {number} timeoutValueSeconds
+ * @param {number=} opt_attenuationSeconds Attenuation value in seconds.
+ * @return {!Countdown} A countdown timer.
+ */
+function createAttenuatedTimer(timerFactory, timeoutValueSeconds,
+ opt_attenuationSeconds) {
+ timeoutValueSeconds = attenuateTimeoutInSeconds(timeoutValueSeconds,
+ opt_attenuationSeconds);
return timerFactory.createTimer(timeoutValueSeconds * 1000);
}
diff --git a/chrome/browser/resources/cryptotoken/enroller.js b/chrome/browser/resources/cryptotoken/enroller.js
index 867dab7..1ee758e 100644
--- a/chrome/browser/resources/cryptotoken/enroller.js
+++ b/chrome/browser/resources/cryptotoken/enroller.js
@@ -138,8 +138,9 @@
return null;
}
- var timer = createTimerForRequest(
- FACTORY_REGISTRY.getCountdownFactory(), request);
+ var timeoutValueSeconds = getTimeoutValueFromRequest(request);
+ var timer = createAttenuatedTimer(
+ FACTORY_REGISTRY.getCountdownFactory(), timeoutValueSeconds);
var logMsgUrl = request['logMsgUrl'];
var enroller = new Enroller(timer, sender, errorCb, successCb, logMsgUrl);
return enroller;
diff --git a/chrome/browser/resources/cryptotoken/manifest.json b/chrome/browser/resources/cryptotoken/manifest.json
index 71bfd91..ac73862 100644
--- a/chrome/browser/resources/cryptotoken/manifest.json
+++ b/chrome/browser/resources/cryptotoken/manifest.json
@@ -1,7 +1,7 @@
{
"name": "CryptoTokenExtension",
"description": "CryptoToken Component Extension",
- "version": "0.9.2",
+ "version": "0.9.6",
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq7zRobvA+AVlvNqkHSSVhh1sEWsHSqz4oR/XptkDe/Cz3+gW9ZGumZ20NCHjaac8j1iiesdigp8B1LJsd/2WWv2Dbnto4f8GrQ5MVphKyQ9WJHwejEHN2K4vzrTcwaXqv5BSTXwxlxS/mXCmXskTfryKTLuYrcHEWK8fCHb+0gvr8b/kvsi75A1aMmb6nUnFJvETmCkOCPNX5CHTdy634Ts/x0fLhRuPlahk63rdf7agxQv5viVjQFk+tbgv6aa9kdSd11Js/RZ9yZjrFgHOBWgP4jTBqud4+HUglrzu8qynFipyNRLCZsaxhm+NItTyNgesxLdxZcwOz56KD1Q4IQIDAQAB",
"manifest_version": 2,
"permissions": [
@@ -55,6 +55,7 @@
"origincheck.js",
"textfetcher.js",
"appid.js",
+ "watchdog.js",
"gstaticorigincheck.js",
"googleapprovedorigins.js",
"gnubbydevice.js",
diff --git a/chrome/browser/resources/cryptotoken/requestqueue.js b/chrome/browser/resources/cryptotoken/requestqueue.js
index a878d7a..9c523ea 100644
--- a/chrome/browser/resources/cryptotoken/requestqueue.js
+++ b/chrome/browser/resources/cryptotoken/requestqueue.js
@@ -20,6 +20,7 @@
/**
* @param {!RequestQueue} queue The queue for this request.
+ * @param {number} id An id for this request.
* @param {function(QueuedRequestToken)} beginCb Called when work may begin on
* this request.
* @param {RequestToken} opt_prev Previous request in the same queue.
@@ -27,9 +28,11 @@
* @constructor
* @implements {QueuedRequestToken}
*/
-function RequestToken(queue, beginCb, opt_prev, opt_next) {
+function RequestToken(queue, id, beginCb, opt_prev, opt_next) {
/** @private {!RequestQueue} */
this.queue_ = queue;
+ /** @private {number} */
+ this.id_ = id;
/** @type {function(QueuedRequestToken)} */
this.beginCb = beginCb;
/** @type {RequestToken} */
@@ -64,6 +67,8 @@
this.head_ = null;
/** @private {RequestToken} */
this.tail_ = null;
+ /** @private {number} */
+ this.id_ = 0;
}
/**
@@ -72,6 +77,7 @@
* @private
*/
RequestQueue.prototype.insertToken_ = function(token) {
+ console.log(UTIL_fmt('token ' + this.id_ + ' inserted'));
if (this.head_ === null) {
this.head_ = token;
this.tail_ = token;
@@ -116,6 +122,7 @@
* @param {RequestToken} token Queue token
*/
RequestQueue.prototype.complete = function(token) {
+ console.log(UTIL_fmt('token ' + this.id_ + ' completed'));
var next = token.next;
this.removeToken_(token);
if (next) {
@@ -137,7 +144,7 @@
*/
RequestQueue.prototype.queueRequest = function(beginCb, timer) {
var startNow = this.empty();
- var token = new RequestToken(this, beginCb);
+ var token = new RequestToken(this, ++this.id_, beginCb);
// Clone the timer to set a callback on it, which will ensure complete() is
// eventually called, even if the caller never gets around to it.
timer.clone(token.complete.bind(token));
@@ -171,7 +178,7 @@
*/
OriginKeyedRequestQueue.prototype.queueRequest =
function(appId, origin, beginCb, timer) {
- var key = appId + origin;
+ var key = appId + ' ' + origin;
if (!this.requests_.hasOwnProperty(key)) {
this.requests_[key] = new RequestQueue();
}
diff --git a/chrome/browser/resources/cryptotoken/signer.js b/chrome/browser/resources/cryptotoken/signer.js
index 3277447..f0af2a1 100644
--- a/chrome/browser/resources/cryptotoken/signer.js
+++ b/chrome/browser/resources/cryptotoken/signer.js
@@ -143,6 +143,10 @@
*/
function validateAndEnqueueSignRequest(sender, request,
signChallengesName, errorCb, successCb) {
+ function timeout() {
+ errorCb({errorCode: ErrorCodes.TIMEOUT});
+ }
+
if (!isValidSignRequest(request, signChallengesName)) {
errorCb({errorCode: ErrorCodes.BAD_REQUEST});
return null;
@@ -161,19 +165,31 @@
errorCb({errorCode: ErrorCodes.BAD_REQUEST});
return null;
}
- var timer = createTimerForRequest(
- FACTORY_REGISTRY.getCountdownFactory(), request);
+ var timeoutValueSeconds = getTimeoutValueFromRequest(request);
+ // Attenuate watchdog timeout value less than the signer's timeout, so the
+ // watchdog only fires after the signer could reasonably have called back,
+ // not before.
+ timeoutValueSeconds = attenuateTimeoutInSeconds(timeoutValueSeconds,
+ MINIMUM_TIMEOUT_ATTENUATION_SECONDS / 2);
+ var watchdog = new WatchdogRequestHandler(timeoutValueSeconds, timeout);
+ var wrappedErrorCb = watchdog.wrapCallback(errorCb);
+ var wrappedSuccessCb = watchdog.wrapCallback(successCb);
+
+ var timer = createAttenuatedTimer(
+ FACTORY_REGISTRY.getCountdownFactory(), timeoutValueSeconds);
var logMsgUrl = request['logMsgUrl'];
// Queue sign requests from the same origin, to protect against simultaneous
// sign-out on many tabs resulting in repeated sign-in requests.
var queuedSignRequest = new QueuedSignRequest(signChallenges,
- timer, sender, errorCb, successCb, request['challenge'],
+ timer, sender, wrappedErrorCb, wrappedSuccessCb, request['challenge'],
appId, logMsgUrl);
var requestToken = signRequestQueue.queueRequest(appId, sender.origin,
queuedSignRequest.begin.bind(queuedSignRequest), timer);
queuedSignRequest.setToken(requestToken);
- return queuedSignRequest;
+
+ watchdog.setCloseable(queuedSignRequest);
+ return watchdog;
}
/**
@@ -216,7 +232,7 @@
/** @private {!Array.<SignChallenge>} */
this.signChallenges_ = signChallenges;
/** @private {Countdown} */
- this.timer_ = timer;
+ this.timer_ = timer.clone(this.close.bind(this));
/** @private {WebRequestSender} */
this.sender_ = sender;
/** @private {function(U2fError)} */
@@ -238,10 +254,17 @@
/** Closes this sign request. */
QueuedSignRequest.prototype.close = function() {
if (this.closed_) return;
+ var hadBegunSigning = false;
if (this.begun_ && this.signer_) {
this.signer_.close();
+ hadBegunSigning = true;
}
if (this.token_) {
+ if (hadBegunSigning) {
+ console.log(UTIL_fmt('closing in-progress request'));
+ } else {
+ console.log(UTIL_fmt('closing timed-out request before processing'));
+ }
this.token_.complete();
}
this.closed_ = true;
@@ -260,6 +283,12 @@
* @param {QueuedRequestToken} token Token for this sign request.
*/
QueuedSignRequest.prototype.begin = function(token) {
+ if (this.timer_.expired()) {
+ console.log(UTIL_fmt('Queued request begun after timeout'));
+ this.close();
+ this.errorCb_({errorCode: ErrorCodes.TIMEOUT});
+ return;
+ }
this.begun_ = true;
this.setToken(token);
this.signer_ = new Signer(this.timer_, this.sender_,
@@ -270,6 +299,8 @@
token.complete();
this.errorCb_({errorCode: ErrorCodes.BAD_REQUEST});
}
+ // Signer now has responsibility for maintaining timeout.
+ this.timer_.clearTimeout();
};
/**
@@ -307,7 +338,7 @@
*/
function Signer(timer, sender, errorCb, successCb, opt_logMsgUrl) {
/** @private {Countdown} */
- this.timer_ = timer;
+ this.timer_ = timer.clone();
/** @private {WebRequestSender} */
this.sender_ = sender;
/** @private {function(U2fError)} */
@@ -347,6 +378,10 @@
opt_appId) {
if (this.challengesSet_ || this.done_)
return false;
+ if (this.timer_.expired()) {
+ this.notifyError_({errorCode: ErrorCodes.TIMEOUT});
+ return true;
+ }
/** @private {Array.<SignChallenge>} */
this.signChallenges_ = signChallenges;
/** @private {string|undefined} */
@@ -483,6 +518,17 @@
/** Closes this signer. */
Signer.prototype.close = function() {
+ this.close_();
+};
+
+/**
+ * Closes this signer, and optionally notifies the caller of error.
+ * @param {boolean=} opt_notifying When true, this method is being called in the
+ * process of notifying the caller of an existing status. When false,
+ * the caller is notified with a default error value, ErrorCodes.TIMEOUT.
+ * @private
+ */
+Signer.prototype.close_ = function(opt_notifying) {
if (this.appIdChecker_) {
this.appIdChecker_.close();
}
@@ -491,6 +537,9 @@
this.handler_ = null;
}
this.timer_.clearTimeout();
+ if (!opt_notifying) {
+ this.notifyError_({errorCode: ErrorCodes.TIMEOUT});
+ }
};
/**
@@ -501,8 +550,8 @@
Signer.prototype.notifyError_ = function(error) {
if (this.done_)
return;
- this.close();
this.done_ = true;
+ this.close_(true);
this.errorCb_(error);
};
@@ -516,8 +565,8 @@
Signer.prototype.notifySuccess_ = function(challenge, info, browserData) {
if (this.done_)
return;
- this.close();
this.done_ = true;
+ this.close_(true);
this.successCb_(challenge, info, browserData);
};
diff --git a/chrome/browser/resources/cryptotoken/singlesigner.js b/chrome/browser/resources/cryptotoken/singlesigner.js
index 5538ff7..d2f2333 100644
--- a/chrome/browser/resources/cryptotoken/singlesigner.js
+++ b/chrome/browser/resources/cryptotoken/singlesigner.js
@@ -345,12 +345,20 @@
break;
case DeviceStatusCodes.TIMEOUT_STATUS:
- // TODO: On a TIMEOUT_STATUS, sync first, then retry.
+ this.gnubby_.sync(this.synced_.bind(this));
+ break;
+
case DeviceStatusCodes.BUSY_STATUS:
this.doSign_(this.challengeIndex_);
break;
case DeviceStatusCodes.OK_STATUS:
+ // Lower bound on the minimum length, signature length can vary.
+ var MIN_SIGNATURE_LENGTH = 7;
+ if (!opt_info || opt_info.byteLength < MIN_SIGNATURE_LENGTH) {
+ console.error(UTIL_fmt('Got short response to sign request (' +
+ (opt_info ? opt_info.byteLength : 0) + ' bytes), WTF?'));
+ }
if (this.forEnroll_) {
this.goToError_(code);
} else {
@@ -387,6 +395,20 @@
};
/**
+ * Called with the response of a sync command, called when a sign yields a
+ * timeout to reassert control over the gnubby.
+ * @param {number} code Error code
+ * @private
+ */
+SingleGnubbySigner.prototype.synced_ = function(code) {
+ if (code) {
+ this.goToError_(code, true);
+ return;
+ }
+ this.doSign_(this.challengeIndex_);
+};
+
+/**
* Switches to the error state, and notifies caller.
* @param {number} code Error code
* @param {boolean=} opt_warn Whether to warn in the console about the error.
diff --git a/chrome/browser/resources/cryptotoken/usbsignhandler.js b/chrome/browser/resources/cryptotoken/usbsignhandler.js
index 560ca59..e5c227e 100644
--- a/chrome/browser/resources/cryptotoken/usbsignhandler.js
+++ b/chrome/browser/resources/cryptotoken/usbsignhandler.js
@@ -122,7 +122,20 @@
];
/** @const */
-UsbSignHandler.BOGUS_CHALLENGE_HASH = [
+UsbSignHandler.BOGUS_CHALLENGE_V1 = [
+ 0x04, 0xA2, 0x24, 0x7D, 0x5C, 0x0B, 0x76, 0xF1,
+ 0xDC, 0xCD, 0x44, 0xAF, 0x91, 0x9A, 0xA2, 0x3F,
+ 0x3F, 0xBA, 0x65, 0x9F, 0x06, 0x78, 0x82, 0xFB,
+ 0x93, 0x4B, 0xBF, 0x86, 0x55, 0x95, 0x66, 0x46,
+ 0x76, 0x90, 0xDC, 0xE1, 0xE8, 0x6C, 0x86, 0x86,
+ 0xC3, 0x03, 0x4E, 0x65, 0x52, 0x4C, 0x32, 0x6F,
+ 0xB6, 0x44, 0x0D, 0x50, 0xF9, 0x16, 0xC0, 0xA3,
+ 0xDA, 0x31, 0x4B, 0xD3, 0x3F, 0x94, 0xA5, 0xF1,
+ 0xD3
+];
+
+/** @const */
+UsbSignHandler.BOGUS_CHALLENGE_V2 = [
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
@@ -136,10 +149,29 @@
* @private
*/
UsbSignHandler.prototype.sendBogusEnroll_ = function(gnubby) {
- gnubby.enroll(
- UsbSignHandler.BOGUS_APP_ID_HASH,
- UsbSignHandler.BOGUS_CHALLENGE_HASH,
- this.enrollCallback_.bind(this, gnubby));
+ var self = this;
+ gnubby.version(function(rc, opt_data) {
+ if (rc) {
+ self.notifyError_(rc);
+ return;
+ }
+ var enrollChallenge;
+ var version = UTIL_BytesToString(new Uint8Array(opt_data || []));
+ switch (version) {
+ case Gnubby.U2F_V1:
+ enrollChallenge = UsbSignHandler.BOGUS_CHALLENGE_V1;
+ break;
+ case Gnubby.U2F_V2:
+ enrollChallenge = UsbSignHandler.BOGUS_CHALLENGE_V2;
+ break;
+ default:
+ self.notifyError_(DeviceStatusCodes.INVALID_DATA_STATUS);
+ }
+ gnubby.enroll(
+ /** @type {Array.<number>} */ (enrollChallenge),
+ UsbSignHandler.BOGUS_APP_ID_HASH,
+ self.enrollCallback_.bind(self, gnubby));
+ });
};
/**
diff --git a/chrome/browser/resources/cryptotoken/watchdog.js b/chrome/browser/resources/cryptotoken/watchdog.js
new file mode 100644
index 0000000..17bee28
--- /dev/null
+++ b/chrome/browser/resources/cryptotoken/watchdog.js
@@ -0,0 +1,95 @@
+// Copyright 2014 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.
+
+/**
+ * @fileoverview Provides a watchdog around a collection of callback functions.
+ */
+'use strict';
+
+/**
+ * Creates a watchdog around a collection of callback functions,
+ * ensuring at least one of them is called before the timeout expires.
+ * If a timeout function is provided, calls the timeout function upon timeout
+ * expiration if none of the callback functions has been called.
+ * @param {number} timeoutValueSeconds Timeout value, in seconds.
+ * @param {function()=} opt_timeoutCb Callback function to call on timeout.
+ * @constructor
+ * @implements {Closeable}
+ */
+function WatchdogRequestHandler(timeoutValueSeconds, opt_timeoutCb) {
+ /** @private {number} */
+ this.timeoutValueSeconds_ = timeoutValueSeconds;
+ /** @private {function()|undefined} */
+ this.timeoutCb_ = opt_timeoutCb;
+ /** @private {boolean} */
+ this.calledBack_ = false;
+ /** @private {Countdown} */
+ this.timer_ = FACTORY_REGISTRY.getCountdownFactory().createTimer(
+ this.timeoutValueSeconds_ * 1000, this.timeout_.bind(this));
+ /** @private {Closeable|undefined} */
+ this.closeable_ = undefined;
+ /** @private {boolean} */
+ this.closed_ = false;
+}
+
+/**
+ * Wraps a callback function, such that the fact that the callback function
+ * was or was not called gets tracked by this watchdog object.
+ * @param {function(...?)} cb The callback function to wrap.
+ * @return {function(...?)} A wrapped callback function.
+ */
+WatchdogRequestHandler.prototype.wrapCallback = function(cb) {
+ return this.wrappedCallback_.bind(this, cb);
+};
+
+/** Closes this watchdog. */
+WatchdogRequestHandler.prototype.close = function() {
+ this.closed_ = true;
+ this.timer_.clearTimeout();
+ if (this.closeable_) {
+ this.closeable_.close();
+ this.closeable_ = undefined;
+ }
+};
+
+/**
+ * Sets this watchdog's closeable.
+ * @param {!Closeable} closeable The closeable.
+ */
+WatchdogRequestHandler.prototype.setCloseable = function(closeable) {
+ this.closeable_ = closeable;
+};
+
+/**
+ * Called back when the watchdog expires.
+ * @private
+ */
+WatchdogRequestHandler.prototype.timeout_ = function() {
+ if (!this.calledBack_ && !this.closed_) {
+ var logMsg = 'Not called back within ' + this.timeoutValueSeconds_ +
+ ' second timeout';
+ if (this.timeoutCb_) {
+ logMsg += ', calling default callback';
+ console.warn(UTIL_fmt(logMsg));
+ this.timeoutCb_();
+ } else {
+ console.warn(UTIL_fmt(logMsg));
+ }
+ }
+};
+
+/**
+ * Wrapped callback function.
+ * @param {function(...?)} cb The callback function to call.
+ * @param {...?} var_args The callback function's arguments.
+ * @private
+ */
+WatchdogRequestHandler.prototype.wrappedCallback_ = function(cb, var_args) {
+ if (!this.closed_) {
+ this.calledBack_ = true;
+ this.timer_.clearTimeout();
+ var originalArgs = Array.prototype.slice.call(arguments, 1);
+ cb.apply(null, originalArgs);
+ }
+};
diff --git a/chrome/browser/resources/gaia_auth/manifest.json b/chrome/browser/resources/gaia_auth/manifest.json
index afc5e93..7295c01 100644
--- a/chrome/browser/resources/gaia_auth/manifest.json
+++ b/chrome/browser/resources/gaia_auth/manifest.json
@@ -13,6 +13,7 @@
"<all_urls>"
],
"js": ["channel.js", "saml_injected.js"],
+ "run_at": "document_start",
"all_frames": true
}
],
diff --git a/chrome/browser/resources/gaia_auth/manifest_keyboard.json b/chrome/browser/resources/gaia_auth/manifest_keyboard.json
index 99c03c4..68d59a1 100644
--- a/chrome/browser/resources/gaia_auth/manifest_keyboard.json
+++ b/chrome/browser/resources/gaia_auth/manifest_keyboard.json
@@ -13,6 +13,7 @@
"<all_urls>"
],
"js": ["channel.js", "saml_injected.js"],
+ "run_at": "document_start",
"all_frames": true
},
{
diff --git a/chrome/browser/resources/plugin_metadata/plugins_chromeos.json b/chrome/browser/resources/plugin_metadata/plugins_chromeos.json
index 5d3eed1..57e3685 100644
--- a/chrome/browser/resources/plugin_metadata/plugins_chromeos.json
+++ b/chrome/browser/resources/plugin_metadata/plugins_chromeos.json
@@ -1,12 +1,12 @@
{
- "x-version": 1,
+ "x-version": 2,
"google-talk": {
"mime_types": [
],
"versions": [
{
"version": "0",
- "status": "up_to_date",
+ "status": "requires_authorization",
"comment": "'Google Talk Plugin' and 'Google Talk Plugin Video Accelerator' are bundled with ChromeOS, so we don't define a minimum version."
}
],
diff --git a/chrome/browser/resources/plugin_metadata/plugins_linux.json b/chrome/browser/resources/plugin_metadata/plugins_linux.json
index 367aff8..7ddd998 100644
--- a/chrome/browser/resources/plugin_metadata/plugins_linux.json
+++ b/chrome/browser/resources/plugin_metadata/plugins_linux.json
@@ -1,12 +1,12 @@
{
- "x-version": 4,
+ "x-version": 5,
"google-talk": {
"mime_types": [
],
"versions": [
{
"version": "0",
- "status": "up_to_date",
+ "status": "requires_authorization",
"comment": "'Google Talk Plugin' and 'Google Talk Plugin Video Accelerator' use two completely different versioning schemes, so we can't define a minimum version."
}
],
diff --git a/chrome/browser/resources/plugin_metadata/plugins_mac.json b/chrome/browser/resources/plugin_metadata/plugins_mac.json
index 40abf69..cb424a9 100644
--- a/chrome/browser/resources/plugin_metadata/plugins_mac.json
+++ b/chrome/browser/resources/plugin_metadata/plugins_mac.json
@@ -1,12 +1,12 @@
{
- "x-version": 5,
+ "x-version": 6,
"google-talk": {
"mime_types": [
],
"versions": [
{
"version": "0",
- "status": "up_to_date",
+ "status": "requires_authorization",
"comment": "'Google Talk Plugin' and 'Google Talk Plugin Video Accelerator' use two completely different versioning schemes, so we can't define a minimum version."
}
],
@@ -260,7 +260,7 @@
"versions": [
{
"version": "5.1.30214.0",
- "status": "up_to_date",
+ "status": "requires_authorization",
"reference": "https://support.microsoft.com/kb/2932677"
}
],
@@ -290,7 +290,7 @@
"versions": [
{
"version": "0",
- "status": "up_to_date",
+ "status": "requires_authorization",
"comment": "We do not track version information for the Facebook Video Calling Plugin."
}
],
@@ -306,7 +306,7 @@
"versions": [
{
"version": "0",
- "status": "up_to_date",
+ "status": "requires_authorization",
"comment": "We do not track version information for the Google Earth Plugin."
}
],
diff --git a/chrome/browser/resources/plugin_metadata/plugins_win.json b/chrome/browser/resources/plugin_metadata/plugins_win.json
index 28853b4..5d2229c 100644
--- a/chrome/browser/resources/plugin_metadata/plugins_win.json
+++ b/chrome/browser/resources/plugin_metadata/plugins_win.json
@@ -1,12 +1,12 @@
{
- "x-version": 14,
+ "x-version": 15,
"google-talk": {
"mime_types": [
],
"versions": [
{
"version": "0",
- "status": "up_to_date",
+ "status": "requires_authorization",
"comment": "'Google Talk Plugin' and 'Google Talk Plugin Video Accelerator' use two completely different versioning schemes, so we can't define a minimum version."
}
],
@@ -298,7 +298,7 @@
"versions": [
{
"version": "5.1.30214.0",
- "status": "up_to_date",
+ "status": "requires_authorization",
"reference": "https://support.microsoft.com/kb/2932677"
}
],
@@ -366,7 +366,7 @@
"versions": [
{
"version": "0",
- "status": "up_to_date",
+ "status": "requires_authorization",
"comment": "We do not track version information for the Facebook Video Calling Plugin."
}
],
@@ -382,7 +382,7 @@
"versions": [
{
"version": "0",
- "status": "up_to_date",
+ "status": "requires_authorization",
"comment": "We do not track version information for the Google Earth Plugin."
}
],
diff --git a/chrome/browser/resources/print_preview/settings/dpi_settings.js b/chrome/browser/resources/print_preview/settings/dpi_settings.js
index e39e9f4..a06dc9e 100644
--- a/chrome/browser/resources/print_preview/settings/dpi_settings.js
+++ b/chrome/browser/resources/print_preview/settings/dpi_settings.js
@@ -21,7 +21,11 @@
/** @override */
getDefaultDisplayName_: function(option) {
- return loadTimeData.getStringF('dpiItemLabel', option.horizontal_dpi);
+ var hDpi = option.horizontal_dpi || 0;
+ var vDpi = option.vertical_dpi || 0;
+ if (hDpi > 0 && vDpi > 0 && hDpi != vDpi)
+ return loadTimeData.getStringF('nonIsotropicDpiItemLabel', hDpi, vDpi);
+ return loadTimeData.getStringF('dpiItemLabel', hDpi || vDpi);
}
};
diff --git a/chrome/browser/safe_browsing/download_protection_service.cc b/chrome/browser/safe_browsing/download_protection_service.cc
index ba255be..30f2523 100644
--- a/chrome/browser/safe_browsing/download_protection_service.cc
+++ b/chrome/browser/safe_browsing/download_protection_service.cc
@@ -644,6 +644,9 @@
void GetTabRedirects() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (!service_)
+ return;
+
if (!tab_url_.is_valid()) {
SendRequest();
return;
@@ -669,6 +672,8 @@
const history::RedirectList* redirect_list) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK_EQ(url, tab_url_);
+ if (!service_)
+ return;
if (!redirect_list->empty()) {
tab_redirects_.insert(
diff --git a/chrome/browser/safe_browsing/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection_service_unittest.cc
index b06e8c8..84fd01d 100644
--- a/chrome/browser/safe_browsing/download_protection_service_unittest.cc
+++ b/chrome/browser/safe_browsing/download_protection_service_unittest.cc
@@ -50,6 +50,7 @@
using ::testing::ContainerEq;
using ::testing::DoAll;
using ::testing::ElementsAre;
+using ::testing::Invoke;
using ::testing::Mock;
using ::testing::NotNull;
using ::testing::Return;
@@ -1599,6 +1600,7 @@
std::vector<GURL> url_chain;
url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
GURL referrer("http://www.google.com/");
+ GURL tab_url("http://www.google.com/tab");
base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp"));
base::FilePath final_path(FILE_PATH_LITERAL("a.exe"));
std::string hash = "hash";
@@ -1610,7 +1612,7 @@
.WillRepeatedly(ReturnRef(final_path));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
- EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
+ EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url));
EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
@@ -1637,6 +1639,52 @@
EXPECT_FALSE(HasClientDownloadRequest());
}
+TEST_F(DownloadProtectionServiceTest,
+ TestDownloadItemDestroyedDuringWhitelistCheck) {
+ net::TestURLFetcherFactory factory;
+
+ std::vector<GURL> url_chain;
+ url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
+ GURL referrer("http://www.google.com/");
+ GURL tab_url("http://www.google.com/tab");
+ base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp"));
+ base::FilePath final_path(FILE_PATH_LITERAL("a.exe"));
+ std::string hash = "hash";
+
+ scoped_ptr<content::MockDownloadItem> item(new content::MockDownloadItem);
+ EXPECT_CALL(*item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
+ EXPECT_CALL(*item, GetTargetFilePath())
+ .WillRepeatedly(ReturnRef(final_path));
+ EXPECT_CALL(*item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
+ EXPECT_CALL(*item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
+ EXPECT_CALL(*item, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url));
+ EXPECT_CALL(*item, GetTabReferrerUrl())
+ .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
+ EXPECT_CALL(*item, GetHash()).WillRepeatedly(ReturnRef(hash));
+ EXPECT_CALL(*item, GetReceivedBytes()).WillRepeatedly(Return(100));
+ EXPECT_CALL(*item, HasUserGesture()).WillRepeatedly(Return(true));
+ EXPECT_CALL(*item, GetRemoteAddress()).WillRepeatedly(Return(""));
+
+ EXPECT_CALL(*sb_service_->mock_database_manager(),
+ MatchDownloadWhitelistUrl(_))
+ .WillRepeatedly(Invoke([&item](const GURL&) {
+ item.reset();
+ return false;
+ }));
+ EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
+ EXPECT_CALL(*binary_feature_extractor_.get(),
+ ExtractImageHeaders(tmp_path, _));
+
+ download_service_->CheckClientDownload(
+ item.get(),
+ base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
+ base::Unretained(this)));
+
+ MessageLoop::current()->Run();
+ EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
+ EXPECT_FALSE(HasClientDownloadRequest());
+}
+
TEST_F(DownloadProtectionServiceTest, GetCertificateWhitelistStrings) {
// We'll pass this cert in as the "issuer", even though it isn't really
// used to sign the certs below. GetCertificateWhitelistStirngs doesn't care
diff --git a/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.cc b/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.cc
index c4b184f..6a6acd0 100644
--- a/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.cc
@@ -453,6 +453,11 @@
}
// Remove any metadata.
download_metadata_.reset();
+ // Stop observing this item.
+ if (item_) {
+ item_->RemoveObserver(this);
+ item_= nullptr;
+ }
write_runner_->PostTask(
FROM_HERE, base::Bind(&DeleteMetadataOnWorkerPool, metadata_path_));
// Run callbacks (only present in case of a transition to LOAD_COMPLETE).
diff --git a/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager_unittest.cc
index 071ec3c..538a7da 100644
--- a/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager_unittest.cc
@@ -485,4 +485,28 @@
testing::Values("waiting", "loaded"),
testing::Values("clear", "set")));
+class DownloadMetadataManagerTest : public DownloadMetadataManagerTestBase {
+ protected:
+};
+
+// Test that that opening an item when there is no corresponding metadata works.
+TEST_F(DownloadMetadataManagerTest, OpenDownloadNoMetadata) {
+ // Add a download manager and some items.
+ WriteTestMetadataFile();
+ AddDownloadManager();
+ AddDownloadItems();
+
+ // Allow the metadata manager to discover that no metadata is available.
+ RunAllTasks();
+
+ // Clear metadata.
+ manager_.SetRequest(test_item_.get(), nullptr);
+
+ // Open an item.
+ test_item_->NotifyObserversDownloadOpened();
+
+ // Shut down.
+ ShutdownDownloadManager();
+}
+
} // namespace safe_browsing
diff --git a/chrome/browser/search/contextual_search_policy_handler_android.cc b/chrome/browser/search/contextual_search_policy_handler_android.cc
new file mode 100644
index 0000000..13f5502
--- /dev/null
+++ b/chrome/browser/search/contextual_search_policy_handler_android.cc
@@ -0,0 +1,39 @@
+// Copyright 2014 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.
+
+#include "chrome/browser/search/contextual_search_policy_handler_android.h"
+
+#include "base/prefs/pref_value_map.h"
+#include "base/values.h"
+#include "chrome/common/pref_names.h"
+#include "components/policy/core/common/policy_map.h"
+#include "policy/policy_constants.h"
+
+namespace policy {
+
+ContextualSearchPolicyHandlerAndroid::ContextualSearchPolicyHandlerAndroid()
+ : TypeCheckingPolicyHandler(key::kContextualSearchEnabled,
+ base::Value::TYPE_BOOLEAN) {}
+
+ContextualSearchPolicyHandlerAndroid::~ContextualSearchPolicyHandlerAndroid() {
+}
+
+void ContextualSearchPolicyHandlerAndroid::ApplyPolicySettings(
+ const PolicyMap& policies,
+ PrefValueMap* prefs) {
+ const base::Value* value = policies.GetValue(policy_name());
+ bool contextual_search_enabled = true;
+ // From a Contextual Search preference point of view, "false" means the
+ // feature is turned off completely. "" means the feature is uninitialized and
+ // an opt-in screen is presented to the user, after which the preference is
+ // either "true" or "false", depending on their choice. Here a false policy
+ // explicitly disables Contextual Search.
+ if (value &&
+ value->GetAsBoolean(&contextual_search_enabled) &&
+ !contextual_search_enabled) {
+ prefs->SetString(prefs::kContextualSearchEnabled, "false");
+ }
+}
+
+} // namespace policy
diff --git a/chrome/browser/search/contextual_search_policy_handler_android.h b/chrome/browser/search/contextual_search_policy_handler_android.h
new file mode 100644
index 0000000..3794c20
--- /dev/null
+++ b/chrome/browser/search/contextual_search_policy_handler_android.h
@@ -0,0 +1,31 @@
+// Copyright 2014 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.
+
+#ifndef CHROME_BROWSER_SEARCH_CONTEXTUAL_SEARCH_POLICY_HANDLER_ANDROID_H_
+#define CHROME_BROWSER_SEARCH_CONTEXTUAL_SEARCH_POLICY_HANDLER_ANDROID_H_
+
+#include "components/policy/core/browser/configuration_policy_handler.h"
+
+namespace policy {
+
+class PolicyMap;
+
+// ConfigurationPolicyHandler for the ContextualSearchEnabled policy.
+class ContextualSearchPolicyHandlerAndroid
+ : public TypeCheckingPolicyHandler {
+ public:
+ ContextualSearchPolicyHandlerAndroid();
+ ~ContextualSearchPolicyHandlerAndroid() override;
+
+ // ConfigurationPolicyHandler methods:
+ void ApplyPolicySettings(const PolicyMap& policies,
+ PrefValueMap* prefs) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ContextualSearchPolicyHandlerAndroid);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_SEARCH_CONTEXTUAL_SEARCH_POLICY_HANDLER_ANDROID_H_
diff --git a/chrome/browser/search/contextual_search_policy_handler_android_unittest.cc b/chrome/browser/search/contextual_search_policy_handler_android_unittest.cc
new file mode 100644
index 0000000..1b494f0
--- /dev/null
+++ b/chrome/browser/search/contextual_search_policy_handler_android_unittest.cc
@@ -0,0 +1,59 @@
+// Copyright 2014 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.
+
+#include "base/prefs/pref_value_map.h"
+#include "base/values.h"
+#include "chrome/browser/search/contextual_search_policy_handler_android.h"
+#include "chrome/common/pref_names.h"
+#include "components/policy/core/common/policy_map.h"
+#include "policy/policy_constants.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+
+TEST(ContextualSearchPolicyHandlerAndroidTest, Default) {
+ PolicyMap policy;
+ PrefValueMap prefs;
+ ContextualSearchPolicyHandlerAndroid handler;
+ handler.ApplyPolicySettings(policy, &prefs);
+ std::string pref_value;
+ EXPECT_FALSE(prefs.GetString(prefs::kContextualSearchEnabled, &pref_value));
+ EXPECT_EQ("", pref_value);
+}
+
+TEST(ContextualSearchPolicyHandlerAndroidTest, Enabled) {
+ PolicyMap policy;
+ policy.Set(key::kContextualSearchEnabled,
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ new base::FundamentalValue(true),
+ NULL);
+ PrefValueMap prefs;
+ ContextualSearchPolicyHandlerAndroid handler;
+ handler.ApplyPolicySettings(policy, &prefs);
+
+ // Enabling Contextual Search policy should not set the pref.
+ std::string pref_value;
+ EXPECT_FALSE(prefs.GetString(prefs::kContextualSearchEnabled, &pref_value));
+ EXPECT_EQ("", pref_value);
+}
+
+TEST(ContextualSearchPolicyHandlerAndroidTest, Disabled) {
+ PolicyMap policy;
+ policy.Set(key::kContextualSearchEnabled,
+ POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER,
+ new base::FundamentalValue(false),
+ NULL);
+ PrefValueMap prefs;
+ ContextualSearchPolicyHandlerAndroid handler;
+ handler.ApplyPolicySettings(policy, &prefs);
+
+ // Disabling Contextual Search should switch the pref to managed.
+ std::string pref_value;
+ EXPECT_TRUE(prefs.GetString(prefs::kContextualSearchEnabled, &pref_value));
+ EXPECT_EQ("false", pref_value);
+}
+
+} // namespace policy
diff --git a/chrome/browser/services/gcm/gcm_account_tracker.cc b/chrome/browser/services/gcm/gcm_account_tracker.cc
index a2cdba0..0521688 100644
--- a/chrome/browser/services/gcm/gcm_account_tracker.cc
+++ b/chrome/browser/services/gcm/gcm_account_tracker.cc
@@ -15,11 +15,18 @@
namespace gcm {
namespace {
+
+// Scopes needed by the OAuth2 access tokens.
const char kGCMGroupServerScope[] = "https://www.googleapis.com/auth/gcm";
const char kGCMCheckinServerScope[] =
"https://www.googleapis.com/auth/android_checkin";
+// Name of the GCM account tracker for the OAuth2TokenService.
const char kGCMAccountTrackerName[] = "gcm_account_tracker";
+// Minimum token validity when sending to GCM groups server.
const int64 kMinimumTokenValidityMs = 500;
+// Token reporting interval, when no account changes are detected.
+const int64 kTokenReportingIntervalMs = 12 * 60 * 60 * 1000; // 12 hours in ms.
+
} // namespace
GCMAccountTracker::AccountInfo::AccountInfo(const std::string& email,
@@ -36,7 +43,8 @@
: OAuth2TokenService::Consumer(kGCMAccountTrackerName),
account_tracker_(account_tracker.release()),
driver_(driver),
- shutdown_called_(false) {
+ shutdown_called_(false),
+ reporting_weak_ptr_factory_(this) {
}
GCMAccountTracker::~GCMAccountTracker() {
@@ -56,11 +64,6 @@
driver_->AddConnectionObserver(this);
std::vector<gaia::AccountIds> accounts = account_tracker_->GetAccounts();
- if (accounts.empty()) {
- CompleteCollectingTokens();
- return;
- }
-
for (std::vector<gaia::AccountIds>::const_iterator iter = accounts.begin();
iter != accounts.end();
++iter) {
@@ -70,7 +73,22 @@
}
}
- GetAllNeededTokens();
+ if (IsTokenReportingRequired())
+ ReportTokens();
+ else
+ ScheduleReportTokens();
+}
+
+void GCMAccountTracker::ScheduleReportTokens() {
+ DVLOG(1) << "Deferring the token reporting for: "
+ << GetTimeToNextTokenReporting().InSeconds() << " seconds.";
+
+ reporting_weak_ptr_factory_.InvalidateWeakPtrs();
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&GCMAccountTracker::ReportTokens,
+ reporting_weak_ptr_factory_.GetWeakPtr()),
+ GetTimeToNextTokenReporting());
}
void GCMAccountTracker::OnAccountAdded(const gaia::AccountIds& ids) {
@@ -115,7 +133,7 @@
}
DeleteTokenRequest(request);
- CompleteCollectingTokens();
+ ReportTokens();
}
void GCMAccountTracker::OnGetTokenFailure(
@@ -137,21 +155,22 @@
}
DeleteTokenRequest(request);
- CompleteCollectingTokens();
+ ReportTokens();
}
void GCMAccountTracker::OnConnected(const net::IPEndPoint& ip_endpoint) {
- if (SanitizeTokens())
- GetAllNeededTokens();
+ if (IsTokenReportingRequired())
+ ReportTokens();
}
void GCMAccountTracker::OnDisconnected() {
// We are disconnected, so no point in trying to work with tokens.
}
-void GCMAccountTracker::CompleteCollectingTokens() {
+void GCMAccountTracker::ReportTokens() {
+ SanitizeTokens();
// Make sure all tokens are valid.
- if (SanitizeTokens()) {
+ if (IsTokenFetchingRequired()) {
GetAllNeededTokens();
return;
}
@@ -198,13 +217,14 @@
if (!account_tokens.empty() || account_removed) {
DVLOG(1) << "Reporting the tokens to driver: " << account_tokens.size();
driver_->SetAccountTokens(account_tokens);
+ driver_->SetLastTokenFetchTime(base::Time::Now());
+ ScheduleReportTokens();
} else {
DVLOG(1) << "No tokens and nothing removed. Skipping callback.";
}
}
-bool GCMAccountTracker::SanitizeTokens() {
- bool tokens_needed = false;
+void GCMAccountTracker::SanitizeTokens() {
for (AccountInfos::iterator iter = account_infos_.begin();
iter != account_infos_.end();
++iter) {
@@ -216,12 +236,43 @@
iter->second.state = TOKEN_NEEDED;
iter->second.expiration_time = base::Time();
}
+ }
+}
- if (iter->second.state == TOKEN_NEEDED)
- tokens_needed = true;
+bool GCMAccountTracker::IsTokenReportingRequired() const {
+ if (GetTimeToNextTokenReporting() == base::TimeDelta())
+ return true;
+
+ bool reporting_required = false;
+ for (AccountInfos::const_iterator iter = account_infos_.begin();
+ iter != account_infos_.end();
+ ++iter) {
+ if (iter->second.state == ACCOUNT_REMOVED)
+ reporting_required = true;
}
- return tokens_needed;
+ return reporting_required;
+}
+
+bool GCMAccountTracker::IsTokenFetchingRequired() const {
+ bool token_needed = false;
+ for (AccountInfos::const_iterator iter = account_infos_.begin();
+ iter != account_infos_.end();
+ ++iter) {
+ if (iter->second.state == TOKEN_NEEDED)
+ token_needed = true;
+ }
+
+ return token_needed;
+}
+
+base::TimeDelta GCMAccountTracker::GetTimeToNextTokenReporting() const {
+ base::TimeDelta time_till_next_reporting =
+ driver_->GetLastTokenFetchTime() +
+ base::TimeDelta::FromMilliseconds(kTokenReportingIntervalMs) -
+ base::Time::Now();
+ return time_till_next_reporting < base::TimeDelta() ?
+ base::TimeDelta() : time_till_next_reporting;
}
void GCMAccountTracker::DeleteTokenRequest(
@@ -235,6 +286,9 @@
void GCMAccountTracker::GetAllNeededTokens() {
// Only start fetching tokens if driver is running, they have a limited
// validity time and GCM connection is a good indication of network running.
+ // If the GetAllNeededTokens was called as part of periodic schedule, it may
+ // not have network. In that case the next network change will trigger token
+ // fetching.
if (!driver_->IsConnected())
return;
@@ -282,7 +336,7 @@
iter->second.access_token.clear();
iter->second.state = ACCOUNT_REMOVED;
- CompleteCollectingTokens();
+ ReportTokens();
}
OAuth2TokenService* GCMAccountTracker::GetTokenService() {
diff --git a/chrome/browser/services/gcm/gcm_account_tracker.h b/chrome/browser/services/gcm/gcm_account_tracker.h
index 0b1c5e8..39f357e 100644
--- a/chrome/browser/services/gcm/gcm_account_tracker.h
+++ b/chrome/browser/services/gcm/gcm_account_tracker.h
@@ -14,12 +14,21 @@
#include "google_apis/gaia/account_tracker.h"
#include "google_apis/gaia/oauth2_token_service.h"
+namespace base {
+class Time;
+}
+
namespace gcm {
class GCMDriver;
// Class for reporting back which accounts are signed into. It is only meant to
// be used when the user is signed into sync.
+//
+// This class makes a check for tokens periodically, to make sure the user is
+// still logged into the profile, so that in the case that the user is not, we
+// can immediately report that to the GCM and stop messages addressed to that
+// user from ever reaching Chrome.
class GCMAccountTracker : public gaia::AccountTracker::Observer,
public OAuth2TokenService::Consumer,
public GCMConnectionObserver {
@@ -76,6 +85,8 @@
}
private:
+ friend class GCMAccountTrackerTest;
+
// Maps account keys to account states. Keyed by account_ids as used by
// OAuth2TokenService.
typedef std::map<std::string, AccountInfo> AccountInfos;
@@ -97,13 +108,22 @@
void OnConnected(const net::IPEndPoint& ip_endpoint) override;
void OnDisconnected() override;
+ // Schedules token reporting.
+ void ScheduleReportTokens();
// Report the list of accounts with OAuth2 tokens back using the |callback_|
// function. If there are token requests in progress, do nothing.
- void CompleteCollectingTokens();
+ void ReportTokens();
// Verify that all of the tokens are ready to be passed down to the GCM
// Driver, e.g. none of them has expired or is missing. Returns true if not
// all tokens are valid and a fetching yet more tokens is required.
- bool SanitizeTokens();
+ void SanitizeTokens();
+ // Indicates whether token reporting is required, either because it is due, or
+ // some of the accounts were removed.
+ bool IsTokenReportingRequired() const;
+ // Indicates whether there are tokens that still need fetching.
+ bool IsTokenFetchingRequired() const;
+ // Gets the time until next token reporting.
+ base::TimeDelta GetTimeToNextTokenReporting() const;
// Deletes a token request. Should be called from OnGetTokenSuccess(..) or
// OnGetTokenFailure(..).
void DeleteTokenRequest(const OAuth2TokenService::Request* request);
@@ -133,6 +153,10 @@
ScopedVector<OAuth2TokenService::Request> pending_token_requests_;
+ // Creates weak pointers used to postpone reporting tokens. See
+ // ScheduleReportTokens.
+ base::WeakPtrFactory<GCMAccountTracker> reporting_weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(GCMAccountTracker);
};
diff --git a/chrome/browser/services/gcm/gcm_account_tracker_unittest.cc b/chrome/browser/services/gcm/gcm_account_tracker_unittest.cc
index 2211d76..eb8030a 100644
--- a/chrome/browser/services/gcm/gcm_account_tracker_unittest.cc
+++ b/chrome/browser/services/gcm/gcm_account_tracker_unittest.cc
@@ -8,8 +8,6 @@
#include <string>
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
#include "components/gcm_driver/fake_gcm_driver.h"
#include "google_apis/gaia/fake_identity_provider.h"
#include "google_apis/gaia/fake_oauth2_token_service.h"
@@ -76,6 +74,8 @@
void AddConnectionObserver(GCMConnectionObserver* observer) override;
void RemoveConnectionObserver(GCMConnectionObserver* observer) override;
bool IsConnected() const override { return connected_; }
+ base::Time GetLastTokenFetchTime() override;
+ void SetLastTokenFetchTime(const base::Time& time) override;
// Test results and helpers.
void SetConnected(bool connected);
@@ -98,6 +98,7 @@
GCMConnectionObserver* last_connection_observer_;
GCMConnectionObserver* removed_connection_observer_;
net::IPEndPoint ip_endpoint_;
+ base::Time last_token_fetch_time_;
DISALLOW_COPY_AND_ASSIGN(CustomFakeGCMDriver);
};
@@ -141,6 +142,15 @@
removed_connection_observer_ = NULL;
}
+
+base::Time CustomFakeGCMDriver::GetLastTokenFetchTime() {
+ return last_token_fetch_time_;
+}
+
+void CustomFakeGCMDriver::SetLastTokenFetchTime(const base::Time& time) {
+ last_token_fetch_time_ = time;
+}
+
} // namespace
class GCMAccountTrackerTest : public testing::Test {
@@ -165,6 +175,11 @@
GCMAccountTracker* tracker() { return tracker_.get(); }
CustomFakeGCMDriver* driver() { return &driver_; }
+ // Accessors to private methods of account tracker.
+ bool IsFetchingRequired() const;
+ bool IsTokenReportingRequired() const;
+ base::TimeDelta GetTimeToNextTokenReporting() const;
+
private:
CustomFakeGCMDriver driver_;
@@ -237,6 +252,18 @@
GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE));
}
+bool GCMAccountTrackerTest::IsFetchingRequired() const {
+ return tracker_->IsTokenFetchingRequired();
+}
+
+bool GCMAccountTrackerTest::IsTokenReportingRequired() const {
+ return tracker_->IsTokenReportingRequired();
+}
+
+base::TimeDelta GCMAccountTrackerTest::GetTimeToNextTokenReporting() const {
+ return tracker_->GetTimeToNextTokenReporting();
+}
+
TEST_F(GCMAccountTrackerTest, NoAccounts) {
EXPECT_FALSE(driver()->update_accounts_called());
tracker()->Start();
@@ -403,7 +430,7 @@
EXPECT_EQ(1UL, tracker()->get_pending_token_request_count());
}
-TEST_F(GCMAccountTrackerTest, IvalidateExpiredTokens) {
+TEST_F(GCMAccountTrackerTest, InvalidateExpiredTokens) {
StartAccountSignIn(kAccountId1);
StartAccountSignIn(kAccountId2);
tracker()->Start();
@@ -421,6 +448,63 @@
EXPECT_EQ(1UL, tracker()->get_pending_token_request_count());
}
+// Testing for whether there are still more tokens to be fetched. Typically the
+// need for token fetching triggers immediate request, unless there is no
+// connection, that is why connection is set on and off in this test.
+TEST_F(GCMAccountTrackerTest, IsTokenFetchingRequired) {
+ tracker()->Start();
+ driver()->SetConnected(false);
+ EXPECT_FALSE(IsFetchingRequired());
+ StartAccountSignIn(kAccountId1);
+ FinishAccountSignIn(kAccountId1);
+ EXPECT_TRUE(IsFetchingRequired());
+
+ driver()->SetConnected(true);
+ EXPECT_FALSE(IsFetchingRequired()); // Indicates that fetching has started.
+ IssueAccessToken(kAccountId1);
+ EXPECT_FALSE(IsFetchingRequired());
+
+ driver()->SetConnected(false);
+ StartAccountSignIn(kAccountId2);
+ FinishAccountSignIn(kAccountId2);
+ EXPECT_TRUE(IsFetchingRequired());
+
+ IssueExpiredAccessToken(kAccountId2);
+ // Make sure that if the token was expired it is still needed.
+ EXPECT_TRUE(IsFetchingRequired());
+}
+
+// Tests what is the expected time to the next token fetching.
+TEST_F(GCMAccountTrackerTest, GetTimeToNextTokenReporting) {
+ tracker()->Start();
+ // At this point the last token fetch time is never.
+ EXPECT_EQ(base::TimeDelta(), GetTimeToNextTokenReporting());
+
+ driver()->SetLastTokenFetchTime(base::Time::Now());
+ EXPECT_TRUE(GetTimeToNextTokenReporting() <=
+ base::TimeDelta::FromSeconds(12 * 60 * 60));
+}
+
+// Tests conditions when token reporting is required.
+TEST_F(GCMAccountTrackerTest, IsTokenReportingRequired) {
+ tracker()->Start();
+ // Required because it is overdue.
+ EXPECT_TRUE(IsTokenReportingRequired());
+
+ // Not required because it just happened.
+ driver()->SetLastTokenFetchTime(base::Time::Now());
+ EXPECT_FALSE(IsTokenReportingRequired());
+
+ SignInAccount(kAccountId1);
+ IssueAccessToken(kAccountId1);
+ driver()->ResetResults();
+ // Reporting was triggered, which means testing for required will give false,
+ // but we have the update call.
+ SignOutAccount(kAccountId1);
+ EXPECT_TRUE(driver()->update_accounts_called());
+ EXPECT_FALSE(IsTokenReportingRequired());
+}
+
// TODO(fgorski): Add test for adding account after removal >> make sure it does
// not mark removal.
diff --git a/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc b/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc
index cc0ff76..96d53cf 100644
--- a/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc
+++ b/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc
@@ -119,6 +119,12 @@
if (!screenlock_bridge_->IsLocked())
return;
+ // Do nothing when auth type is online.
+ if (screenlock_bridge_->lock_handler()->GetAuthType(user_email_) ==
+ ScreenlockBridge::LockHandler::ONLINE_SIGN_IN) {
+ return;
+ }
+
// No hardlock UI for trial run.
if (!is_trial_run_ && hardlock_state_ != NO_HARDLOCK) {
ShowHardlockUI();
@@ -313,8 +319,7 @@
// Do not override online signin.
const ScreenlockBridge::LockHandler::AuthType existing_auth_type =
screenlock_bridge_->lock_handler()->GetAuthType(user_email_);
- if (existing_auth_type == ScreenlockBridge::LockHandler::ONLINE_SIGN_IN)
- return;
+ DCHECK_NE(ScreenlockBridge::LockHandler::ONLINE_SIGN_IN, existing_auth_type);
if (state_ == STATE_AUTHENTICATED) {
if (existing_auth_type != ScreenlockBridge::LockHandler::USER_CLICK) {
diff --git a/chrome/browser/signin/easy_unlock_screenlock_state_handler_unittest.cc b/chrome/browser/signin/easy_unlock_screenlock_state_handler_unittest.cc
index 0b020f9..36c18b4 100644
--- a/chrome/browser/signin/easy_unlock_screenlock_state_handler_unittest.cc
+++ b/chrome/browser/signin/easy_unlock_screenlock_state_handler_unittest.cc
@@ -768,6 +768,7 @@
state_handler_->ChangeState(states[i]);
EXPECT_EQ(ScreenlockBridge::LockHandler::ONLINE_SIGN_IN,
lock_handler_->GetAuthType(user_email_));
+ EXPECT_FALSE(lock_handler_->HasCustomIcon());
}
std::vector<EasyUnlockScreenlockStateHandler::HardlockState> hardlock_states;
@@ -782,6 +783,7 @@
state_handler_->SetHardlockState(hardlock_states[i]);
EXPECT_EQ(ScreenlockBridge::LockHandler::ONLINE_SIGN_IN,
lock_handler_->GetAuthType(user_email_));
+ EXPECT_FALSE(lock_handler_->HasCustomIcon());
}
}
diff --git a/chrome/browser/signin/easy_unlock_toggle_flow.cc b/chrome/browser/signin/easy_unlock_toggle_flow.cc
index bb27764..738d6e7 100644
--- a/chrome/browser/signin/easy_unlock_toggle_flow.cc
+++ b/chrome/browser/signin/easy_unlock_toggle_flow.cc
@@ -10,6 +10,7 @@
#include "base/strings/stringprintf.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/chrome_signin_client_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/common/extensions/extension_constants.h"
@@ -145,13 +146,17 @@
DCHECK_EQ(token_request_.get(), request);
token_request_.reset();
- mint_token_flow_.reset(
- new OAuth2MintTokenFlow(this,
- OAuth2MintTokenFlow::Parameters(
- extension_misc::kEasyUnlockAppId,
- GetEasyUnlockAppClientId(profile_),
- GetScopes(),
- OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE)));
+ SigninClient* signin_client =
+ ChromeSigninClientFactory::GetForProfile(profile_);
+ std::string signin_scoped_device_id =
+ signin_client->GetSigninScopedDeviceId();
+
+ mint_token_flow_.reset(new OAuth2MintTokenFlow(
+ this,
+ OAuth2MintTokenFlow::Parameters(
+ extension_misc::kEasyUnlockAppId, GetEasyUnlockAppClientId(profile_),
+ GetScopes(), signin_scoped_device_id,
+ OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE)));
mint_token_flow_->Start(profile_->GetRequestContext(), access_token);
}
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index 9fb4b92..29deb31 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -188,6 +188,15 @@
password->RemoveLoginsSyncedBetween(start, end);
}
+// Perform the actual sync data folder deletion.
+// This should only be called on the sync thread.
+void DeleteSyncDataFolder(const base::FilePath& directory_path) {
+ if (base::DirectoryExists(directory_path)) {
+ if (!base::DeleteFile(directory_path, true))
+ LOG(DFATAL) << "Could not delete the Sync Data folder.";
+ }
+}
+
} // anonymous namespace
bool ShouldShowActionOnUI(
@@ -671,6 +680,8 @@
invalidator = provider->GetInvalidationService();
}
+ directory_path_ = profile_->GetPath().Append(sync_folder);
+
backend_.reset(
factory_->CreateSyncBackendHost(
profile_->GetDebugName(),
@@ -807,8 +818,15 @@
}
void ProfileSyncService::ShutdownImpl(syncer::ShutdownReason reason) {
- if (!backend_)
+ if (!backend_) {
+ if (reason == syncer::ShutdownReason::DISABLE_SYNC && sync_thread_) {
+ // If the backend is already shut down when a DISABLE_SYNC happens,
+ // the data directory needs to be cleaned up here.
+ sync_thread_->message_loop()->PostTask(FROM_HERE,
+ base::Bind(&DeleteSyncDataFolder, directory_path_));
+ }
return;
+ }
non_blocking_data_type_manager_.DisconnectSyncBackend();
@@ -2737,3 +2755,17 @@
if (backend_initialized_)
backend_->FlushDirectory();
}
+
+base::FilePath ProfileSyncService::GetDirectoryPathForTest() const {
+ return directory_path_;
+}
+
+base::MessageLoop* ProfileSyncService::GetSyncLoopForTest() const {
+ if (sync_thread_) {
+ return sync_thread_->message_loop();
+ } else if (backend_) {
+ return backend_->GetSyncLoopForTesting();
+ } else {
+ return NULL;
+ }
+}
diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h
index a8bcc3c..5c499a6 100644
--- a/chrome/browser/sync/profile_sync_service.h
+++ b/chrome/browser/sync/profile_sync_service.h
@@ -11,6 +11,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/location.h"
#include "base/memory/scoped_ptr.h"
@@ -788,6 +789,12 @@
// killed in the near future.
void FlushDirectory() const;
+ // Needed to test whether the directory is deleted properly.
+ base::FilePath GetDirectoryPathForTest() const;
+
+ // Sometimes we need to wait for tasks on the sync thread in tests.
+ base::MessageLoop* GetSyncLoopForTest() const;
+
protected:
// Helper to configure the priority data types.
void ConfigurePriorityDataTypes();
@@ -973,7 +980,7 @@
// Clean up prefs and backup DB when rollback is not needed.
void CleanUpBackup();
- // Factory used to create various dependent objects.
+ // Factory used to create various dependent objects.
scoped_ptr<ProfileSyncComponentsFactory> factory_;
// The profile whose data we are synchronizing.
@@ -1156,6 +1163,9 @@
BrowsingDataRemover::Observer* browsing_data_remover_observer_;
+ // The full path to the sync data directory.
+ base::FilePath directory_path_;
+
DISALLOW_COPY_AND_ASSIGN(ProfileSyncService);
};
diff --git a/chrome/browser/sync/test/integration/single_client_directory_sync_test.cc b/chrome/browser/sync/test/integration/single_client_directory_sync_test.cc
new file mode 100644
index 0000000..964707d
--- /dev/null
+++ b/chrome/browser/sync/test/integration/single_client_directory_sync_test.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2014 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.
+
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/time/time.h"
+#include "chrome/browser/sync/profile_sync_service.h"
+#include "chrome/browser/sync/test/integration/sync_test.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+class SingleClientDirectorySyncTest : public SyncTest {
+ public:
+ SingleClientDirectorySyncTest() : SyncTest(SINGLE_CLIENT) {}
+ virtual ~SingleClientDirectorySyncTest() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SingleClientDirectorySyncTest);
+};
+
+void SignalEvent(base::WaitableEvent* e) {
+ e->Signal();
+}
+
+bool WaitForExistingTasksOnLoop(base::MessageLoop* loop) {
+ base::WaitableEvent e(true, false);
+ loop->PostTask(FROM_HERE, base::Bind(&SignalEvent, &e));
+ // Timeout stolen from StatusChangeChecker::GetTimeoutDuration().
+ return e.TimedWait(base::TimeDelta::FromSeconds(45));
+}
+
+IN_PROC_BROWSER_TEST_F(SingleClientDirectorySyncTest,
+ StopThenDisableDeletesDirectory) {
+ ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
+ ProfileSyncService* sync_service = GetSyncService(0);
+ base::FilePath directory_path = sync_service->GetDirectoryPathForTest();
+ ASSERT_TRUE(base::DirectoryExists(directory_path));
+ sync_service->StopAndSuppress();
+ sync_service->DisableForUser();
+
+ // Wait for StartupController::StartUp()'s tasks to finish.
+ base::RunLoop run_loop;
+ base::MessageLoop::current()->PostTask(FROM_HERE, run_loop.QuitClosure());
+ run_loop.Run();
+ // Wait for the directory deletion to finish.
+ base::MessageLoop* sync_loop = sync_service->GetSyncLoopForTest();
+ ASSERT_TRUE(WaitForExistingTasksOnLoop(sync_loop));
+
+ ASSERT_FALSE(base::DirectoryExists(directory_path));
+}
diff --git a/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc b/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc
index 858ae19..baf38d9 100644
--- a/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc
+++ b/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc
@@ -91,7 +91,9 @@
void AutofillPopupViewAndroid::SuggestionSelected(JNIEnv* env,
jobject obj,
jint list_index) {
- controller_->AcceptSuggestion(list_index);
+ // Race: Hide() may have already run.
+ if (controller_)
+ controller_->AcceptSuggestion(list_index);
}
void AutofillPopupViewAndroid::PopupDismissed(JNIEnv* env, jobject obj) {
diff --git a/chrome/browser/ui/android/website_settings_popup_android.cc b/chrome/browser/ui/android/website_settings_popup_android.cc
index dcece72..f26ae56 100644
--- a/chrome/browser/ui/android/website_settings_popup_android.cc
+++ b/chrome/browser/ui/android/website_settings_popup_android.cc
@@ -104,7 +104,7 @@
std::vector<ContentSettingsType> permissions_to_display;
permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_GEOLOCATION);
permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM);
- permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
+ permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING);
permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_IMAGES);
permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_JAVASCRIPT);
permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_POPUPS);
diff --git a/chrome/browser/ui/browser_instant_controller.cc b/chrome/browser/ui/browser_instant_controller.cc
index 73d08d5..c579176 100644
--- a/chrome/browser/ui/browser_instant_controller.cc
+++ b/chrome/browser/ui/browser_instant_controller.cc
@@ -19,6 +19,7 @@
#include "chrome/browser/ui/search/search_model.h"
#include "chrome/browser/ui/search/search_tab_helper.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/instant_types.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/user_metrics.h"
@@ -73,6 +74,7 @@
const base::string16& search_terms =
chrome::ExtractSearchTermsFromURL(profile(), url);
+ EmbeddedSearchRequestParams request_params(url);
if (search_terms.empty())
return false;
@@ -82,7 +84,7 @@
if (prerenderer->CanCommitQuery(GetActiveWebContents(), search_terms)) {
// Submit query to render the prefetched results. Browser will swap the
// prerendered contents with the active tab contents.
- prerenderer->Commit(search_terms);
+ prerenderer->Commit(search_terms, request_params);
return false;
} else {
prerenderer->Cancel();
@@ -93,8 +95,7 @@
// InstantController.
if (!chrome::IsQueryExtractionAllowedForURL(profile(), url))
return false;
-
- return instant_.SubmitQuery(search_terms);
+ return instant_.SubmitQuery(search_terms, request_params);
}
Profile* BrowserInstantController::profile() const {
diff --git a/chrome/browser/ui/extensions/extension_action_view_controller.cc b/chrome/browser/ui/extensions/extension_action_view_controller.cc
index 82a28d5..5ee63c8 100644
--- a/chrome/browser/ui/extensions/extension_action_view_controller.cc
+++ b/chrome/browser/ui/extensions/extension_action_view_controller.cc
@@ -16,6 +16,7 @@
#include "chrome/browser/ui/extensions/extension_action_platform_delegate.h"
#include "chrome/browser/ui/toolbar/toolbar_action_view_delegate.h"
#include "chrome/common/extensions/api/extension_action/action_info.h"
+#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_constants.h"
#include "ui/gfx/image/image_skia.h"
@@ -34,7 +35,9 @@
view_delegate_(nullptr),
platform_delegate_(ExtensionActionPlatformDelegate::Create(this)),
icon_factory_(browser->profile(), extension, extension_action, this),
- icon_observer_(nullptr) {
+ icon_observer_(nullptr),
+ extension_registry_(
+ extensions::ExtensionRegistry::Get(browser_->profile())) {
DCHECK(extension_action);
DCHECK(extension_action->action_type() == ActionInfo::TYPE_PAGE ||
extension_action->action_type() == ActionInfo::TYPE_BROWSER);
@@ -56,10 +59,16 @@
gfx::Image ExtensionActionViewController::GetIcon(
content::WebContents* web_contents) {
+ if (!ExtensionIsValid())
+ return gfx::Image();
+
return icon_factory_.GetIcon(SessionTabHelper::IdForTab(web_contents));
}
gfx::ImageSkia ExtensionActionViewController::GetIconWithBadge() {
+ if (!ExtensionIsValid())
+ return gfx::ImageSkia();
+
content::WebContents* web_contents = view_delegate_->GetCurrentWebContents();
gfx::Size spacing(0, 3);
gfx::ImageSkia icon = *GetIcon(web_contents).ToImageSkia();
@@ -70,11 +79,17 @@
}
base::string16 ExtensionActionViewController::GetActionName() const {
+ if (!ExtensionIsValid())
+ return base::string16();
+
return base::UTF8ToUTF16(extension_->name());
}
base::string16 ExtensionActionViewController::GetAccessibleName(
content::WebContents* web_contents) const {
+ if (!ExtensionIsValid())
+ return base::string16();
+
std::string title =
extension_action()->GetTitle(SessionTabHelper::IdForTab(web_contents));
return base::UTF8ToUTF16(title.empty() ? extension()->name() : title);
@@ -87,12 +102,18 @@
bool ExtensionActionViewController::IsEnabled(
content::WebContents* web_contents) const {
+ if (!ExtensionIsValid())
+ return false;
+
return extension_action_->GetIsVisible(
SessionTabHelper::IdForTab(web_contents));
}
bool ExtensionActionViewController::HasPopup(
content::WebContents* web_contents) const {
+ if (!ExtensionIsValid())
+ return false;
+
int tab_id = SessionTabHelper::IdForTab(web_contents);
return (tab_id < 0) ? false : extension_action_->HasPopup(tab_id);
}
@@ -120,6 +141,9 @@
bool ExtensionActionViewController::ExecuteAction(PopupShowAction show_action,
bool grant_tab_permissions) {
+ if (!ExtensionIsValid())
+ return false;
+
if (extensions::ExtensionActionAPI::Get(browser_->profile())
->ExecuteExtensionAction(
extension_, browser_, grant_tab_permissions) ==
@@ -137,12 +161,18 @@
gfx::Canvas* canvas,
const gfx::Rect& bounds,
content::WebContents* web_contents) const {
+ if (!ExtensionIsValid())
+ return;
+
int tab_id = SessionTabHelper::IdForTab(web_contents);
if (tab_id >= 0)
extension_action_->PaintBadge(canvas, bounds, tab_id);
}
void ExtensionActionViewController::RegisterCommand() {
+ if (!ExtensionIsValid())
+ return;
+
platform_delegate_->RegisterCommand();
}
@@ -157,9 +187,16 @@
view_delegate_->UpdateState();
}
+bool ExtensionActionViewController::ExtensionIsValid() const {
+ return extension_registry_->enabled_extensions().Contains(extension_->id());
+}
+
bool ExtensionActionViewController::GetExtensionCommand(
extensions::Command* command) {
DCHECK(command);
+ if (!ExtensionIsValid())
+ return false;
+
CommandService* command_service = CommandService::Get(browser_->profile());
if (extension_action_->action_type() == ActionInfo::TYPE_PAGE) {
return command_service->GetPageActionCommand(
@@ -173,6 +210,9 @@
PopupShowAction show_action,
const GURL& popup_url,
bool grant_tab_permissions) {
+ if (!ExtensionIsValid())
+ return false;
+
bool already_showing = platform_delegate_->IsShowingPopup();
// Always hide the current popup, even if it's not owned by this extension.
diff --git a/chrome/browser/ui/extensions/extension_action_view_controller.h b/chrome/browser/ui/extensions/extension_action_view_controller.h
index 77ae2f5..e703310 100644
--- a/chrome/browser/ui/extensions/extension_action_view_controller.h
+++ b/chrome/browser/ui/extensions/extension_action_view_controller.h
@@ -18,10 +18,14 @@
namespace extensions {
class Command;
class Extension;
+class ExtensionRegistry;
}
// The platform-independent controller for an ExtensionAction that is shown on
// the toolbar (such as a page or browser action).
+// Since this class doesn't own the extension or extension action in question,
+// be sure to check for validity using ExtensionIsValid() before using those
+// members (see also comments above ExtensionIsValid()).
class ExtensionActionViewController
: public ToolbarActionViewController,
public ExtensionActionIconFactory::Observer,
@@ -77,6 +81,12 @@
// ExtensionActionIconFactory::Observer:
void OnIconUpdated() override;
+ // Checks if the associated |extension| is still valid by checking its
+ // status in the registry. Since the OnExtensionUnloaded() notifications are
+ // not in a deterministic order, it's possible that the view tries to refresh
+ // itself before we're notified to remove it.
+ bool ExtensionIsValid() const;
+
// Executes the extension action with |show_action|. If
// |grant_tab_permissions| is true, this will grant the extension active tab
// permissions. Only do this if this was done through a user action (and not
@@ -118,6 +128,9 @@
// has been updated.
ExtensionActionIconFactory::Observer* icon_observer_;
+ // The associated ExtensionRegistry; cached for quick checking.
+ extensions::ExtensionRegistry* extension_registry_;
+
DISALLOW_COPY_AND_ASSIGN(ExtensionActionViewController);
};
diff --git a/chrome/browser/ui/search/instant_controller.cc b/chrome/browser/ui/search/instant_controller.cc
index c6edfdd..c0be4f5 100644
--- a/chrome/browser/ui/search/instant_controller.cc
+++ b/chrome/browser/ui/search/instant_controller.cc
@@ -78,13 +78,14 @@
InstantController::~InstantController() {
}
-bool InstantController::SubmitQuery(const base::string16& search_terms) {
+bool InstantController::SubmitQuery(const base::string16& search_terms,
+ const EmbeddedSearchRequestParams& params) {
if (instant_tab_ && instant_tab_->supports_instant() &&
search_mode_.is_origin_search()) {
// Use |instant_tab_| to run the query if we're already on a search results
// page. (NOTE: in particular, we do not send the query to NTPs.)
SearchTabHelper::FromWebContents(instant_tab_->web_contents())->Submit(
- search_terms);
+ search_terms, params);
instant_tab_->web_contents()->Focus();
EnsureSearchTermsAreSet(instant_tab_->web_contents(), search_terms);
return true;
diff --git a/chrome/browser/ui/search/instant_controller.h b/chrome/browser/ui/search/instant_controller.h
index d7b7b09..44ccf77 100644
--- a/chrome/browser/ui/search/instant_controller.h
+++ b/chrome/browser/ui/search/instant_controller.h
@@ -23,6 +23,7 @@
class InstantService;
class InstantTab;
class Profile;
+struct EmbeddedSearchRequestParams;
namespace content {
class WebContents;
@@ -49,7 +50,8 @@
// Called if the browser is navigating to a search URL for |search_terms| with
// search-term-replacement enabled. If |instant_tab_| can be used to process
// the search, this does so and returns true. Else, returns false.
- bool SubmitQuery(const base::string16& search_terms);
+ bool SubmitQuery(const base::string16& search_terms,
+ const EmbeddedSearchRequestParams& params);
// The search mode in the active tab has changed. Bind |instant_tab_| if the
// |new_mode| reflects an Instant search results page.
diff --git a/chrome/browser/ui/search/instant_search_prerenderer.cc b/chrome/browser/ui/search/instant_search_prerenderer.cc
index e7ed452..94b94de 100644
--- a/chrome/browser/ui/search/instant_search_prerenderer.cc
+++ b/chrome/browser/ui/search/instant_search_prerenderer.cc
@@ -100,10 +100,12 @@
SetSuggestionToPrefetch(suggestion);
}
-void InstantSearchPrerenderer::Commit(const base::string16& query) {
+void InstantSearchPrerenderer::Commit(
+ const base::string16& query,
+ const EmbeddedSearchRequestParams& params) {
DCHECK(prerender_handle_);
DCHECK(prerender_contents());
- SearchTabHelper::FromWebContents(prerender_contents())->Submit(query);
+ SearchTabHelper::FromWebContents(prerender_contents())->Submit(query, params);
}
bool InstantSearchPrerenderer::CanCommitQuery(
diff --git a/chrome/browser/ui/search/instant_search_prerenderer.h b/chrome/browser/ui/search/instant_search_prerenderer.h
index dba9041..797bd57 100644
--- a/chrome/browser/ui/search/instant_search_prerenderer.h
+++ b/chrome/browser/ui/search/instant_search_prerenderer.h
@@ -61,7 +61,8 @@
// Tells the Instant search base page to render the search results for the
// given |query|.
- void Commit(const base::string16& query);
+ void Commit(const base::string16& query,
+ const EmbeddedSearchRequestParams& params);
// Returns true if the prerendered page can be used to process the search for
// the given |source|.
diff --git a/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc b/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc
index 8501ea4..b708b85 100644
--- a/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc
+++ b/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc
@@ -21,8 +21,10 @@
#include "chrome/browser/search/instant_service.h"
#include "chrome/browser/search/instant_unittest_base.h"
#include "chrome/browser/search/search.h"
+#include "chrome/browser/ui/browser_instant_controller.h"
#include "chrome/browser/ui/search/search_tab_helper.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/instant_types.h"
#include "chrome/common/render_messages.h"
#include "components/omnibox/autocomplete_match.h"
#include "content/public/browser/navigation_controller.h"
@@ -295,7 +297,7 @@
base::string16 query = ASCIIToUTF16("flowers");
PrerenderSearchQuery(query);
InstantSearchPrerenderer* prerenderer = GetInstantSearchPrerenderer();
- prerenderer->Commit(query);
+ prerenderer->Commit(query, EmbeddedSearchRequestParams());
EXPECT_TRUE(MessageWasSent(ChromeViewMsg_SearchBoxSubmit::ID));
}
@@ -493,4 +495,30 @@
EXPECT_EQ(GetPrerenderURL(), GetActiveWebContents()->GetURL());
EXPECT_EQ(static_cast<PrerenderHandle*>(NULL), prerender_handle());
}
+
+TEST_F(TestUsePrerenderPage, SetEmbeddedSearchRequestParams) {
+ PrerenderSearchQuery(ASCIIToUTF16("foo"));
+ EXPECT_TRUE(browser()->instant_controller());
+
+ // Open a search results page. Query extraction flag is disabled in field
+ // trials. Search results page URL does not contain search terms replacement
+ // key.
+ GURL url("https://www.google.com/url?bar=foo&aqs=chrome...0&ie=utf-8&oq=f");
+ browser()->instant_controller()->OpenInstant(CURRENT_TAB, url);
+ content::MockRenderProcessHost* process =
+ static_cast<content::MockRenderProcessHost*>(
+ prerender_contents()->GetRenderViewHost()->GetProcess());
+ const IPC::Message* message = process->sink().GetFirstMessageMatching(
+ ChromeViewMsg_SearchBoxSubmit::ID);
+ ASSERT_TRUE(message);
+
+ // Verify the IPC message params.
+ Tuple2<base::string16, EmbeddedSearchRequestParams> params;
+ ChromeViewMsg_SearchBoxSubmit::Read(message, ¶ms);
+ EXPECT_EQ("foo", base::UTF16ToASCII(params.a));
+ EXPECT_EQ("f", base::UTF16ToASCII(params.b.original_query));
+ EXPECT_EQ("utf-8", base::UTF16ToASCII(params.b.input_encoding));
+ EXPECT_EQ("", base::UTF16ToASCII(params.b.rlz_parameter_value));
+ EXPECT_EQ("chrome...0", base::UTF16ToASCII(params.b.assisted_query_stats));
+}
#endif
diff --git a/chrome/browser/ui/search/search_ipc_router.cc b/chrome/browser/ui/search/search_ipc_router.cc
index c81a1e9..9e592c5 100644
--- a/chrome/browser/ui/search/search_ipc_router.cc
+++ b/chrome/browser/ui/search/search_ipc_router.cc
@@ -136,11 +136,12 @@
Send(new ChromeViewMsg_SearchBoxToggleVoiceSearch(routing_id()));
}
-void SearchIPCRouter::Submit(const base::string16& text) {
+void SearchIPCRouter::Submit(const base::string16& text,
+ const EmbeddedSearchRequestParams& params) {
if (!policy_->ShouldSubmitQuery())
return;
- Send(new ChromeViewMsg_SearchBoxSubmit(routing_id(), text));
+ Send(new ChromeViewMsg_SearchBoxSubmit(routing_id(), text, params));
}
void SearchIPCRouter::OnTabActivated() {
diff --git a/chrome/browser/ui/search/search_ipc_router.h b/chrome/browser/ui/search/search_ipc_router.h
index b2af4ef..e5ab662 100644
--- a/chrome/browser/ui/search/search_ipc_router.h
+++ b/chrome/browser/ui/search/search_ipc_router.h
@@ -160,7 +160,8 @@
void ToggleVoiceSearch();
// Tells the page that the user pressed Enter in the omnibox.
- void Submit(const base::string16& text);
+ void Submit(const base::string16& text,
+ const EmbeddedSearchRequestParams& params);
// Called when the tab corresponding to |this| instance is activated.
void OnTabActivated();
diff --git a/chrome/browser/ui/search/search_ipc_router_unittest.cc b/chrome/browser/ui/search/search_ipc_router_unittest.cc
index 2d33e1f..d4836c6 100644
--- a/chrome/browser/ui/search/search_ipc_router_unittest.cc
+++ b/chrome/browser/ui/search/search_ipc_router_unittest.cc
@@ -871,7 +871,7 @@
.WillOnce(testing::Return(true));
process()->sink().ClearMessages();
- GetSearchIPCRouter().Submit(base::string16());
+ GetSearchIPCRouter().Submit(base::string16(), EmbeddedSearchRequestParams());
EXPECT_TRUE(MessageWasSent(ChromeViewMsg_SearchBoxSubmit::ID));
}
@@ -883,7 +883,7 @@
.WillOnce(testing::Return(false));
process()->sink().ClearMessages();
- GetSearchIPCRouter().Submit(base::string16());
+ GetSearchIPCRouter().Submit(base::string16(), EmbeddedSearchRequestParams());
EXPECT_FALSE(MessageWasSent(ChromeViewMsg_SearchBoxSubmit::ID));
}
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc
index f2c34e7..1ed4f53 100644
--- a/chrome/browser/ui/search/search_tab_helper.cc
+++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -255,8 +255,9 @@
ipc_router_.SetSuggestionToPrefetch(suggestion);
}
-void SearchTabHelper::Submit(const base::string16& text) {
- ipc_router_.Submit(text);
+void SearchTabHelper::Submit(const base::string16& text,
+ const EmbeddedSearchRequestParams& params) {
+ ipc_router_.Submit(text, params);
}
void SearchTabHelper::OnTabActivated() {
diff --git a/chrome/browser/ui/search/search_tab_helper.h b/chrome/browser/ui/search/search_tab_helper.h
index 5b5f460..061e098 100644
--- a/chrome/browser/ui/search/search_tab_helper.h
+++ b/chrome/browser/ui/search/search_tab_helper.h
@@ -80,7 +80,8 @@
void SetSuggestionToPrefetch(const InstantSuggestion& suggestion);
// Tells the page that the user pressed Enter in the omnibox.
- void Submit(const base::string16& text);
+ void Submit(const base::string16& text,
+ const EmbeddedSearchRequestParams& params);
// Called when the tab corresponding to |this| instance is activated.
void OnTabActivated();
diff --git a/chrome/browser/ui/settings_window_manager.cc b/chrome/browser/ui/settings_window_manager.cc
index c60d5ae..5e4954b 100644
--- a/chrome/browser/ui/settings_window_manager.cc
+++ b/chrome/browser/ui/settings_window_manager.cc
@@ -35,6 +35,11 @@
void SettingsWindowManager::ShowChromePageForProfile(Profile* profile,
const GURL& gurl) {
+ // Use the original (non off-the-record) profile for settings unless
+ // this is a guest session.
+ if (!profile->IsGuestSession() && profile->IsOffTheRecord())
+ profile = profile->GetOriginalProfile();
+
// Look for an existing browser window.
Browser* browser = FindBrowserForProfile(profile);
if (browser) {
@@ -62,6 +67,7 @@
params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE;
chrome::Navigate(¶ms);
settings_session_map_[profile] = params.browser->session_id().id();
+ DCHECK(params.browser->is_trusted_source());
FOR_EACH_OBSERVER(SettingsWindowManagerObserver,
observers_, OnNewSettingsWindow(params.browser));
diff --git a/chrome/browser/ui/views/extensions/extension_action_platform_delegate_views.cc b/chrome/browser/ui/views/extensions/extension_action_platform_delegate_views.cc
index c9bac7c..33aba19 100644
--- a/chrome/browser/ui/views/extensions/extension_action_platform_delegate_views.cc
+++ b/chrome/browser/ui/views/extensions/extension_action_platform_delegate_views.cc
@@ -119,8 +119,9 @@
ExtensionActionViewController::PopupShowAction show_action,
const GURL& popup_url,
bool grant_tab_permissions) {
- views::BubbleBorder::Arrow arrow = base::i18n::IsRTL() ?
- views::BubbleBorder::TOP_LEFT : views::BubbleBorder::TOP_RIGHT;
+ // TOP_RIGHT is correct for both RTL and LTR, because the views platform
+ // performs the flipping in RTL cases.
+ views::BubbleBorder::Arrow arrow = views::BubbleBorder::TOP_RIGHT;
views::View* reference_view = GetDelegateViews()->GetReferenceViewForPopup();
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
index a49c387..a6a3872 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
@@ -119,9 +119,16 @@
gfx::Image avatar;
gfx::Image taskbar_badge_avatar;
bool is_rectangle = false;
- AvatarMenuButton::GetAvatarImages(browser_view_->browser()->profile(),
- &avatar, &taskbar_badge_avatar,
- &is_rectangle);
+
+ // Update the avatar button in the window frame and the taskbar overlay.
+ bool should_show_avatar_menu =
+ avatar_button_ || AvatarMenu::ShouldShowAvatarMenu();
+
+ if (!AvatarMenuButton::GetAvatarImages(
+ browser_view_->browser()->profile(), should_show_avatar_menu, &avatar,
+ &taskbar_badge_avatar, &is_rectangle)) {
+ return;
+ }
// Disable the menu when we should not show the menu.
if (avatar_button_ && !AvatarMenu::ShouldShowAvatarMenu())
@@ -194,8 +201,9 @@
gfx::Image avatar;
gfx::Image taskbar_badge_avatar;
bool is_rectangle;
+ // Only need to update the taskbar overlay here.
AvatarMenuButton::GetAvatarImages(browser_view_->browser()->profile(),
- &avatar, &taskbar_badge_avatar,
- &is_rectangle);
+ AvatarMenu::ShouldShowAvatarMenu(), &avatar,
+ &taskbar_badge_avatar, &is_rectangle);
DrawTaskbarDecoration(avatar, taskbar_badge_avatar);
}
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 258cbd1..150d202 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -75,6 +75,7 @@
#include "chrome/browser/ui/views/infobars/infobar_container_view.h"
#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
#include "chrome/browser/ui/views/location_bar/location_icon_view.h"
+#include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h"
#include "chrome/browser/ui/views/omnibox/omnibox_view_views.h"
#include "chrome/browser/ui/views/profiles/avatar_menu_bubble_view.h"
#include "chrome/browser/ui/views/profiles/avatar_menu_button.h"
@@ -821,6 +822,9 @@
// Update all the UI bits.
UpdateTitleBar();
+
+ TranslateBubbleView::CloseBubble();
+ ZoomBubbleView::CloseBubble();
}
void BrowserView::ZoomChangedForActiveTab(bool can_show_bubble) {
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index f842e32..4cd9598 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -971,8 +971,6 @@
browser_->search_model()->voice_search_supported());
RefreshContentSettingViews();
generated_credit_card_view_->Update();
- ZoomBubbleView::CloseBubble();
- TranslateBubbleView::CloseBubble();
RefreshZoomView();
RefreshPageActionViews();
RefreshTranslateIcon();
@@ -1138,6 +1136,8 @@
return false;
const bool was_visible = zoom_view_->visible();
zoom_view_->Update(ZoomController::FromWebContents(web_contents));
+ if (!zoom_view_->visible())
+ ZoomBubbleView::CloseBubble();
return was_visible != zoom_view_->visible();
}
@@ -1154,6 +1154,8 @@
command_updater()->UpdateCommandEnabled(IDC_TRANSLATE_PAGE, enabled);
translate_icon_view_->SetVisible(enabled);
translate_icon_view_->SetToggled(language_state.IsPageTranslated());
+ if (!enabled)
+ TranslateBubbleView::CloseBubble();
}
bool LocationBarView::RefreshManagePasswordsIconView() {
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
index 081b8b2..fd6b6ae 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -69,6 +69,7 @@
if (zoom_bubble_ &&
zoom_bubble_->GetAnchorView() == anchor_view &&
!extension) {
+ DCHECK_EQ(web_contents, zoom_bubble_->web_contents_);
zoom_bubble_->Refresh();
return;
}
@@ -174,6 +175,10 @@
}
void ZoomBubbleView::Close() {
+ // Widget's Close() is async, but we don't want to use zoom_bubble_ after
+ // this. Additionally web_contents_ may have been destroyed.
+ zoom_bubble_ = NULL;
+ web_contents_ = NULL;
GetWidget()->Close();
}
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
index a8068ba..e76c8cc 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
@@ -95,7 +95,7 @@
immersive_controller->GetRevealedLock(
ImmersiveModeController::ANIMATE_REVEAL_NO));
ASSERT_TRUE(immersive_controller->IsRevealed());
- EXPECT_TRUE(ZoomBubbleView::zoom_bubble_->GetWidget()->IsClosed());
+ EXPECT_EQ(NULL, ZoomBubbleView::zoom_bubble_);
// The zoom bubble should be anchored when it is shown in immersive fullscreen
// and the top-of-window views are revealed.
diff --git a/chrome/browser/ui/views/profiles/avatar_menu_button.cc b/chrome/browser/ui/views/profiles/avatar_menu_button.cc
index 65d8452..a63e79c 100644
--- a/chrome/browser/ui/views/profiles/avatar_menu_button.cc
+++ b/chrome/browser/ui/views/profiles/avatar_menu_button.cc
@@ -95,10 +95,11 @@
}
// static
-void AvatarMenuButton::GetAvatarImages(Profile* profile,
+bool AvatarMenuButton::GetAvatarImages(Profile* profile,
+ bool should_show_avatar_menu,
gfx::Image* avatar,
gfx::Image* taskbar_badge_avatar,
- bool *is_rectangle) {
+ bool* is_rectangle) {
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
if (profile->GetProfileType() == Profile::GUEST_PROFILE) {
*avatar = rb.
@@ -114,12 +115,12 @@
taskbar_badge_avatar,
&is_badge_rectangle);
#endif
- } else if (AvatarMenu::ShouldShowAvatarMenu()) {
+ } else if (should_show_avatar_menu) {
ProfileInfoCache& cache =
g_browser_process->profile_manager()->GetProfileInfoCache();
size_t index = cache.GetIndexOfProfileWithPath(profile->GetPath());
if (index == std::string::npos)
- return;
+ return false;
if (switches::IsNewAvatarMenu()) {
*avatar = cache.GetAvatarIconOfProfileAtIndex(index);
@@ -138,6 +139,7 @@
AvatarMenu::GetImageForMenuButton(profile, avatar, is_rectangle);
}
}
+ return true;
}
// views::ViewTargeterDelegate:
diff --git a/chrome/browser/ui/views/profiles/avatar_menu_button.h b/chrome/browser/ui/views/profiles/avatar_menu_button.h
index 6bab639..343e467 100644
--- a/chrome/browser/ui/views/profiles/avatar_menu_button.h
+++ b/chrome/browser/ui/views/profiles/avatar_menu_button.h
@@ -54,11 +54,13 @@
// Get avatar images for the profile. |avatar| is used in the browser window
// whereas |taskbar_badge_avatar| is used for the OS taskbar. If
// |taskbar_badge_avatar| is empty then |avatar| should be used for the
- // taskbar as well.
- static void GetAvatarImages(Profile* profile,
+ // taskbar as well. Returns false if the cache doesn't have an entry for a
+ // Profile::REGULAR_PROFILE type |profile|, otherwise return true.
+ static bool GetAvatarImages(Profile* profile,
+ bool should_show_avatar_menu,
gfx::Image* avatar,
gfx::Image* taskbar_badge_avatar,
- bool *is_rectangle);
+ bool* is_rectangle);
private:
// views::ViewTargeterDelegate:
diff --git a/chrome/browser/ui/views/toolbar/chevron_menu_button.cc b/chrome/browser/ui/views/toolbar/chevron_menu_button.cc
index a965b47..68f9340 100644
--- a/chrome/browser/ui/views/toolbar/chevron_menu_button.cc
+++ b/chrome/browser/ui/views/toolbar/chevron_menu_button.cc
@@ -416,16 +416,24 @@
}
int ChevronMenuButton::OnPerformDrop(const ui::DropTargetEvent& event) {
+ weak_factory_.InvalidateWeakPtrs();
return ui::DragDropTypes::DRAG_MOVE;
}
void ChevronMenuButton::OnMenuButtonClicked(views::View* source,
const gfx::Point& point) {
DCHECK_EQ(this, source);
- ShowOverflowMenu(false);
+ // The menu could already be open if a user dragged an item over it but
+ // ultimately dropped elsewhere (as in that case the menu will close on a
+ // timer). In this case, the click should close the open menu.
+ if (menu_controller_)
+ menu_controller_->CloseMenu();
+ else
+ ShowOverflowMenu(false);
}
void ChevronMenuButton::ShowOverflowMenu(bool for_drop) {
+ // We should never try to show an overflow menu when one is already visible.
DCHECK(!menu_controller_);
menu_controller_.reset(new MenuController(
this, browser_actions_container_, for_drop));
diff --git a/chrome/browser/ui/website_settings/website_settings.cc b/chrome/browser/ui/website_settings/website_settings.cc
index ac71f0e..ac35488 100644
--- a/chrome/browser/ui/website_settings/website_settings.cc
+++ b/chrome/browser/ui/website_settings/website_settings.cc
@@ -81,6 +81,9 @@
CONTENT_SETTINGS_TYPE_MEDIASTREAM,
CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
+#if defined(OS_ANDROID)
+ CONTENT_SETTINGS_TYPE_PUSH_MESSAGING,
+#endif
};
bool CertificateTransparencyStatusMatch(
@@ -256,6 +259,7 @@
case CONTENT_SETTINGS_TYPE_FULLSCREEN:
case CONTENT_SETTINGS_TYPE_MOUSELOCK:
case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
+ case CONTENT_SETTINGS_TYPE_PUSH_MESSAGING:
primary_pattern = ContentSettingsPattern::FromURL(site_url_);
secondary_pattern = ContentSettingsPattern::Wildcard();
break;
diff --git a/chrome/browser/ui/website_settings/website_settings_ui.cc b/chrome/browser/ui/website_settings/website_settings_ui.cc
index 4232aa7..21d7f64 100644
--- a/chrome/browser/ui/website_settings/website_settings_ui.cc
+++ b/chrome/browser/ui/website_settings/website_settings_ui.cc
@@ -119,6 +119,7 @@
case CONTENT_SETTINGS_TYPE_GEOLOCATION:
return l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TYPE_LOCATION);
case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
+ case CONTENT_SETTINGS_TYPE_PUSH_MESSAGING:
return l10n_util::GetStringUTF16(
IDS_WEBSITE_SETTINGS_TYPE_NOTIFICATIONS);
case CONTENT_SETTINGS_TYPE_FULLSCREEN:
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
index 94fd12d..3e5210c 100644
--- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
@@ -20,6 +20,7 @@
#include "chrome/browser/chromeos/login/error_screens_histogram_helper.h"
#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
#include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/extensions/signin/gaia_auth_extension_loader.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
@@ -117,6 +118,7 @@
network_state_informer_(network_state_informer),
error_screen_actor_(error_screen_actor),
histogram_helper_(new ErrorScreensHistogramHelper("Enrollment")),
+ auth_extension_(nullptr),
weak_ptr_factory_(this) {
set_async_assets_load_id(OobeUI::kScreenOobeEnrollment);
DCHECK(network_state_informer_.get());
@@ -173,6 +175,11 @@
}
void EnrollmentScreenHandler::Show() {
+ if (!auth_extension_) {
+ Profile* signin_profile = ProfileHelper::GetSigninProfile();
+ auth_extension_.reset(new ScopedGaiaAuthExtension(signin_profile));
+ }
+
if (!page_is_ready())
show_on_init_ = true;
else
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
index 004ddb1..6c5946f 100644
--- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
@@ -15,6 +15,7 @@
#include "chrome/browser/browsing_data/browsing_data_remover.h"
#include "chrome/browser/chromeos/login/enrollment/enrollment_screen_actor.h"
#include "chrome/browser/chromeos/login/ui/webui_login_view.h"
+#include "chrome/browser/extensions/signin/scoped_gaia_auth_extension.h"
#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
#include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
@@ -148,6 +149,9 @@
scoped_ptr<ErrorScreensHistogramHelper> histogram_helper_;
+ // GAIA extension loader.
+ scoped_ptr<ScopedGaiaAuthExtension> auth_extension_;
+
base::WeakPtrFactory<EnrollmentScreenHandler> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(EnrollmentScreenHandler);
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
index 09e64c3..89d4ce3 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
@@ -663,8 +663,10 @@
void NetInternalsMessageHandler::OnGetHistoricNetworkStats(
const base::ListValue* list) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ Profile* profile = Profile::FromWebUI(web_ui());
base::Value* historic_network_info =
- ChromeNetworkDelegate::HistoricNetworkStatsInfoToValue();
+ ChromeNetworkDelegate::HistoricNetworkStatsInfoToValue(
+ profile->GetPrefs());
SendJavascriptCommand("receivedHistoricNetworkStats", historic_network_info);
}
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
index da1e608..c6da4d7 100644
--- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
+++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
@@ -83,7 +83,7 @@
#if defined(OS_CHROMEOS)
"https://www.google.com/support/chromeos/bin/answer.py?answer=1057090";
#else
- "https://support.google.com/chrome/answer/95464#guest";
+ "https://support.google.com/chrome/?p=ui_guest";
#endif
std::string SkColorToRGBAString(SkColor color) {
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
index 1fa9831..7d9e944 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -266,6 +266,8 @@
IDS_PRINT_PREVIEW_MEDIA_SIZE_LABEL);
source->AddLocalizedString("dpiLabel", IDS_PRINT_PREVIEW_DPI_LABEL);
source->AddLocalizedString("dpiItemLabel", IDS_PRINT_PREVIEW_DPI_ITEM_LABEL);
+ source->AddLocalizedString("nonIsotropicDpiItemLabel",
+ IDS_PRINT_PREVIEW_NON_ISOTROPIC_DPI_ITEM_LABEL);
source->AddLocalizedString("destinationSearchTitle",
IDS_PRINT_PREVIEW_DESTINATION_SEARCH_TITLE);
source->AddLocalizedString("accountSelectTitle",
diff --git a/chrome/browser/upgrade_detector_impl.cc b/chrome/browser/upgrade_detector_impl.cc
index bc0e4c7..108f3ab 100644
--- a/chrome/browser/upgrade_detector_impl.cc
+++ b/chrome/browser/upgrade_detector_impl.cc
@@ -134,12 +134,10 @@
bool* is_auto_update_enabled) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- base::string16 app_guid = installer::GetAppGuidForUpdates(IsSystemInstall());
- DCHECK(!app_guid.empty());
// Don't try to turn on autoupdate when we failed previously.
if (is_auto_update_enabled) {
*is_auto_update_enabled =
- GoogleUpdateSettings::AreAutoupdatesEnabled(app_guid);
+ GoogleUpdateSettings::AreAutoupdatesEnabled();
}
*is_unstable_channel = IsUnstableChannel();
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback_task);
diff --git a/chrome/browser/web_applications/web_app_win.cc b/chrome/browser/web_applications/web_app_win.cc
index e9688bd..00f7ac2 100644
--- a/chrome/browser/web_applications/web_app_win.cc
+++ b/chrome/browser/web_applications/web_app_win.cc
@@ -618,7 +618,8 @@
return false;
}
- if (switches::kEnableAppsFileAssociations) {
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableAppsFileAssociations)) {
CreateFileAssociationsForApp(
shortcut_info.extension_id, shortcut_info.title,
shortcut_info.profile_path, file_handlers_info);
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 98ba522..44bad0d 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1049,6 +1049,8 @@
'browser/safe_browsing/safe_browsing_tab_observer.h',
'browser/safe_browsing/srt_global_error_win.cc',
'browser/safe_browsing/srt_global_error_win.h',
+ 'browser/search/contextual_search_policy_handler_android.cc',
+ 'browser/search/contextual_search_policy_handler_android.h',
'browser/search/contextual_search_promo_source_android.cc',
'browser/search/contextual_search_promo_source_android.h',
'browser/search/iframe_source.cc',
@@ -2207,6 +2209,8 @@
'browser/first_run/try_chrome_dialog_view.cc',
'browser/first_run/try_chrome_dialog_view.h',
'browser/first_run/upgrade_util.cc',
+ 'browser/google/did_run_updater_win.cc',
+ 'browser/google/did_run_updater_win.h',
'browser/hang_monitor/hang_crash_dump_win.cc',
'browser/hang_monitor/hang_crash_dump_win.h',
'browser/hang_monitor/hung_plugin_action.cc',
@@ -2766,6 +2770,7 @@
'android/java/src/org/chromium/chrome/browser/JavascriptAppModalDialog.java',
'android/java/src/org/chromium/chrome/browser/NavigationPopup.java',
'android/java/src/org/chromium/chrome/browser/net/spdyproxy/DataReductionProxySettings.java',
+ 'android/java/src/org/chromium/chrome/browser/NotificationUIManager.java',
'android/java/src/org/chromium/chrome/browser/omnibox/AnswersImage.java',
'android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteController.java',
'android/java/src/org/chromium/chrome/browser/omnibox/OmniboxPrerender.java',
@@ -3377,6 +3382,12 @@
'<(allocator_target)',
],
}],
+ ['branding!="Chrome"', {
+ 'sources!': [
+ 'browser/google/did_run_updater_win.cc',
+ 'browser/google/did_run_updater_win.h',
+ ],
+ }],
],
}, { # 'OS!="win"
'sources': [ '<@(chrome_browser_non_win_sources)' ],
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 78b08f0..430201e 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1218,6 +1218,7 @@
'browser/sync/test/integration/single_client_backup_rollback_test.cc',
'browser/sync/test/integration/single_client_bookmarks_sync_test.cc',
'browser/sync/test/integration/single_client_dictionary_sync_test.cc',
+ 'browser/sync/test/integration/single_client_directory_sync_test.cc',
'browser/sync/test/integration/single_client_extensions_sync_test.cc',
'browser/sync/test/integration/single_client_passwords_sync_test.cc',
'browser/sync/test/integration/single_client_preferences_sync_test.cc',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 0440fad..eb5ae7d 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -696,6 +696,7 @@
'browser/safe_browsing/safe_browsing_store_unittest.cc',
'browser/safe_browsing/safe_browsing_util_unittest.cc',
'browser/safe_browsing/two_phase_uploader_unittest.cc',
+ 'browser/search/contextual_search_policy_handler_android_unittest.cc',
'browser/search/hotword_service_unittest.cc',
'browser/search/iframe_source_unittest.cc',
'browser/search/instant_service_unittest.cc',
@@ -1327,6 +1328,7 @@
'common/favicon/favicon_url_parser_unittest.cc',
'common/importer/firefox_importer_utils_unittest.cc',
'common/ini_parser_unittest.cc',
+ 'common/instant_types_unittest.cc',
'common/mac/cfbundle_blocker_unittest.mm',
'common/mac/mock_launchd.cc',
'common/mac/mock_launchd.h',
diff --git a/chrome/common/OWNERS b/chrome/common/OWNERS
index e2dfba2..dfa9816 100644
--- a/chrome/common/OWNERS
+++ b/chrome/common/OWNERS
@@ -36,9 +36,9 @@
per-file spellcheck_result.h=rouslan@chromium.org
# Instant/Search files.
-per-file instant_types.*=kmadhusu@chromium.org
-per-file instant_types.*=jered@chromium.org
-per-file instant_types.*=samarth@chromium.org
+per-file instant_types*=kmadhusu@chromium.org
+per-file instant_types*=jered@chromium.org
+per-file instant_types*=samarth@chromium.org
per-file search_types.*=kmadhusu@chromium.org
per-file search_types.*=jered@chromium.org
per-file search_types.*=samarth@chromium.org
diff --git a/chrome/common/extensions/api/automation.idl b/chrome/common/extensions/api/automation.idl
index 9da10e0..920af3f 100644
--- a/chrome/common/extensions/api/automation.idl
+++ b/chrome/common/extensions/api/automation.idl
@@ -46,6 +46,7 @@
show,
textChanged,
textSelectionChanged,
+ treeChanged,
valueChanged
};
diff --git a/chrome/common/extensions/api/file_manager_private.idl b/chrome/common/extensions/api/file_manager_private.idl
index a8c92bb..a1bad67 100644
--- a/chrome/common/extensions/api/file_manager_private.idl
+++ b/chrome/common/extensions/api/file_manager_private.idl
@@ -458,6 +458,10 @@
// Reasons of offline.
DOMString? reason;
+
+ // Whether the device has a cellular network access or not. i.e. the |type|
+ // can be 'metered' or not.
+ boolean hasCellularNetworkAccess;
};
// Device event dispatched to listeners of onDeviceChaged. See also
diff --git a/chrome/common/instant_types.cc b/chrome/common/instant_types.cc
index 5d199ae..4dca3a5 100644
--- a/chrome/common/instant_types.cc
+++ b/chrome/common/instant_types.cc
@@ -4,6 +4,19 @@
#include "chrome/common/instant_types.h"
+#include "base/strings/utf_string_conversions.h"
+#include "net/base/escape.h"
+
+namespace {
+
+std::string GetComponent(const std::string& url,
+ const url::Component component) {
+ return (component.len > 0) ? url.substr(component.begin, component.len) :
+ std::string();
+}
+
+} // namespace
+
InstantSuggestion::InstantSuggestion() {
}
@@ -68,3 +81,50 @@
has_attribution == rhs.has_attribution &&
logo_alternate == rhs.logo_alternate;
}
+
+const char kSearchQueryKey[] = "q";
+const char kOriginalQueryKey[] = "oq";
+const char kRLZParameterKey[] = "rlz";
+const char kInputEncodingKey[] = "ie";
+const char kAssistedQueryStatsKey[] = "aqs";
+
+EmbeddedSearchRequestParams::EmbeddedSearchRequestParams() {
+}
+
+EmbeddedSearchRequestParams::EmbeddedSearchRequestParams(const GURL& url) {
+ const std::string& url_params(url.query());
+ url::Component query, key, value;
+ query.len = static_cast<int>(url_params.size());
+
+ const net::UnescapeRule::Type unescape_rules =
+ net::UnescapeRule::CONTROL_CHARS | net::UnescapeRule::SPACES |
+ net::UnescapeRule::URL_SPECIAL_CHARS | net::UnescapeRule::NORMAL |
+ net::UnescapeRule::REPLACE_PLUS_WITH_SPACE;
+
+ while (url::ExtractQueryKeyValue(url_params.c_str(), &query, &key, &value)) {
+ if (!key.is_nonempty())
+ continue;
+
+ std::string key_param(GetComponent(url_params, key));
+ std::string value_param(GetComponent(url_params, value));
+ if (key_param == kSearchQueryKey) {
+ search_query = base::UTF8ToUTF16(net::UnescapeURLComponent(
+ value_param, unescape_rules));
+ } else if (key_param == kOriginalQueryKey) {
+ original_query = base::UTF8ToUTF16(net::UnescapeURLComponent(
+ value_param, unescape_rules));
+ } else if (key_param == kRLZParameterKey) {
+ rlz_parameter_value = net::UnescapeAndDecodeUTF8URLComponent(
+ value_param, net::UnescapeRule::NORMAL);
+ } else if (key_param == kInputEncodingKey) {
+ input_encoding = net::UnescapeAndDecodeUTF8URLComponent(
+ value_param, net::UnescapeRule::NORMAL);
+ } else if (key_param == kAssistedQueryStatsKey) {
+ assisted_query_stats = net::UnescapeAndDecodeUTF8URLComponent(
+ value_param, net::UnescapeRule::NORMAL);
+ }
+ }
+}
+
+EmbeddedSearchRequestParams::~EmbeddedSearchRequestParams() {
+}
diff --git a/chrome/common/instant_types.h b/chrome/common/instant_types.h
index e482a52..bc33f89 100644
--- a/chrome/common/instant_types.h
+++ b/chrome/common/instant_types.h
@@ -131,4 +131,40 @@
typedef std::pair<InstantRestrictedID, InstantMostVisitedItem>
InstantMostVisitedItemIDPair;
+// Embedded search request logging stats params.
+extern const char kSearchQueryKey[];
+extern const char kOriginalQueryKey[];
+extern const char kRLZParameterKey[];
+extern const char kInputEncodingKey[];
+extern const char kAssistedQueryStatsKey[];
+
+// A wrapper to hold embedded search request params. Used to tell the server
+// about the search query logging stats at the query submission time.
+struct EmbeddedSearchRequestParams {
+ EmbeddedSearchRequestParams();
+ // Extracts the request params from the |url| and initializes the member
+ // variables.
+ explicit EmbeddedSearchRequestParams(const GURL& url);
+ ~EmbeddedSearchRequestParams();
+
+ // Submitted search query.
+ base::string16 search_query;
+
+ // User typed query.
+ base::string16 original_query;
+
+ // RLZ parameter.
+ base::string16 rlz_parameter_value;
+
+ // Character input encoding type.
+ base::string16 input_encoding;
+
+ // The optional assisted query stats, aka AQS, used for logging purposes.
+ // This string contains impressions of all autocomplete matches shown
+ // at the query submission time. For privacy reasons, we require the
+ // search provider to support HTTPS protocol in order to receive the AQS
+ // param.
+ // For more details, see http://goto.google.com/binary-clients-logging.
+ base::string16 assisted_query_stats;
+};
#endif // CHROME_COMMON_INSTANT_TYPES_H_
diff --git a/chrome/common/instant_types_unittest.cc b/chrome/common/instant_types_unittest.cc
new file mode 100644
index 0000000..47ebebd
--- /dev/null
+++ b/chrome/common/instant_types_unittest.cc
@@ -0,0 +1,69 @@
+// Copyright 2014 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.
+
+#include "chrome/common/instant_types.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+struct TestData {
+ const char* search_request_url;
+ const char* expected_search_query;
+ const char* expected_original_query;
+ const char* expected_rlz_param;
+ const char* expected_input_encoding;
+ const char* expected_assisted_query_stats;
+};
+
+TEST(EmbeddedSearchRequestParams, ExtractParams) {
+ TestData cases[] = {
+ {"https://foo/search?q=google&oq=g&rlz=30ls&ie=utf-8&aqs=chrome..6l5.j04",
+ "google",
+ "g",
+ "30ls",
+ "utf-8",
+ "chrome..6l5.j04"
+ },
+ // Do not populate "rlz" param.
+ {"https://foo/search?q=google%20j&oq=g&ie=utf-8&aqs=chrome.2.65.j04",
+ "google j",
+ "g",
+ "",
+ "utf-8",
+ "chrome.2.65.j04"
+ },
+ // Unescape search query.
+ {"https://foo/search?q=google+j&oq=g&rlz=30&ie=utf-8&aqs=chrome.2.65.j04",
+ "google j",
+ "g",
+ "30",
+ "utf-8",
+ "chrome.2.65.j04"
+ },
+ // Unescape original query.
+ {"https://foo/search?q=g+j%20j&oq=g+j&rlz=30&ie=utf-8&aqs=chrome.2.65.j04",
+ "g j j",
+ "g j",
+ "30",
+ "utf-8",
+ "chrome.2.65.j04"
+ },
+ };
+
+ for (size_t i = 0; i < arraysize(cases); ++i) {
+ EmbeddedSearchRequestParams params(GURL(cases[i].search_request_url));
+ EXPECT_EQ(cases[i].expected_search_query,
+ base::UTF16ToASCII(params.search_query)) << "For index: " << i;
+ EXPECT_EQ(cases[i].expected_original_query,
+ base::UTF16ToASCII(params.original_query)) << "For index: " << i;
+ EXPECT_EQ(cases[i].expected_rlz_param,
+ base::UTF16ToASCII(params.rlz_parameter_value)) <<
+ "For index: " << i;
+ EXPECT_EQ(cases[i].expected_input_encoding,
+ base::UTF16ToASCII(params.input_encoding)) << "For index: " << i;
+ EXPECT_EQ(cases[i].expected_assisted_query_stats,
+ base::UTF16ToASCII(params.assisted_query_stats)) <<
+ "For index: " << i;
+ }
+}
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index 8bba1bc..1d5b491 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -125,6 +125,14 @@
IPC_STRUCT_TRAITS_MEMBER(incognito)
IPC_STRUCT_TRAITS_END()
+IPC_STRUCT_TRAITS_BEGIN(EmbeddedSearchRequestParams)
+ IPC_STRUCT_TRAITS_MEMBER(search_query)
+ IPC_STRUCT_TRAITS_MEMBER(original_query)
+ IPC_STRUCT_TRAITS_MEMBER(rlz_parameter_value)
+ IPC_STRUCT_TRAITS_MEMBER(input_encoding)
+ IPC_STRUCT_TRAITS_MEMBER(assisted_query_stats)
+IPC_STRUCT_TRAITS_END()
+
IPC_STRUCT_TRAITS_BEGIN(InstantSuggestion)
IPC_STRUCT_TRAITS_MEMBER(text)
IPC_STRUCT_TRAITS_MEMBER(metadata)
@@ -267,8 +275,9 @@
IPC_MESSAGE_ROUTED1(ChromeViewMsg_SearchBoxSetSuggestionToPrefetch,
InstantSuggestion /* suggestion */)
-IPC_MESSAGE_ROUTED1(ChromeViewMsg_SearchBoxSubmit,
- base::string16 /* value */)
+IPC_MESSAGE_ROUTED2(ChromeViewMsg_SearchBoxSubmit,
+ base::string16 /* value */,
+ EmbeddedSearchRequestParams /* params */)
IPC_MESSAGE_ROUTED1(ChromeViewMsg_SearchBoxThemeChanged,
ThemeBackgroundInfo /* value */)
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc
index b02be69..70fb2d3 100644
--- a/chrome/installer/setup/setup_main.cc
+++ b/chrome/installer/setup/setup_main.cc
@@ -1207,16 +1207,7 @@
}
} else if (cmd_line.HasSwitch(installer::switches::kReenableAutoupdates)) {
// setup.exe has been asked to attempt to reenable updates for Chrome.
- // Figure out whether we should do so for the multi binaries or the main
- // Chrome product.
- BrowserDistribution::Type dist_type = BrowserDistribution::CHROME_BROWSER;
- if (installer_state->is_multi_install())
- dist_type = BrowserDistribution::CHROME_BINARIES;
-
- BrowserDistribution* dist =
- BrowserDistribution::GetSpecificDistribution(dist_type);
- bool updates_enabled =
- GoogleUpdateSettings::ReenableAutoupdatesForApp(dist->GetAppGuid());
+ bool updates_enabled = GoogleUpdateSettings::ReenableAutoupdates();
*exit_code = updates_enabled ? installer::REENABLE_UPDATES_SUCCEEDED :
installer::REENABLE_UPDATES_FAILED;
} else {
diff --git a/chrome/installer/util/google_update_settings.cc b/chrome/installer/util/google_update_settings.cc
index 3c4cba6..8883413 100644
--- a/chrome/installer/util/google_update_settings.cc
+++ b/chrome/installer/util/google_update_settings.cc
@@ -625,8 +625,8 @@
}
// static
-bool GoogleUpdateSettings::AreAutoupdatesEnabled(
- const base::string16& app_guid) {
+bool GoogleUpdateSettings::AreAutoupdatesEnabled() {
+#if defined(GOOGLE_CHROME_BUILD)
// Check the auto-update check period override. If it is 0 or exceeds the
// maximum timeout, then for all intents and purposes auto updates are
// disabled.
@@ -640,47 +640,78 @@
return false;
}
- UpdatePolicy policy = GetAppUpdatePolicy(app_guid, NULL);
- return (policy == AUTOMATIC_UPDATES || policy == AUTO_UPDATES_ONLY);
+ // Auto updates are subtly broken when Chrome and the binaries have different
+ // overrides in place. If this Chrome cannot possibly be multi-install by
+ // virtue of being a side-by-side installation, simply check Chrome's policy.
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
+ UpdatePolicy app_policy = GetAppUpdatePolicy(dist->GetAppGuid(), nullptr);
+ if (InstallUtil::IsChromeSxSProcess())
+ return app_policy == AUTOMATIC_UPDATES || app_policy == AUTO_UPDATES_ONLY;
+
+ // Otherwise, check for consistency between Chrome and the binaries regardless
+ // of whether or not this Chrome is multi-install since the next update likely
+ // will attempt to migrate it to such.
+ BrowserDistribution* binaries = BrowserDistribution::GetSpecificDistribution(
+ BrowserDistribution::CHROME_BINARIES);
+ return (GetAppUpdatePolicy(binaries->GetAppGuid(), nullptr) == app_policy &&
+ (app_policy == AUTOMATIC_UPDATES || app_policy == AUTO_UPDATES_ONLY));
+#else // defined(GOOGLE_CHROME_BUILD)
+ // Chromium does not auto update.
+ return false;
+#endif // !defined(GOOGLE_CHROME_BUILD)
}
// static
-bool GoogleUpdateSettings::ReenableAutoupdatesForApp(
- const base::string16& app_guid) {
+bool GoogleUpdateSettings::ReenableAutoupdates() {
#if defined(GOOGLE_CHROME_BUILD)
int needs_reset_count = 0;
int did_reset_count = 0;
+ // Reset overrides for Chrome and for the binaries if this Chrome supports
+ // multi-install.
+ std::vector<base::string16> app_guids;
+ app_guids.push_back(BrowserDistribution::GetDistribution()->GetAppGuid());
+ if (!InstallUtil::IsChromeSxSProcess()) {
+ app_guids.push_back(BrowserDistribution::GetSpecificDistribution(
+ BrowserDistribution::CHROME_BINARIES)->GetAppGuid());
+ }
+
UpdatePolicy update_policy = kDefaultUpdatePolicy;
RegKey policy_key;
if (policy_key.Open(HKEY_LOCAL_MACHINE, kPoliciesKey,
KEY_SET_VALUE | KEY_QUERY_VALUE) == ERROR_SUCCESS) {
- // First check the app-specific override value and reset that if needed.
- // Note that this intentionally sets the override to AUTOMATIC_UPDATES
- // even if it was previously AUTO_UPDATES_ONLY. The thinking is that
- // AUTOMATIC_UPDATES is marginally more likely to let a user update and this
- // code is only called when a stuck user asks for updates.
- base::string16 app_update_override(kUpdateOverrideValuePrefix);
- app_update_override.append(app_guid);
+ // Set to true while app-specific overrides are present that allow automatic
+ // updates. When this is the case, the defaults are irrelevant and don't
+ // need to be checked or reset.
+ bool automatic_updates_allowed_by_overrides = true;
DWORD value = 0;
- bool has_app_update_override =
- policy_key.ReadValueDW(app_update_override.c_str(),
- &value) == ERROR_SUCCESS;
- if (has_app_update_override &&
- (!GetUpdatePolicyFromDword(value, &update_policy) ||
- update_policy != GoogleUpdateSettings::AUTOMATIC_UPDATES)) {
- ++needs_reset_count;
- if (policy_key.WriteValue(
- app_update_override.c_str(),
- static_cast<DWORD>(GoogleUpdateSettings::AUTOMATIC_UPDATES)) ==
- ERROR_SUCCESS) {
- ++did_reset_count;
+ for (const base::string16& app_guid : app_guids) {
+ // First check the app-specific override value and reset that if needed.
+ // Note that this intentionally sets the override to AUTOMATIC_UPDATES
+ // even if it was previously AUTO_UPDATES_ONLY. The thinking is that
+ // AUTOMATIC_UPDATES is marginally more likely to let a user update and
+ // this code is only called when a stuck user asks for updates.
+ base::string16 app_update_override(kUpdateOverrideValuePrefix);
+ app_update_override.append(app_guid);
+ if (policy_key.ReadValueDW(app_update_override.c_str(),
+ &value) != ERROR_SUCCESS) {
+ automatic_updates_allowed_by_overrides = false;
+ } else if (!GetUpdatePolicyFromDword(value, &update_policy) ||
+ update_policy != GoogleUpdateSettings::AUTOMATIC_UPDATES) {
+ automatic_updates_allowed_by_overrides = false;
+ ++needs_reset_count;
+ if (policy_key.WriteValue(
+ app_update_override.c_str(),
+ static_cast<DWORD>(GoogleUpdateSettings::AUTOMATIC_UPDATES)) ==
+ ERROR_SUCCESS) {
+ ++did_reset_count;
+ }
}
}
- // If there was no app-specific override policy see if there's a global
+ // If there were no app-specific override policies, see if there's a global
// policy preventing updates and delete it if so.
- if (!has_app_update_override &&
+ if (!automatic_updates_allowed_by_overrides &&
policy_key.ReadValueDW(kUpdatePolicyValue, &value) == ERROR_SUCCESS &&
(!GetUpdatePolicyFromDword(value, &update_policy) ||
update_policy != GoogleUpdateSettings::AUTOMATIC_UPDATES)) {
@@ -706,7 +737,7 @@
// For some reason we couldn't open the policy key with the desired
// permissions to make changes (the most likely reason is that there is no
// policy set). Simply return whether or not we think updates are enabled.
- return AreAutoupdatesEnabled(app_guid);
+ return AreAutoupdatesEnabled();
}
#endif
diff --git a/chrome/installer/util/google_update_settings.h b/chrome/installer/util/google_update_settings.h
index bc66431..ea5a7d5 100644
--- a/chrome/installer/util/google_update_settings.h
+++ b/chrome/installer/util/google_update_settings.h
@@ -243,22 +243,24 @@
static UpdatePolicy GetAppUpdatePolicy(const base::string16& app_guid,
bool* is_overridden);
- // Returns true if the app indicated by |app_guid| should be updated
- // automatically by Google Update based on current autoupdate settings. This
- // is distinct from GetAppUpdatePolicy which checks only a subset of things
- // that can cause an app not to update.
- static bool AreAutoupdatesEnabled(const base::string16& app_guid);
+ // Returns true if Chrome should be updated automatically by Google Update
+ // based on current autoupdate settings. This is distinct from
+ // GetAppUpdatePolicy (which checks only the policy for a given app), as it
+ // checks for general Google Update configuration as well as multi-install
+ // Chrome. Note that for Chromium builds, this returns false since Chromium is
+ // assumed not to autoupdate.
+ static bool AreAutoupdatesEnabled();
- // Attempts to reenable auto-updates for |app_guid| by removing
- // any group policy settings that would block updates from occurring. This is
- // a superset of the things checked by GetAppUpdatePolicy() as
- // GetAppUpdatePolicy() does not check Omaha's AutoUpdateCheckPeriodMinutes
- // setting which will be reset by this method. Will need to be called from an
- // elevated process since those settings live in HKLM. Returns true if there
- // is a reasonable belief that updates are not disabled by policy when this
- // method returns, false otherwise. Note that for Chromium builds, this
- // returns true since Chromium is assumed not to autoupdate.
- static bool ReenableAutoupdatesForApp(const base::string16& app_guid);
+ // Attempts to reenable auto-updates for Chrome by removing any group policy
+ // settings that would block updates from occurring. This is a superset of the
+ // things checked by GetAppUpdatePolicy() as GetAppUpdatePolicy() does not
+ // check Omaha's AutoUpdateCheckPeriodMinutes setting which will be reset by
+ // this method. Will need to be called from an elevated process since those
+ // settings live in HKLM. Returns true if there is a reasonable belief that
+ // updates are not disabled by policy when this method returns, false
+ // otherwise. Note that for Chromium builds, this returns true since Chromium
+ // is assumed not to autoupdate.
+ static bool ReenableAutoupdates();
// Records UMA stats about Chrome's update policy.
static void RecordChromeUpdatePolicyHistograms();
diff --git a/chrome/installer/util/google_update_settings_unittest.cc b/chrome/installer/util/google_update_settings_unittest.cc
index 4504d16..ecab320 100644
--- a/chrome/installer/util/google_update_settings_unittest.cc
+++ b/chrome/installer/util/google_update_settings_unittest.cc
@@ -759,86 +759,91 @@
}
TEST_F(GoogleUpdateSettingsTest, PerAppUpdatesDisabledByPolicy) {
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
EXPECT_TRUE(
- SetUpdatePolicyForAppGuid(kTestProductGuid,
+ SetUpdatePolicyForAppGuid(dist->GetAppGuid(),
GoogleUpdateSettings::UPDATES_DISABLED));
bool is_overridden = false;
GoogleUpdateSettings::UpdatePolicy update_policy =
- GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid,
+ GoogleUpdateSettings::GetAppUpdatePolicy(dist->GetAppGuid(),
&is_overridden);
EXPECT_TRUE(is_overridden);
EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED, update_policy);
- EXPECT_FALSE(GoogleUpdateSettings::AreAutoupdatesEnabled(kTestProductGuid));
+ EXPECT_FALSE(GoogleUpdateSettings::AreAutoupdatesEnabled());
- EXPECT_TRUE(
- GoogleUpdateSettings::ReenableAutoupdatesForApp(kTestProductGuid));
- update_policy = GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid,
+ EXPECT_TRUE(GoogleUpdateSettings::ReenableAutoupdates());
+ update_policy = GoogleUpdateSettings::GetAppUpdatePolicy(dist->GetAppGuid(),
&is_overridden);
// Should still have a policy but now that policy should explicitly enable
// updates.
EXPECT_TRUE(is_overridden);
EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES, update_policy);
- EXPECT_TRUE(GoogleUpdateSettings::AreAutoupdatesEnabled(kTestProductGuid));
+ EXPECT_TRUE(GoogleUpdateSettings::AreAutoupdatesEnabled());
}
TEST_F(GoogleUpdateSettingsTest, PerAppUpdatesEnabledWithGlobalDisabled) {
- // Disable updates globally but enable them for our specific app (the app-
- // specific setting should take precedence).
+ // Disable updates globally but enable them for Chrome (the app-specific
+ // setting should take precedence).
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
+ BrowserDistribution* binaries = BrowserDistribution::GetSpecificDistribution(
+ BrowserDistribution::CHROME_BINARIES);
EXPECT_TRUE(
- SetUpdatePolicyForAppGuid(kTestProductGuid,
+ SetUpdatePolicyForAppGuid(dist->GetAppGuid(),
+ GoogleUpdateSettings::AUTOMATIC_UPDATES));
+ EXPECT_TRUE(
+ SetUpdatePolicyForAppGuid(binaries->GetAppGuid(),
GoogleUpdateSettings::AUTOMATIC_UPDATES));
EXPECT_TRUE(SetGlobalUpdatePolicy(GoogleUpdateSettings::UPDATES_DISABLED));
// Make sure we read this as still having updates enabled.
- EXPECT_TRUE(GoogleUpdateSettings::AreAutoupdatesEnabled(kTestProductGuid));
+ EXPECT_TRUE(GoogleUpdateSettings::AreAutoupdatesEnabled());
// Make sure that the reset action returns true and is a no-op.
- EXPECT_TRUE(
- GoogleUpdateSettings::ReenableAutoupdatesForApp(kTestProductGuid));
+ EXPECT_TRUE(GoogleUpdateSettings::ReenableAutoupdates());
EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES,
- GetUpdatePolicyForAppGuid(kTestProductGuid));
+ GetUpdatePolicyForAppGuid(dist->GetAppGuid()));
+ EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES,
+ GetUpdatePolicyForAppGuid(binaries->GetAppGuid()));
EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED, GetGlobalUpdatePolicy());
}
TEST_F(GoogleUpdateSettingsTest, GlobalUpdatesDisabledByPolicy) {
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
EXPECT_TRUE(SetGlobalUpdatePolicy(GoogleUpdateSettings::UPDATES_DISABLED));
bool is_overridden = false;
// The contract for GetAppUpdatePolicy states that |is_overridden| should be
// set to false when updates are disabled on a non-app-specific basis.
GoogleUpdateSettings::UpdatePolicy update_policy =
- GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid,
+ GoogleUpdateSettings::GetAppUpdatePolicy(dist->GetAppGuid(),
&is_overridden);
EXPECT_FALSE(is_overridden);
EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED, update_policy);
- EXPECT_FALSE(GoogleUpdateSettings::AreAutoupdatesEnabled(kTestProductGuid));
+ EXPECT_FALSE(GoogleUpdateSettings::AreAutoupdatesEnabled());
- EXPECT_TRUE(
- GoogleUpdateSettings::ReenableAutoupdatesForApp(kTestProductGuid));
- update_policy = GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid,
+ EXPECT_TRUE(GoogleUpdateSettings::ReenableAutoupdates());
+ update_policy = GoogleUpdateSettings::GetAppUpdatePolicy(dist->GetAppGuid(),
&is_overridden);
// Policy should now be to enable updates, |is_overridden| should still be
// false.
EXPECT_FALSE(is_overridden);
EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES, update_policy);
- EXPECT_TRUE(GoogleUpdateSettings::AreAutoupdatesEnabled(kTestProductGuid));
+ EXPECT_TRUE(GoogleUpdateSettings::AreAutoupdatesEnabled());
}
TEST_F(GoogleUpdateSettingsTest, UpdatesDisabledByTimeout) {
// Disable updates altogether.
EXPECT_TRUE(SetUpdateTimeoutOverride(0));
- EXPECT_FALSE(GoogleUpdateSettings::AreAutoupdatesEnabled(kTestProductGuid));
- EXPECT_TRUE(
- GoogleUpdateSettings::ReenableAutoupdatesForApp(kTestProductGuid));
- EXPECT_TRUE(GoogleUpdateSettings::AreAutoupdatesEnabled(kTestProductGuid));
+ EXPECT_FALSE(GoogleUpdateSettings::AreAutoupdatesEnabled());
+ EXPECT_TRUE(GoogleUpdateSettings::ReenableAutoupdates());
+ EXPECT_TRUE(GoogleUpdateSettings::AreAutoupdatesEnabled());
// Set the update period to something unreasonable.
EXPECT_TRUE(SetUpdateTimeoutOverride(
GoogleUpdateSettings::kCheckPeriodOverrideMinutesMax + 1));
- EXPECT_FALSE(GoogleUpdateSettings::AreAutoupdatesEnabled(kTestProductGuid));
- EXPECT_TRUE(
- GoogleUpdateSettings::ReenableAutoupdatesForApp(kTestProductGuid));
- EXPECT_TRUE(GoogleUpdateSettings::AreAutoupdatesEnabled(kTestProductGuid));
+ EXPECT_FALSE(GoogleUpdateSettings::AreAutoupdatesEnabled());
+ EXPECT_TRUE(GoogleUpdateSettings::ReenableAutoupdates());
+ EXPECT_TRUE(GoogleUpdateSettings::AreAutoupdatesEnabled());
}
TEST_F(GoogleUpdateSettingsTest, ExperimentsLabelHelperSystem) {
diff --git a/chrome/renderer/resources/extensions/searchbox_api.js b/chrome/renderer/resources/extensions/searchbox_api.js
index 2ddf819..4b5ab3a 100644
--- a/chrome/renderer/resources/extensions/searchbox_api.js
+++ b/chrome/renderer/resources/extensions/searchbox_api.js
@@ -17,6 +17,7 @@
native function GetDisplayInstantResults();
native function GetMostVisitedItemData();
native function GetQuery();
+ native function GetSearchRequestParams();
native function GetRightToLeft();
native function GetStartMargin();
native function GetSuggestionToPrefetch();
@@ -37,6 +38,8 @@
this.__defineGetter__('startMargin', GetStartMargin);
this.__defineGetter__('suggestion', GetSuggestionToPrefetch);
this.__defineGetter__('value', GetQuery);
+ Object.defineProperty(this, 'requestParams',
+ { get: GetSearchRequestParams });
this.focus = function() {
Focus();
diff --git a/chrome/renderer/searchbox/searchbox.cc b/chrome/renderer/searchbox/searchbox.cc
index 7c898c5..f639bfc 100644
--- a/chrome/renderer/searchbox/searchbox.cc
+++ b/chrome/renderer/searchbox/searchbox.cc
@@ -237,6 +237,10 @@
return theme_info_;
}
+const EmbeddedSearchRequestParams& SearchBox::GetEmbeddedSearchRequestParams() {
+ return embedded_search_request_params_;
+}
+
void SearchBox::Focus() {
render_view()->Send(new ChromeViewHostMsg_FocusOmnibox(
render_view()->GetRoutingID(), page_seq_no_, OMNIBOX_FOCUS_VISIBLE));
@@ -426,8 +430,10 @@
}
}
-void SearchBox::OnSubmit(const base::string16& query) {
+void SearchBox::OnSubmit(const base::string16& query,
+ const EmbeddedSearchRequestParams& params) {
query_ = query;
+ embedded_search_request_params_ = params;
if (render_view()->GetWebView() && render_view()->GetWebView()->mainFrame()) {
DVLOG(1) << render_view() << " OnSubmit";
extensions_v8::SearchBoxExtension::DispatchSubmit(
@@ -463,6 +469,7 @@
void SearchBox::Reset() {
query_.clear();
+ embedded_search_request_params_ = EmbeddedSearchRequestParams();
suggestion_ = InstantSuggestion();
start_margin_ = 0;
is_focused_ = false;
diff --git a/chrome/renderer/searchbox/searchbox.h b/chrome/renderer/searchbox/searchbox.h
index cf0ea52..4b32c81 100644
--- a/chrome/renderer/searchbox/searchbox.h
+++ b/chrome/renderer/searchbox/searchbox.h
@@ -86,6 +86,7 @@
void Paste(const base::string16& text);
const ThemeBackgroundInfo& GetThemeBackgroundInfo();
+ const EmbeddedSearchRequestParams& GetEmbeddedSearchRequestParams();
// Sends ChromeViewHostMsg_SetVoiceSearchSupported to the browser.
void SetVoiceSearchSupported(bool supported);
@@ -129,7 +130,8 @@
void OnSetDisplayInstantResults(bool display_instant_results);
void OnSetInputInProgress(bool input_in_progress);
void OnSetSuggestionToPrefetch(const InstantSuggestion& suggestion);
- void OnSubmit(const base::string16& query);
+ void OnSubmit(const base::string16& query,
+ const EmbeddedSearchRequestParams& params);
void OnThemeChanged(const ThemeBackgroundInfo& theme_info);
void OnToggleVoiceSearch();
@@ -151,6 +153,7 @@
InstantRestrictedIDCache<InstantMostVisitedItem> most_visited_items_cache_;
ThemeBackgroundInfo theme_info_;
base::string16 query_;
+ EmbeddedSearchRequestParams embedded_search_request_params_;
int start_margin_;
InstantSuggestion suggestion_;
diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc
index 612287b..250915c 100644
--- a/chrome/renderer/searchbox/searchbox_extension.cc
+++ b/chrome/renderer/searchbox/searchbox_extension.cc
@@ -383,6 +383,10 @@
// Returns true if the Searchbox itself is oriented right-to-left.
static void GetRightToLeft(const v8::FunctionCallbackInfo<v8::Value>& args);
+ // Gets the Embedded Search request params. Used for logging purposes.
+ static void GetSearchRequestParams(
+ const v8::FunctionCallbackInfo<v8::Value>& args);
+
// Gets the start-edge margin to use with extended Instant.
static void GetStartMargin(const v8::FunctionCallbackInfo<v8::Value>& args);
@@ -561,6 +565,8 @@
return v8::FunctionTemplate::New(isolate, GetQuery);
if (name->Equals(v8::String::NewFromUtf8(isolate, "GetRightToLeft")))
return v8::FunctionTemplate::New(isolate, GetRightToLeft);
+ if (name->Equals(v8::String::NewFromUtf8(isolate, "GetSearchRequestParams")))
+ return v8::FunctionTemplate::New(isolate, GetSearchRequestParams);
if (name->Equals(v8::String::NewFromUtf8(isolate, "GetStartMargin")))
return v8::FunctionTemplate::New(isolate, GetStartMargin);
if (name->Equals(v8::String::NewFromUtf8(isolate, "GetSuggestionToPrefetch")))
@@ -746,6 +752,39 @@
}
// static
+void SearchBoxExtensionWrapper::GetSearchRequestParams(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ content::RenderView* render_view = GetRenderView();
+ if (!render_view) return;
+
+ const EmbeddedSearchRequestParams& params =
+ SearchBox::Get(render_view)->GetEmbeddedSearchRequestParams();
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::Handle<v8::Object> data = v8::Object::New(isolate);
+ if (!params.search_query.empty()) {
+ data->Set(v8::String::NewFromUtf8(isolate, kSearchQueryKey),
+ UTF16ToV8String(isolate, params.search_query));
+ }
+ if (!params.original_query.empty()) {
+ data->Set(v8::String::NewFromUtf8(isolate, kOriginalQueryKey),
+ UTF16ToV8String(isolate, params.original_query));
+ }
+ if (!params.rlz_parameter_value.empty()) {
+ data->Set(v8::String::NewFromUtf8(isolate, kRLZParameterKey),
+ UTF16ToV8String(isolate, params.rlz_parameter_value));
+ }
+ if (!params.input_encoding.empty()) {
+ data->Set(v8::String::NewFromUtf8(isolate, kInputEncodingKey),
+ UTF16ToV8String(isolate, params.input_encoding));
+ }
+ if (!params.assisted_query_stats.empty()) {
+ data->Set(v8::String::NewFromUtf8(isolate, kAssistedQueryStatsKey),
+ UTF16ToV8String(isolate, params.assisted_query_stats));
+ }
+ args.GetReturnValue().Set(data);
+}
+
+// static
void SearchBoxExtensionWrapper::GetStartMargin(
const v8::FunctionCallbackInfo<v8::Value>& args) {
content::RenderView* render_view = GetRenderView();
diff --git a/chromeos/settings/timezone_settings.cc b/chromeos/settings/timezone_settings.cc
index 1c8f894..7403b5b 100644
--- a/chromeos/settings/timezone_settings.cc
+++ b/chromeos/settings/timezone_settings.cc
@@ -88,11 +88,13 @@
"Europe/Amsterdam",
"Europe/Belgrade",
"Europe/Berlin",
+ "Europe/Bratislava",
"Europe/Brussels",
"Europe/Budapest",
"Europe/Copenhagen",
"Europe/Ljubljana",
"Europe/Madrid",
+ "Europe/Malta",
"Europe/Oslo",
"Europe/Paris",
"Europe/Prague",
@@ -100,8 +102,10 @@
"Europe/Stockholm",
"Europe/Sarajevo",
"Europe/Tirane",
+ "Europe/Vaduz",
"Europe/Vienna",
"Europe/Warsaw",
+ "Europe/Zagreb",
"Europe/Zurich",
"Africa/Windhoek",
"Africa/Lagos",
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.cc
index d9d6c5c..125d8ac 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.cc
@@ -12,7 +12,8 @@
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_http_job.h"
-#include "net/url_request/url_request_job_factory.h"
+#include "net/url_request/url_request_job_manager.h"
+#include "url/url_constants.h"
namespace data_reduction_proxy {
@@ -46,9 +47,9 @@
return nullptr;
// Returning non-NULL has the effect of restarting the request with the
// supplied job.
- DCHECK(request->url().SchemeIs("http"));
- return request->context()->job_factory()->MaybeCreateJobWithProtocolHandler(
- "http", request, network_delegate);
+ DCHECK(request->url().SchemeIs(url::kHttpScheme));
+ return net::URLRequestJobManager::GetInstance()->CreateJob(
+ request, network_delegate);
}
} // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy_version_header.target.darwin-arm.mk b/components/data_reduction_proxy_version_header.target.darwin-arm.mk
index 8a56cd5..3167295 100644
--- a/components/data_reduction_proxy_version_header.target.darwin-arm.mk
+++ b/components/data_reduction_proxy_version_header.target.darwin-arm.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.10\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.darwin-arm64.mk b/components/data_reduction_proxy_version_header.target.darwin-arm64.mk
index 8a56cd5..3167295 100644
--- a/components/data_reduction_proxy_version_header.target.darwin-arm64.mk
+++ b/components/data_reduction_proxy_version_header.target.darwin-arm64.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.10\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.darwin-mips.mk b/components/data_reduction_proxy_version_header.target.darwin-mips.mk
index 8a56cd5..3167295 100644
--- a/components/data_reduction_proxy_version_header.target.darwin-mips.mk
+++ b/components/data_reduction_proxy_version_header.target.darwin-mips.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.10\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.darwin-mips64.mk b/components/data_reduction_proxy_version_header.target.darwin-mips64.mk
index 8a56cd5..3167295 100644
--- a/components/data_reduction_proxy_version_header.target.darwin-mips64.mk
+++ b/components/data_reduction_proxy_version_header.target.darwin-mips64.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.10\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.darwin-x86.mk b/components/data_reduction_proxy_version_header.target.darwin-x86.mk
index 8a56cd5..3167295 100644
--- a/components/data_reduction_proxy_version_header.target.darwin-x86.mk
+++ b/components/data_reduction_proxy_version_header.target.darwin-x86.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.10\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.darwin-x86_64.mk b/components/data_reduction_proxy_version_header.target.darwin-x86_64.mk
index 8a56cd5..3167295 100644
--- a/components/data_reduction_proxy_version_header.target.darwin-x86_64.mk
+++ b/components/data_reduction_proxy_version_header.target.darwin-x86_64.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.10\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.linux-arm.mk b/components/data_reduction_proxy_version_header.target.linux-arm.mk
index 8a56cd5..3167295 100644
--- a/components/data_reduction_proxy_version_header.target.linux-arm.mk
+++ b/components/data_reduction_proxy_version_header.target.linux-arm.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.10\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.linux-arm64.mk b/components/data_reduction_proxy_version_header.target.linux-arm64.mk
index 8a56cd5..3167295 100644
--- a/components/data_reduction_proxy_version_header.target.linux-arm64.mk
+++ b/components/data_reduction_proxy_version_header.target.linux-arm64.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.10\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.linux-mips.mk b/components/data_reduction_proxy_version_header.target.linux-mips.mk
index 8a56cd5..3167295 100644
--- a/components/data_reduction_proxy_version_header.target.linux-mips.mk
+++ b/components/data_reduction_proxy_version_header.target.linux-mips.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.10\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.linux-mips64.mk b/components/data_reduction_proxy_version_header.target.linux-mips64.mk
index 8a56cd5..3167295 100644
--- a/components/data_reduction_proxy_version_header.target.linux-mips64.mk
+++ b/components/data_reduction_proxy_version_header.target.linux-mips64.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.10\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.linux-x86.mk b/components/data_reduction_proxy_version_header.target.linux-x86.mk
index 8a56cd5..3167295 100644
--- a/components/data_reduction_proxy_version_header.target.linux-x86.mk
+++ b/components/data_reduction_proxy_version_header.target.linux-x86.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.10\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.linux-x86_64.mk b/components/data_reduction_proxy_version_header.target.linux-x86_64.mk
index 8a56cd5..3167295 100644
--- a/components/data_reduction_proxy_version_header.target.linux-x86_64.mk
+++ b/components/data_reduction_proxy_version_header.target.linux-x86_64.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.10\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/enhanced_bookmarks/enhanced_bookmark_model.cc b/components/enhanced_bookmarks/enhanced_bookmark_model.cc
index ffcc02a..e9b8bae 100644
--- a/components/enhanced_bookmarks/enhanced_bookmark_model.cc
+++ b/components/enhanced_bookmarks/enhanced_bookmark_model.cc
@@ -313,10 +313,7 @@
int old_index,
const BookmarkNode* node,
const std::set<GURL>& removed_urls) {
- std::string remote_id = GetRemoteId(node);
- id_map_.erase(remote_id);
- nodes_to_reset_.erase(node);
- set_needs_offline_processing_tasks_.erase(node);
+ RemoveNodeFromMaps(node);
FOR_EACH_OBSERVER(
EnhancedBookmarkModelObserver, observers_, EnhancedBookmarkRemoved(node));
}
@@ -386,6 +383,16 @@
}
}
+void EnhancedBookmarkModel::RemoveNodeFromMaps(const BookmarkNode* node) {
+ for (int i = 0; i < node->child_count(); i++) {
+ RemoveNodeFromMaps(node->GetChild(i));
+ }
+ std::string remote_id = GetRemoteId(node);
+ id_map_.erase(remote_id);
+ nodes_to_reset_.erase(node);
+ set_needs_offline_processing_tasks_.erase(node);
+}
+
void EnhancedBookmarkModel::ScheduleResetDuplicateRemoteIds() {
if (!nodes_to_reset_.empty()) {
base::MessageLoopProxy::current()->PostTask(
diff --git a/components/enhanced_bookmarks/enhanced_bookmark_model.h b/components/enhanced_bookmarks/enhanced_bookmark_model.h
index 4196f64..8bfc566 100644
--- a/components/enhanced_bookmarks/enhanced_bookmark_model.h
+++ b/components/enhanced_bookmarks/enhanced_bookmark_model.h
@@ -165,6 +165,9 @@
// by a (Schedule)ResetDuplicateRemoteIds call when done adding nodes.
void AddToIdMap(const BookmarkNode* node);
+ // Recursively removes a node and all its children from the various maps.
+ void RemoveNodeFromMaps(const BookmarkNode* node);
+
// If there are nodes that needs to reset their remote ids, schedules
// ResetDuplicateRemoteIds to be run asynchronously.
void ScheduleResetDuplicateRemoteIds();
diff --git a/components/enhanced_bookmarks/enhanced_bookmark_model_unittest.cc b/components/enhanced_bookmarks/enhanced_bookmark_model_unittest.cc
index 0d12de1..90855bb 100644
--- a/components/enhanced_bookmarks/enhanced_bookmark_model_unittest.cc
+++ b/components/enhanced_bookmarks/enhanced_bookmark_model_unittest.cc
@@ -752,3 +752,15 @@
bookmark_model_->Remove(node->parent(), node->parent()->GetIndexOf(node));
base::RunLoop().RunUntilIdle();
}
+
+TEST_F(EnhancedBookmarkModelTest,
+ RemoveParentShouldRemoveChildrenFromMaps) {
+ const BookmarkNode* parent = AddFolder();
+ const BookmarkNode* node = AddBookmark("Title", parent);
+ std::string remote_id = GetId(node);
+ EXPECT_EQ(node, model_->BookmarkForRemoteId(remote_id));
+
+ const BookmarkNode* gp = parent->parent();
+ bookmark_model_->Remove(gp, gp->GetIndexOf(parent));
+ EXPECT_FALSE(model_->BookmarkForRemoteId(remote_id));
+}
diff --git a/components/gcm_driver/gcm_client_impl.cc b/components/gcm_driver/gcm_client_impl.cc
index 8fe3df7..4a68dc0 100644
--- a/components/gcm_driver/gcm_client_impl.cc
+++ b/components/gcm_driver/gcm_client_impl.cc
@@ -474,7 +474,7 @@
void GCMClientImpl::SetLastTokenFetchTime(const base::Time& time) {
gcm_store_->SetLastTokenFetchTime(
time,
- base::Bind(&GCMClientImpl::DefaultStoreCallback,
+ base::Bind(&GCMClientImpl::IgnoreWriteResultCallback,
weak_ptr_factory_.GetWeakPtr()));
}
@@ -597,6 +597,11 @@
DCHECK(success);
}
+void GCMClientImpl::IgnoreWriteResultCallback(bool success) {
+ // TODO(fgorski): Ignoring the write result for now to make sure
+ // sync_intergration_tests are not broken.
+}
+
void GCMClientImpl::Stop() {
DVLOG(1) << "Stopping the GCM Client";
weak_ptr_factory_.InvalidateWeakPtrs();
diff --git a/components/gcm_driver/gcm_client_impl.h b/components/gcm_driver/gcm_client_impl.h
index b6a1ab5..c27bb7b 100644
--- a/components/gcm_driver/gcm_client_impl.h
+++ b/components/gcm_driver/gcm_client_impl.h
@@ -230,6 +230,9 @@
// |gcm_store_| fails.
void DefaultStoreCallback(bool success);
+ // Callback for store operation where result does not matter.
+ void IgnoreWriteResultCallback(bool success);
+
// Completes the registration request.
void OnRegisterCompleted(const std::string& app_id,
const std::vector<std::string>& sender_ids,
diff --git a/components/gcm_driver/gcm_driver_desktop.cc b/components/gcm_driver/gcm_driver_desktop.cc
index 6902efb..b2ab93a 100644
--- a/components/gcm_driver/gcm_driver_desktop.cc
+++ b/components/gcm_driver/gcm_driver_desktop.cc
@@ -363,6 +363,10 @@
gcm_enabled_(true),
connected_(false),
account_mapper_(new GCMAccountMapper(this)),
+ // Setting to max, to make sure it does not prompt for token reporting
+ // Before reading a reasonable value from the DB, which might be never,
+ // in which case the fetching will be triggered.
+ last_token_fetch_time_(base::Time::Max()),
ui_thread_(ui_thread),
io_thread_(io_thread),
weak_ptr_factory_(this) {
@@ -646,6 +650,8 @@
void GCMDriverDesktop::SetLastTokenFetchTime(const base::Time& time) {
DCHECK(ui_thread_->RunsTasksOnCurrentThread());
+ last_token_fetch_time_ = time;
+
io_thread_->PostTask(
FROM_HERE,
base::Bind(&GCMDriverDesktop::IOWorker::SetLastTokenFetchTime,
@@ -772,9 +778,10 @@
const base::Time& last_token_fetch_time) {
DCHECK(ui_thread_->RunsTasksOnCurrentThread());
+ last_token_fetch_time_ = last_token_fetch_time;
+
GCMDriver::AddAppHandler(kGCMAccountMapperAppId, account_mapper_.get());
account_mapper_->Initialize(account_mappings);
- last_token_fetch_time_ = last_token_fetch_time;
delayed_task_controller_->SetReady();
}
diff --git a/components/gcm_driver/gcm_driver_desktop_unittest.cc b/components/gcm_driver/gcm_driver_desktop_unittest.cc
index e02f8b3..f27d018 100644
--- a/components/gcm_driver/gcm_driver_desktop_unittest.cc
+++ b/components/gcm_driver/gcm_driver_desktop_unittest.cc
@@ -991,6 +991,13 @@
EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
}
+TEST_F(GCMDriverFunctionalTest, LastTokenFetchTime) {
+ EXPECT_EQ(base::Time(), driver()->GetLastTokenFetchTime());
+ base::Time fetch_time = base::Time::Now();
+ driver()->SetLastTokenFetchTime(fetch_time);
+ EXPECT_EQ(fetch_time, driver()->GetLastTokenFetchTime());
+}
+
// Tests a single instance of GCMDriver.
class GCMChannelStatusSyncerTest : public GCMDriverTest {
public:
diff --git a/components/metrics/metrics_service.cc b/components/metrics/metrics_service.cc
index 4fa2e75..adb8f2c 100644
--- a/components/metrics/metrics_service.cc
+++ b/components/metrics/metrics_service.cc
@@ -549,6 +549,19 @@
IncrementPrefValue(prefs::kStabilityDebuggerPresent);
}
+void MetricsService::ClearSavedStabilityMetrics() {
+ for (size_t i = 0; i < metrics_providers_.size(); ++i)
+ metrics_providers_[i]->ClearSavedStabilityMetrics();
+
+ // Reset the prefs that are managed by MetricsService/MetricsLog directly.
+ local_state_->SetInteger(prefs::kStabilityCrashCount, 0);
+ local_state_->SetInteger(prefs::kStabilityExecutionPhase,
+ UNINITIALIZED_PHASE);
+ local_state_->SetInteger(prefs::kStabilityIncompleteSessionEndCount, 0);
+ local_state_->SetInteger(prefs::kStabilityLaunchCount, 0);
+ local_state_->SetBoolean(prefs::kStabilitySessionEndCompleted, true);
+}
+
//------------------------------------------------------------------------------
// private methods
//------------------------------------------------------------------------------
@@ -600,18 +613,8 @@
// number of different edge cases, such as if the last version crashed before
// it could save off a system profile or if UMA reporting is disabled (which
// normally results in stats being accumulated).
- if (!has_initial_stability_log_ && version_changed) {
- for (size_t i = 0; i < metrics_providers_.size(); ++i)
- metrics_providers_[i]->ClearSavedStabilityMetrics();
-
- // Reset the prefs that are managed by MetricsService/MetricsLog directly.
- local_state_->SetInteger(prefs::kStabilityCrashCount, 0);
- local_state_->SetInteger(prefs::kStabilityExecutionPhase,
- UNINITIALIZED_PHASE);
- local_state_->SetInteger(prefs::kStabilityIncompleteSessionEndCount, 0);
- local_state_->SetInteger(prefs::kStabilityLaunchCount, 0);
- local_state_->SetBoolean(prefs::kStabilitySessionEndCompleted, true);
- }
+ if (!has_initial_stability_log_ && version_changed)
+ ClearSavedStabilityMetrics();
// Update session ID.
++session_id_;
diff --git a/components/metrics/metrics_service.h b/components/metrics/metrics_service.h
index 19794ea..db1fae2 100644
--- a/components/metrics/metrics_service.h
+++ b/components/metrics/metrics_service.h
@@ -239,6 +239,9 @@
void CheckForClonedInstall(
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+ // Clears the stability metrics that are saved in local state.
+ void ClearSavedStabilityMetrics();
+
protected:
// Exposed for testing.
MetricsLogManager* log_manager() { return &log_manager_; }
diff --git a/components/omnibox/omnibox_field_trial.cc b/components/omnibox/omnibox_field_trial.cc
index 7ad2956..0955eea 100644
--- a/components/omnibox/omnibox_field_trial.cc
+++ b/components/omnibox/omnibox_field_trial.cc
@@ -114,26 +114,14 @@
}
int OmniboxFieldTrial::GetDisabledProviderTypes() {
- // Make sure that Autocomplete dynamic field trials are activated. It's OK to
- // call this method multiple times.
- ActivateDynamicTrials();
-
- // Look for group names in form of "DisabledProviders_<mask>" where "mask"
- // is a bitmap of disabled provider types (AutocompleteProvider::Type).
- int provider_types = 0;
- for (int i = 0; i < kMaxAutocompleteDynamicFieldTrials; ++i) {
- std::string group_name = base::FieldTrialList::FindFullName(
- DynamicFieldTrialName(i));
- const char kDisabledProviders[] = "DisabledProviders_";
- if (!StartsWithASCII(group_name, kDisabledProviders, true))
- continue;
- int types = 0;
- if (!base::StringToInt(base::StringPiece(
- group_name.substr(strlen(kDisabledProviders))), &types))
- continue;
- provider_types |= types;
+ const std::string& types_string = variations::GetVariationParamValue(
+ kBundledExperimentFieldTrialName,
+ kDisableProvidersRule);
+ int types = 0;
+ if (types_string.empty() || !base::StringToInt(types_string, &types)) {
+ return 0;
}
- return provider_types;
+ return types;
}
void OmniboxFieldTrial::GetActiveSuggestFieldTrialHashes(
@@ -367,6 +355,7 @@
const char OmniboxFieldTrial::kBundledExperimentFieldTrialName[] =
"OmniboxBundledExperimentV1";
+const char OmniboxFieldTrial::kDisableProvidersRule[] = "DisableProviders";
const char OmniboxFieldTrial::kShortcutsScoringMaxRelevanceRule[] =
"ShortcutsScoringMaxRelevance";
const char OmniboxFieldTrial::kSearchHistoryRule[] = "SearchHistory";
diff --git a/components/omnibox/omnibox_field_trial.h b/components/omnibox/omnibox_field_trial.h
index d54b2b3..5a8909d 100644
--- a/components/omnibox/omnibox_field_trial.h
+++ b/components/omnibox/omnibox_field_trial.h
@@ -98,12 +98,11 @@
// This method may be called multiple times.
static void ActivateDynamicTrials();
+ // ---------------------------------------------------------
+ // For any experiment that's part of the bundled omnibox field trial.
+
// Returns a bitmap containing AutocompleteProvider::Type values
// that should be disabled in AutocompleteController.
- // This method simply goes over all autocomplete dynamic field trial groups
- // and looks for group names like "ProvidersDisabled_NNN" where NNN is
- // an integer corresponding to a bitmap mask. All extracted bitmaps
- // are OR-ed together and returned as the final result.
static int GetDisabledProviderTypes();
// Returns whether the user is in any dynamic field trial where the
@@ -300,6 +299,7 @@
// Exposed publicly for the sake of unittests.
static const char kBundledExperimentFieldTrialName[];
// Rule names used by the bundled experiment.
+ static const char kDisableProvidersRule[];
static const char kShortcutsScoringMaxRelevanceRule[];
static const char kSearchHistoryRule[];
static const char kDemoteByTypeRule[];
diff --git a/components/omnibox/omnibox_field_trial_unittest.cc b/components/omnibox/omnibox_field_trial_unittest.cc
index 47f7467..fe30271 100644
--- a/components/omnibox/omnibox_field_trial_unittest.cc
+++ b/components/omnibox/omnibox_field_trial_unittest.cc
@@ -138,32 +138,56 @@
EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes());
{
- SCOPED_TRACE("Invalid groups");
- CreateTestTrial("AutocompleteDynamicTrial_0", "DisabledProviders_");
- EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes());
- ResetFieldTrialList();
- CreateTestTrial("AutocompleteDynamicTrial_1", "DisabledProviders_XXX");
- EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes());
- ResetFieldTrialList();
- CreateTestTrial("AutocompleteDynamicTrial_1", "DisabledProviders_12abc");
+ SCOPED_TRACE("Outside the bundled field trial.");
+ CreateTestTrial("AutocompleteDynamicTrial_0", "DisabledProviders_123");
EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes());
}
{
- SCOPED_TRACE("Valid group name, unsupported trial name.");
+ SCOPED_TRACE("Valid field trial, missing param.");
ResetFieldTrialList();
- CreateTestTrial("UnsupportedTrialName", "DisabledProviders_20");
+ std::map<std::string, std::string> params;
+ ASSERT_TRUE(variations::AssociateVariationParams(
+ OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params));
+ base::FieldTrialList::CreateFieldTrial(
+ OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A");
EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes());
}
{
- SCOPED_TRACE("Valid field and group name.");
+ SCOPED_TRACE("Valid field trial, empty param value.");
ResetFieldTrialList();
- CreateTestTrial("AutocompleteDynamicTrial_2", "DisabledProviders_3");
- EXPECT_EQ(3, OmniboxFieldTrial::GetDisabledProviderTypes());
- // Two groups should be OR-ed together.
- CreateTestTrial("AutocompleteDynamicTrial_3", "DisabledProviders_6");
- EXPECT_EQ(7, OmniboxFieldTrial::GetDisabledProviderTypes());
+ std::map<std::string, std::string> params;
+ params[std::string(OmniboxFieldTrial::kDisableProvidersRule)] = "";
+ ASSERT_TRUE(variations::AssociateVariationParams(
+ OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params));
+ base::FieldTrialList::CreateFieldTrial(
+ OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A");
+ EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes());
+ }
+
+ {
+ SCOPED_TRACE("Valid field trial, invalid param value.");
+ ResetFieldTrialList();
+ std::map<std::string, std::string> params;
+ params[std::string(OmniboxFieldTrial::kDisableProvidersRule)] = "aaa";
+ ASSERT_TRUE(variations::AssociateVariationParams(
+ OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params));
+ base::FieldTrialList::CreateFieldTrial(
+ OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A");
+ EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes());
+ }
+
+ {
+ SCOPED_TRACE("Valid field trial and param.");
+ ResetFieldTrialList();
+ std::map<std::string, std::string> params;
+ params[std::string(OmniboxFieldTrial::kDisableProvidersRule)] = "12321";
+ ASSERT_TRUE(variations::AssociateVariationParams(
+ OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params));
+ base::FieldTrialList::CreateFieldTrial(
+ OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A");
+ EXPECT_EQ(12321, OmniboxFieldTrial::GetDisabledProviderTypes());
}
}
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc
index f2ab2e4..60fa6fd 100644
--- a/components/password_manager/core/browser/login_database.cc
+++ b/components/password_manager/core/browser/login_database.cc
@@ -324,8 +324,9 @@
bool custom_passphrase_sync_enabled) {
sql::Statement s(db_.GetCachedStatement(
SQL_FROM_HERE,
- "SELECT signon_realm, blacklisted_by_user, COUNT(username_value) "
- "FROM logins GROUP BY signon_realm, blacklisted_by_user"));
+ "SELECT signon_realm, password_type, blacklisted_by_user,"
+ "COUNT(username_value) FROM logins GROUP BY "
+ "signon_realm, password_type, blacklisted_by_user"));
if (!s.is_valid())
return;
@@ -335,23 +336,38 @@
custom_passphrase = "WithCustomPassphrase";
}
- int total_accounts = 0;
+ int total_user_created_accounts = 0;
+ int total_generated_accounts = 0;
int blacklisted_sites = 0;
while (s.Step()) {
- int blacklisted = s.ColumnInt(1);
- int accounts_per_site = s.ColumnInt(2);
+ PasswordForm::Type password_type =
+ static_cast<PasswordForm::Type>(s.ColumnInt(1));
+ int blacklisted = s.ColumnInt(2);
+ int accounts_per_site = s.ColumnInt(3);
if (blacklisted) {
++blacklisted_sites;
+ } else if (password_type == PasswordForm::TYPE_GENERATED) {
+ total_generated_accounts += accounts_per_site;
+ LogAccountStat(
+ base::StringPrintf("PasswordManager.AccountsPerSite.AutoGenerated.%s",
+ custom_passphrase.c_str()),
+ accounts_per_site);
} else {
- total_accounts += accounts_per_site;
- LogAccountStat(base::StringPrintf("PasswordManager.AccountsPerSite.%s",
- custom_passphrase.c_str()),
- accounts_per_site);
+ total_user_created_accounts += accounts_per_site;
+ LogAccountStat(
+ base::StringPrintf("PasswordManager.AccountsPerSite.UserCreated.%s",
+ custom_passphrase.c_str()),
+ accounts_per_site);
}
}
- LogAccountStat(base::StringPrintf("PasswordManager.TotalAccounts.%s",
- custom_passphrase.c_str()),
- total_accounts);
+ LogAccountStat(
+ base::StringPrintf("PasswordManager.TotalAccounts.UserCreated.%s",
+ custom_passphrase.c_str()),
+ total_user_created_accounts);
+ LogAccountStat(
+ base::StringPrintf("PasswordManager.TotalAccounts.AutoGenerated.%s",
+ custom_passphrase.c_str()),
+ total_generated_accounts);
LogAccountStat(base::StringPrintf("PasswordManager.BlacklistedSites.%s",
custom_passphrase.c_str()),
blacklisted_sites);
@@ -368,13 +384,13 @@
usage_statement.ColumnInt(0));
if (type == PasswordForm::TYPE_GENERATED) {
- LogTimesUsedStat(
- base::StringPrintf("PasswordManager.TimesGeneratedPasswordUsed.%s",
- custom_passphrase.c_str()),
- usage_statement.ColumnInt(1));
+ LogTimesUsedStat(base::StringPrintf(
+ "PasswordManager.TimesPasswordUsed.AutoGenerated.%s",
+ custom_passphrase.c_str()),
+ usage_statement.ColumnInt(1));
} else {
LogTimesUsedStat(
- base::StringPrintf("PasswordManager.TimesPasswordUsed.%s",
+ base::StringPrintf("PasswordManager.TimesPasswordUsed.UserCreated.%s",
custom_passphrase.c_str()),
usage_statement.ColumnInt(1));
}
diff --git a/components/password_manager/core/browser/login_database_unittest.cc b/components/password_manager/core/browser/login_database_unittest.cc
index 4faaa8c..5ec0e2e 100644
--- a/components/password_manager/core/browser/login_database_unittest.cc
+++ b/components/password_manager/core/browser/login_database_unittest.cc
@@ -11,6 +11,7 @@
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/histogram_tester.h"
#include "base/time/time.h"
#include "components/autofill/core/common/password_form.h"
#include "components/password_manager/core/browser/psl_matching_helper.h"
@@ -951,6 +952,79 @@
EXPECT_EQ(form, *result[0]);
}
+TEST_F(LoginDatabaseTest, ReportMetricsTest) {
+ PasswordForm password_form;
+ password_form.origin = GURL("http://example.com");
+ password_form.username_value = ASCIIToUTF16("test1@gmail.com");
+ password_form.password_value = ASCIIToUTF16("test");
+ password_form.signon_realm = "http://example.com/";
+ password_form.times_used = 0;
+ EXPECT_EQ(AddChangeForForm(password_form), db_.AddLogin(password_form));
+
+ password_form.username_value = ASCIIToUTF16("test2@gmail.com");
+ password_form.times_used = 1;
+ EXPECT_EQ(AddChangeForForm(password_form), db_.AddLogin(password_form));
+
+ password_form.origin = GURL("http://second.example.com");
+ password_form.signon_realm = "http://second.example.com";
+ password_form.times_used = 3;
+ EXPECT_EQ(AddChangeForForm(password_form), db_.AddLogin(password_form));
+
+ password_form.username_value = ASCIIToUTF16("test3@gmail.com");
+ password_form.type = PasswordForm::TYPE_GENERATED;
+ password_form.times_used = 2;
+ EXPECT_EQ(AddChangeForForm(password_form), db_.AddLogin(password_form));
+
+ password_form.origin = GURL("http://third.example.com/");
+ password_form.signon_realm = "http://third.example.com/";
+ password_form.times_used = 4;
+ EXPECT_EQ(AddChangeForForm(password_form), db_.AddLogin(password_form));
+
+ base::HistogramTester histogram_tester;
+ db_.ReportMetrics("", false);
+
+ histogram_tester.ExpectUniqueSample(
+ "PasswordManager.TotalAccounts.UserCreated.WithoutCustomPassphrase",
+ 3,
+ 1);
+ histogram_tester.ExpectBucketCount(
+ "PasswordManager.AccountsPerSite.UserCreated.WithoutCustomPassphrase",
+ 1,
+ 1);
+ histogram_tester.ExpectBucketCount(
+ "PasswordManager.AccountsPerSite.UserCreated.WithoutCustomPassphrase",
+ 2,
+ 1);
+ histogram_tester.ExpectBucketCount(
+ "PasswordManager.TimesPasswordUsed.UserCreated.WithoutCustomPassphrase",
+ 0,
+ 1);
+ histogram_tester.ExpectBucketCount(
+ "PasswordManager.TimesPasswordUsed.UserCreated.WithoutCustomPassphrase",
+ 1,
+ 1);
+ histogram_tester.ExpectBucketCount(
+ "PasswordManager.TimesPasswordUsed.UserCreated.WithoutCustomPassphrase",
+ 3,
+ 1);
+ histogram_tester.ExpectUniqueSample(
+ "PasswordManager.TotalAccounts.AutoGenerated.WithoutCustomPassphrase",
+ 2,
+ 1);
+ histogram_tester.ExpectUniqueSample(
+ "PasswordManager.AccountsPerSite.AutoGenerated.WithoutCustomPassphrase",
+ 1,
+ 2);
+ histogram_tester.ExpectBucketCount(
+ "PasswordManager.TimesPasswordUsed.AutoGenerated.WithoutCustomPassphrase",
+ 2,
+ 1);
+ histogram_tester.ExpectBucketCount(
+ "PasswordManager.TimesPasswordUsed.AutoGenerated.WithoutCustomPassphrase",
+ 4,
+ 1);
+}
+
#if defined(OS_POSIX)
// Only the current user has permission to read the database.
//
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 3859d68..32be334 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -123,7 +123,7 @@
# persistent IDs for all fields (but not for groups!) are needed. These are
# specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs,
# because doing so would break the deployed wire format!
-# For your editing convenience: highest ID currently used: 280
+# For your editing convenience: highest ID currently used: 281
#
# Placeholders:
# The following placeholder strings are automatically substituted:
@@ -6955,6 +6955,28 @@
Note that, despite the number, "sslv3" is an earier version than "tls1".''',
},
+ {
+ 'name': 'ContextualSearchEnabled',
+ 'type': 'main',
+ 'schema': { 'type': 'boolean' },
+ 'supported_on': [
+ 'android:40-',
+ ],
+ 'features': {
+ 'dynamic_refresh': True,
+ 'per_profile': True,
+ },
+ 'example_value': True,
+ 'id': 281,
+ 'caption': '''Enable Touch to Search''',
+ 'desc': '''Enables the availability of Touch to Search in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>'s content view.
+
+ If you enable this setting, Touch to Search will be available to the user and they can choose to turn the feature on or off.
+
+ If you disable this setting, Touch to Search will be disabled completely.
+
+ If this policy is left not set, it is equivalent to being enabled, see description above.''',
+ },
],
'messages': {
# Messages that are not associated to any policies.
diff --git a/components/signin/core/common/profile_management_switches.cc b/components/signin/core/common/profile_management_switches.cc
index f1a7203..a696753 100644
--- a/components/signin/core/common/profile_management_switches.cc
+++ b/components/signin/core/common/profile_management_switches.cc
@@ -24,6 +24,12 @@
};
State GetProcessState() {
+ // Disables the new avatar menu if the web-based signin is turned on, because
+ // the new avatar menu always uses the inline signin, which may break some
+ // SAML users.
+ if (switches::IsEnableWebBasedSignin())
+ return STATE_OLD_AVATAR_MENU;
+
// Find the state of both command line args.
bool is_new_avatar_menu =
CommandLine::ForCurrentProcess()->HasSwitch(
@@ -126,8 +132,7 @@
bool IsEnableWebBasedSignin() {
return CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableWebBasedSignin) && !IsNewProfileManagement() &&
- !IsEnableWebviewBasedSignin();
+ switches::kEnableWebBasedSignin) && !IsEnableWebviewBasedSignin();
}
bool IsEnableWebviewBasedSignin() {
diff --git a/content/browser/accessibility/android_granularity_movement_browsertest.cc b/content/browser/accessibility/android_granularity_movement_browsertest.cc
index be185f2..975da4c 100644
--- a/content/browser/accessibility/android_granularity_movement_browsertest.cc
+++ b/content/browser/accessibility/android_granularity_movement_browsertest.cc
@@ -51,8 +51,13 @@
return web_contents->GetRootBrowserAccessibilityManager()->GetRoot();
}
- // Call NextAtGranularity repeatedly and return a string that concatenates
- // all of the text of the returned text ranges.
+ // First, set accessibility focus to a node and wait for the update that
+ // loads inline text boxes for that node. (We load inline text boxes
+ // asynchronously on Android since we only ever need them for the node
+ // with accessibility focus.)
+ //
+ // Then call NextAtGranularity repeatedly and return a string that
+ // concatenates all of the text of the returned text ranges.
//
// As an example, if the node's text is "cat dog" and you traverse by
// word, this returns "'cat', 'dog'".
@@ -64,6 +69,13 @@
base::string16 TraverseNodeAtGranularity(
BrowserAccessibility* node,
int granularity) {
+ AccessibilityNotificationWaiter waiter(
+ shell(), AccessibilityModeComplete,
+ ui::AX_EVENT_TREE_CHANGED);
+ node->manager()->delegate()->AccessibilitySetAccessibilityFocus(
+ node->GetId());
+ waiter.WaitForNotification();
+
int start_index = -1;
int end_index = -1;
BrowserAccessibilityAndroid* android_node =
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc
index 4ab0e6e..53189cb 100644
--- a/content/browser/accessibility/browser_accessibility_android.cc
+++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -6,6 +6,7 @@
#include "base/i18n/break_iterator.h"
#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/accessibility/browser_accessibility_manager_android.h"
#include "content/common/accessibility_messages.h"
@@ -76,6 +77,10 @@
if (HasFocusableChild())
return false;
+ // Date and time controls should drop their children.
+ if (GetRole() == ui::AX_ROLE_DATE || GetRole() == ui::AX_ROLE_TIME)
+ return true;
+
// Headings with text can drop their children.
base::string16 name = GetText();
if (GetRole() == ui::AX_ROLE_HEADING && !name.empty())
@@ -92,6 +97,24 @@
return BrowserAccessibility::PlatformIsLeaf();
}
+bool BrowserAccessibilityAndroid::CanScrollForward() const {
+ if (!IsSlider())
+ return false;
+
+ float value = GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE);
+ float max = GetFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE);
+ return value < max;
+}
+
+bool BrowserAccessibilityAndroid::CanScrollBackward() const {
+ if (!IsSlider())
+ return false;
+
+ float value = GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE);
+ float min = GetFloatAttribute(ui::AX_ATTR_MIN_VALUE_FOR_RANGE);
+ return value > min;
+}
+
bool BrowserAccessibilityAndroid::IsCheckable() const {
bool checkable = false;
bool is_aria_pressed_defined;
@@ -208,6 +231,10 @@
return HasState(ui::AX_STATE_SELECTED);
}
+bool BrowserAccessibilityAndroid::IsSlider() const {
+ return GetRole() == ui::AX_ROLE_SLIDER;
+}
+
bool BrowserAccessibilityAndroid::IsVisibleToUser() const {
return !HasState(ui::AX_STATE_INVISIBLE);
}
@@ -229,12 +256,15 @@
case ui::AX_ROLE_SLIDER:
class_name = "android.widget.SeekBar";
break;
+ case ui::AX_ROLE_COLOR_WELL:
case ui::AX_ROLE_COMBO_BOX:
+ case ui::AX_ROLE_DATE:
+ case ui::AX_ROLE_POP_UP_BUTTON:
+ case ui::AX_ROLE_TIME:
class_name = "android.widget.Spinner";
break;
case ui::AX_ROLE_BUTTON:
case ui::AX_ROLE_MENU_BUTTON:
- case ui::AX_ROLE_POP_UP_BUTTON:
class_name = "android.widget.Button";
break;
case ui::AX_ROLE_CHECK_BOX:
@@ -297,13 +327,29 @@
// name on Android, not 2 or 3 like on Windows or Mac.
// First, always return the |value| attribute if this is an
- // editable text field.
- if (!value().empty() &&
- (GetRole() == ui::AX_ROLE_EDITABLE_TEXT ||
- GetRole() == ui::AX_ROLE_TEXT_AREA ||
- GetRole() == ui::AX_ROLE_TEXT_FIELD ||
- HasState(ui::AX_STATE_EDITABLE))) {
- return base::UTF8ToUTF16(value());
+ // input field.
+ if (!value().empty()) {
+ if (HasState(ui::AX_STATE_EDITABLE))
+ return base::UTF8ToUTF16(value());
+
+ switch (GetRole()) {
+ case ui::AX_ROLE_COMBO_BOX:
+ case ui::AX_ROLE_EDITABLE_TEXT:
+ case ui::AX_ROLE_POP_UP_BUTTON:
+ case ui::AX_ROLE_TEXT_AREA:
+ case ui::AX_ROLE_TEXT_FIELD:
+ return base::UTF8ToUTF16(value());
+ }
+ }
+
+ // For color wells, the color is stored in separate attributes.
+ // Perhaps we could return color names in the future?
+ if (GetRole() == ui::AX_ROLE_COLOR_WELL) {
+ int red = GetIntAttribute(ui::AX_ATTR_COLOR_VALUE_RED);
+ int green = GetIntAttribute(ui::AX_ATTR_COLOR_VALUE_GREEN);
+ int blue = GetIntAttribute(ui::AX_ATTR_COLOR_VALUE_BLUE);
+ return base::UTF8ToUTF16(
+ base::StringPrintf("#%02X%02X%02X", red, green, blue));
}
// Always prefer visible text if this is a link. Sites sometimes add
@@ -321,8 +367,17 @@
// Blink, making the platform-specific mapping to accessible text simpler.
base::string16 description = GetString16Attribute(ui::AX_ATTR_DESCRIPTION);
base::string16 help = GetString16Attribute(ui::AX_ATTR_HELP);
+
base::string16 placeholder;
- GetHtmlAttribute("placeholder", &placeholder);
+ switch (GetRole()) {
+ case ui::AX_ROLE_DATE:
+ case ui::AX_ROLE_EDITABLE_TEXT:
+ case ui::AX_ROLE_TEXT_AREA:
+ case ui::AX_ROLE_TEXT_FIELD:
+ case ui::AX_ROLE_TIME:
+ GetHtmlAttribute("placeholder", &placeholder);
+ }
+
int title_elem_id = GetIntAttribute(
ui::AX_ATTR_TITLE_UI_ELEMENT);
base::string16 text;
@@ -334,7 +389,7 @@
text = help;
else if (!name().empty())
text = base::UTF8ToUTF16(name());
- else if (GetRole() == ui::AX_ROLE_TEXT_FIELD && !placeholder.empty())
+ else if (!placeholder.empty())
text = placeholder;
else if (!value().empty())
text = base::UTF8ToUTF16(value());
@@ -383,11 +438,13 @@
break;
case ui::AX_ROLE_SLIDER:
case ui::AX_ROLE_PROGRESS_INDICATOR: {
- float value_for_range;
- if (GetFloatAttribute(
- ui::AX_ATTR_VALUE_FOR_RANGE, &value_for_range)) {
- index = static_cast<int>(value_for_range);
- }
+ // Return a percentage here for live feedback in an AccessibilityEvent.
+ // The exact value is returned in RangeCurrentValue.
+ float min = GetFloatAttribute(ui::AX_ATTR_MIN_VALUE_FOR_RANGE);
+ float max = GetFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE);
+ float value = GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE);
+ if (max > min && value >= min && value <= max)
+ index = static_cast<int>(((value - min)) * 100 / (max - min));
break;
}
}
@@ -403,14 +460,12 @@
count = PlatformChildCount();
break;
case ui::AX_ROLE_SLIDER:
- case ui::AX_ROLE_PROGRESS_INDICATOR: {
- float max_value_for_range;
- if (GetFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE,
- &max_value_for_range)) {
- count = static_cast<int>(max_value_for_range);
- }
+ case ui::AX_ROLE_PROGRESS_INDICATOR:
+ // An AccessibilityEvent can only return integer information about a
+ // seek control, so we return a percentage. The real range is returned
+ // in RangeMin and RangeMax.
+ count = 100;
break;
- }
}
return count;
}
diff --git a/content/browser/accessibility/browser_accessibility_android.h b/content/browser/accessibility/browser_accessibility_android.h
index 8dc2126..70579ab 100644
--- a/content/browser/accessibility/browser_accessibility_android.h
+++ b/content/browser/accessibility/browser_accessibility_android.h
@@ -19,6 +19,8 @@
virtual bool PlatformIsLeaf() const override;
+ bool CanScrollForward() const;
+ bool CanScrollBackward() const;
bool IsCheckable() const;
bool IsChecked() const;
bool IsClickable() const;
@@ -38,6 +40,7 @@
bool IsRangeType() const;
bool IsScrollable() const;
bool IsSelected() const;
+ bool IsSlider() const;
bool IsVisibleToUser() const;
bool CanOpenPopup() const;
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h
index f07814c..c0e59fa 100644
--- a/content/browser/accessibility/browser_accessibility_manager.h
+++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -69,6 +69,7 @@
const gfx::Rect& bounds) const = 0;
virtual void AccessibilityHitTest(
const gfx::Point& point) = 0;
+ virtual void AccessibilitySetAccessibilityFocus(int acc_obj_id) = 0;
virtual void AccessibilityFatalError() = 0;
virtual gfx::AcceleratedWidget AccessibilityGetAcceleratedWidget() = 0;
virtual gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible() = 0;
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc
index 7dbc149..fd4e0ff 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -116,9 +116,15 @@
if (obj.is_null())
return;
+ BrowserAccessibilityAndroid* android_node =
+ static_cast<BrowserAccessibilityAndroid*>(node);
+
if (event_type == ui::AX_EVENT_HIDE)
return;
+ if (event_type == ui::AX_EVENT_TREE_CHANGED)
+ return;
+
if (event_type == ui::AX_EVENT_HOVER) {
HandleHoverEvent(node);
return;
@@ -157,8 +163,6 @@
case ui::AX_EVENT_SHOW: {
// This event is fired when an object appears in a live region.
// Speak its text.
- BrowserAccessibilityAndroid* android_node =
- static_cast<BrowserAccessibilityAndroid*>(node);
Java_BrowserAccessibilityManager_announceLiveRegionText(
env, obj.obj(),
base::android::ConvertUTF16ToJavaString(
@@ -175,6 +179,9 @@
if (node->IsEditableText()) {
Java_BrowserAccessibilityManager_handleEditableTextChanged(
env, obj.obj(), node->GetId());
+ } else if (android_node->IsSlider()) {
+ Java_BrowserAccessibilityManager_handleSliderChanged(
+ env, obj.obj(), node->GetId());
}
break;
default:
@@ -247,6 +254,8 @@
Java_BrowserAccessibilityManager_setAccessibilityNodeInfoBooleanAttributes(
env, obj, info,
id,
+ node->CanScrollForward(),
+ node->CanScrollBackward(),
node->IsCheckable(),
node->IsChecked(),
node->IsClickable(),
@@ -465,6 +474,38 @@
SetTextSelection(*node, start, end);
}
+jboolean BrowserAccessibilityManagerAndroid::AdjustSlider(
+ JNIEnv* env, jobject obj, jint id, jboolean increment) {
+ BrowserAccessibility* node = GetFromID(id);
+ if (!node)
+ return false;
+
+ BrowserAccessibilityAndroid* android_node =
+ static_cast<BrowserAccessibilityAndroid*>(node);
+
+ if (!android_node->IsSlider() || !android_node->IsEnabled())
+ return false;
+
+ float value = node->GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE);
+ float min = node->GetFloatAttribute(ui::AX_ATTR_MIN_VALUE_FOR_RANGE);
+ float max = node->GetFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE);
+ if (max <= min)
+ return false;
+
+ // To behave similarly to an Android SeekBar, move by an increment of
+ // approximately 20%.
+ float original_value = value;
+ float delta = (max - min) / 5.0f;
+ value += (increment ? delta : -delta);
+ value = std::max(std::min(value, max), min);
+ if (value != original_value) {
+ BrowserAccessibilityManager::SetValue(
+ *node, base::UTF8ToUTF16(base::DoubleToString(value)));
+ return true;
+ }
+ return false;
+}
+
void BrowserAccessibilityManagerAndroid::HandleHoverEvent(
BrowserAccessibility* node) {
JNIEnv* env = AttachCurrentThread();
@@ -677,6 +718,12 @@
return true;
}
+void BrowserAccessibilityManagerAndroid::SetAccessibilityFocus(
+ JNIEnv* env, jobject obj, jint id) {
+ if (delegate_)
+ delegate_->AccessibilitySetAccessibilityFocus(id);
+}
+
void BrowserAccessibilityManagerAndroid::OnRootChanged(ui::AXNode* new_root) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.h b/content/browser/accessibility/browser_accessibility_manager_android.h
index 63d3268..f0e2d34 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.h
+++ b/content/browser/accessibility/browser_accessibility_manager_android.h
@@ -79,6 +79,7 @@
void ScrollToMakeNodeVisible(JNIEnv* env, jobject obj, jint id);
void SetTextFieldValue(JNIEnv* env, jobject obj, jint id, jstring value);
void SetSelection(JNIEnv* env, jobject obj, jint id, jint start, jint end);
+ jboolean AdjustSlider(JNIEnv* env, jobject obj, jint id, jboolean increment);
// Return the id of the next node in tree order in the direction given by
// |forwards|, starting with |start_id|, that matches |element_type|,
@@ -115,6 +116,11 @@
int32 granularity, int cursor_index,
BrowserAccessibilityAndroid* node, int32* start_index, int32* end_index);
+ // Set accessibility focus. This sends a message to the renderer to
+ // asynchronously load inline text boxes for this node only, enabling more
+ // accurate movement by granularities on this node.
+ void SetAccessibilityFocus(JNIEnv* env, jobject obj, jint id);
+
protected:
// AXTreeDelegate overrides.
virtual void OnRootChanged(ui::AXNode* new_root) override;
diff --git a/content/browser/accessibility/browser_accessibility_manager_unittest.cc b/content/browser/accessibility/browser_accessibility_manager_unittest.cc
index b71187c..8e2e3d0 100644
--- a/content/browser/accessibility/browser_accessibility_manager_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_unittest.cc
@@ -82,6 +82,7 @@
return gfx::Point();
}
void AccessibilityHitTest(const gfx::Point& point) override {}
+ void AccessibilitySetAccessibilityFocus(int acc_obj_id) override {}
void AccessibilityFatalError() override { got_fatal_error_ = true; }
gfx::AcceleratedWidget AccessibilityGetAcceleratedWidget() override {
return gfx::kNullAcceleratedWidget;
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index a589114..b794107 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -471,6 +471,10 @@
Send(new AccessibilityMsg_HitTest(routing_id_, point));
}
+void RenderFrameHostImpl::AccessibilitySetAccessibilityFocus(int acc_obj_id) {
+ Send(new AccessibilityMsg_SetAccessibilityFocus(routing_id_, acc_obj_id));
+}
+
void RenderFrameHostImpl::AccessibilityFatalError() {
browser_accessibility_manager_.reset(NULL);
if (accessibility_reset_token_)
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index feab5a3..b1c4703 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -143,6 +143,7 @@
gfx::Point AccessibilityOriginInScreen(
const gfx::Rect& bounds) const override;
void AccessibilityHitTest(const gfx::Point& point) override;
+ void AccessibilitySetAccessibilityFocus(int acc_obj_id) override;
void AccessibilityFatalError() override;
gfx::AcceleratedWidget AccessibilityGetAcceleratedWidget() override;
gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible() override;
diff --git a/content/common/accessibility_messages.h b/content/common/accessibility_messages.h
index fac9830..69dfb51 100644
--- a/content/common/accessibility_messages.h
+++ b/content/common/accessibility_messages.h
@@ -153,6 +153,13 @@
IPC_MESSAGE_ROUTED1(AccessibilityMsg_HitTest,
gfx::Point /* location to test */)
+// Relay a request from assistive technology to set accessibility focus
+// to a given node. On platforms where this is used (currently Android),
+// inline text boxes are only computed for the node with accessibility focus,
+// rather than for the whole tree.
+IPC_MESSAGE_ROUTED1(AccessibilityMsg_SetAccessibilityFocus,
+ int /* object id */)
+
// Tells the render view that a AccessibilityHostMsg_Events
// message was processed and it can send addition events.
IPC_MESSAGE_ROUTED0(AccessibilityMsg_Events_ACK)
diff --git a/content/common/gpu/image_transport_surface_calayer_mac.h b/content/common/gpu/image_transport_surface_calayer_mac.h
index 1de28b3..1a7c3a2 100644
--- a/content/common/gpu/image_transport_surface_calayer_mac.h
+++ b/content/common/gpu/image_transport_surface_calayer_mac.h
@@ -9,6 +9,7 @@
#include "content/common/gpu/image_transport_surface_fbo_mac.h"
#include "ui/base/cocoa/remote_layer_api.h"
#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gpu_switching_observer.h"
#include "ui/gl/scoped_cgl.h"
@class ImageTransportLayer;
@@ -17,7 +18,8 @@
// Allocate CAOpenGLLayer-backed storage for an FBO image transport surface.
class CALayerStorageProvider
- : public ImageTransportSurfaceFBO::StorageProvider {
+ : public ImageTransportSurfaceFBO::StorageProvider,
+ public ui::GpuSwitchingObserver {
public:
CALayerStorageProvider(ImageTransportSurfaceFBO* transport_surface);
~CALayerStorageProvider() override;
@@ -40,6 +42,9 @@
void LayerDoDraw();
void LayerResetStorageProvider();
+ // ui::GpuSwitchingObserver implementation.
+ void OnGpuSwitched() override;
+
private:
void DrawImmediatelyAndUnblockBrowser();
@@ -76,6 +81,16 @@
base::scoped_nsobject<CAContext> context_;
base::scoped_nsobject<ImageTransportLayer> layer_;
+ // When a CAContext is destroyed in the GPU process, it will become a blank
+ // CALayer in the browser process. Put retains on these contexts in this queue
+ // when they are discarded, and remove one item from the queue as each frame
+ // is acked.
+ std::list<base::scoped_nsobject<CAContext> > previously_discarded_contexts_;
+
+ // Indicates that the CALayer should be recreated at the next swap. This is
+ // to ensure that the CGLContext created for the CALayer be on the right GPU.
+ bool recreate_layer_after_gpu_switch_;
+
// Weak factory against which a timeout task for forcing a draw is created.
base::WeakPtrFactory<CALayerStorageProvider> pending_draw_weak_factory_;
diff --git a/content/common/gpu/image_transport_surface_calayer_mac.mm b/content/common/gpu/image_transport_surface_calayer_mac.mm
index 264b97f..0147b3c 100644
--- a/content/common/gpu/image_transport_surface_calayer_mac.mm
+++ b/content/common/gpu/image_transport_surface_calayer_mac.mm
@@ -13,6 +13,11 @@
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gl/gl_gl_api_implementation.h"
#include "ui/gl/gl_switches.h"
+#include "ui/gl/gpu_switching_manager.h"
+
+namespace {
+const size_t kFramesToKeepCAContextAfterDiscard = 2;
+}
@interface ImageTransportLayer : CAOpenGLLayer {
content::CALayerStorageProvider* storageProvider_;
@@ -97,9 +102,13 @@
can_draw_returned_false_count_(0),
fbo_texture_(0),
fbo_scale_factor_(1),
- pending_draw_weak_factory_(this) {}
+ recreate_layer_after_gpu_switch_(false),
+ pending_draw_weak_factory_(this) {
+ ui::GpuSwitchingManager::GetInstance()->AddObserver(this);
+}
CALayerStorageProvider::~CALayerStorageProvider() {
+ ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this);
}
gfx::Size CALayerStorageProvider::GetRoundedSize(gfx::Size size) {
@@ -155,10 +164,22 @@
void CALayerStorageProvider::SwapBuffers(
const gfx::Size& size, float scale_factor) {
DCHECK(!has_pending_draw_);
+
+ // Recreate the CALayer on the new GPU if a GPU switch has occurred. Note
+ // that the CAContext will retain a reference to the old CALayer until the
+ // call to -[CAContext setLayer:] replaces the old CALayer with the new one.
+ if (recreate_layer_after_gpu_switch_) {
+ [layer_ resetStorageProvider];
+ layer_.reset();
+ recreate_layer_after_gpu_switch_ = false;
+ }
+
+ // Set the pending draw flag only after destroying the old layer (otherwise
+ // destroying it will un-set the flag).
has_pending_draw_ = true;
// Allocate a CAContext to use to transport the CALayer to the browser
- // process.
+ // process, if needed.
if (!context_) {
base::scoped_nsobject<NSDictionary> dict([[NSDictionary alloc] init]);
CGSConnectionID connection_id = CGSMainConnectionID();
@@ -167,7 +188,7 @@
[context_ retain];
}
- // Allocate a CALayer to use to draw the content.
+ // Allocate a CALayer to use to draw the content, if needed.
if (!layer_) {
layer_.reset([[ImageTransportLayer alloc] initWithStorageProvider:this]);
gfx::Size dip_size(gfx::ToFlooredSize(gfx::ScaleSize(
@@ -180,6 +201,11 @@
[context_ setLayer:layer_];
}
+ // Replacing the CAContext's CALayer will sometimes results in an immediate
+ // draw. If that happens, early-out.
+ if (!has_pending_draw_)
+ return;
+
// Tell CoreAnimation to draw our frame.
if (gpu_vsync_disabled_ || throttling_disabled_) {
DrawImmediatelyAndUnblockBrowser();
@@ -228,12 +254,27 @@
// at the next swap.
[layer_ resetStorageProvider];
layer_.reset();
+
+ // If we remove all references to the CAContext in this process, it will be
+ // blanked-out in the browser process (even if the browser process is inside
+ // a NSDisableScreenUpdates block). Ensure that the context is kept around
+ // until a fixed number of frames (determined empirically) have been acked.
+ // http://crbug.com/425819
+ while (previously_discarded_contexts_.size() <
+ kFramesToKeepCAContextAfterDiscard) {
+ previously_discarded_contexts_.push_back(
+ base::scoped_nsobject<CAContext>());
+ }
+ previously_discarded_contexts_.push_back(context_);
+
context_.reset();
}
void CALayerStorageProvider::SwapBuffersAckedByBrowser(
bool disable_throttling) {
throttling_disabled_ = disable_throttling;
+ if (!previously_discarded_contexts_.empty())
+ previously_discarded_contexts_.pop_front();
}
CGLContextObj CALayerStorageProvider::LayerShareGroupContext() {
@@ -312,6 +353,10 @@
UnblockBrowserIfNeeded();
}
+void CALayerStorageProvider::OnGpuSwitched() {
+ recreate_layer_after_gpu_switch_ = true;
+}
+
void CALayerStorageProvider::UnblockBrowserIfNeeded() {
if (!has_pending_draw_)
return;
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index effba1e..8e4645f 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -700,6 +700,7 @@
mRenderCoordinates.reset();
initPopupZoomer(mContext);
mImeAdapter = createImeAdapter(mContext);
+ attachImeAdapter();
mAccessibilityInjector = AccessibilityInjector.newInstance(this);
@@ -1331,7 +1332,7 @@
}
private void clearUserSelection() {
- if (isSelectionEditable()) {
+ if (mFocusedNodeEditable) {
if (mInputConnection != null) {
int selectionEnd = Selection.getSelectionEnd(mEditable);
mInputConnection.setSelection(selectionEnd, selectionEnd);
@@ -2250,7 +2251,7 @@
for (int i = 0; i < items.length; i++) {
popupItems.add(new SelectPopupItem(items[i], enabled[i]));
}
- if (DeviceFormFactor.isTablet(mContext) && !multiple) {
+ if (DeviceFormFactor.isTablet(mContext) && !multiple && !isTouchExplorationEnabled()) {
mSelectPopup = new SelectPopupDropdown(this, popupItems, bounds, selectedIndices);
} else {
mSelectPopup = new SelectPopupDialog(this, popupItems, multiple, selectedIndices);
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java
index f349a0a..cc53676 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java
@@ -63,6 +63,7 @@
private int mSelectionGranularity;
private int mSelectionStartIndex;
private int mSelectionEndIndex;
+ private boolean mVisible = true;
/**
* Create a BrowserAccessibilityManager object, which is owned by the C++
@@ -121,6 +122,21 @@
}
/**
+ * Set whether the web content made accessible by this class is currently visible.
+ * Set it to false if the web view is still on the screen but it's obscured by a
+ * dialog or overlay. This will make every virtual view in the web hierarchy report
+ * that it's not visible, and not accessibility focusable.
+ *
+ * @param visible Whether the web content is currently visible and not obscured.
+ */
+ public void setVisible(boolean visible) {
+ if (visible == mVisible) return;
+
+ mVisible = visible;
+ mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+ }
+
+ /**
* @see AccessibilityNodeProvider#createAccessibilityNodeInfo(int)
*/
protected AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) {
@@ -230,6 +246,7 @@
return jumpToElementType(elementType, false);
}
case ACTION_SET_TEXT: {
+ if (!nativeIsEditableText(mNativeObj, virtualViewId)) return false;
if (arguments == null) return false;
String newText = arguments.getString(
ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE);
@@ -237,9 +254,10 @@
nativeSetTextFieldValue(mNativeObj, virtualViewId, newText);
// Match Android framework and set the cursor to the end of the text field.
nativeSetSelection(mNativeObj, virtualViewId, newText.length(), newText.length());
- break;
+ return true;
}
case AccessibilityNodeInfo.ACTION_SET_SELECTION: {
+ if (!nativeIsEditableText(mNativeObj, virtualViewId)) return false;
int selectionStart = 0;
int selectionEnd = 0;
if (arguments != null) {
@@ -249,7 +267,7 @@
AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT);
}
nativeSetSelection(mNativeObj, virtualViewId, selectionStart, selectionEnd);
- break;
+ return true;
}
case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY: {
if (arguments == null) return false;
@@ -273,6 +291,10 @@
}
return previousAtGranularity(granularity, extend);
}
+ case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
+ return nativeAdjustSlider(mNativeObj, virtualViewId, true);
+ case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
+ return nativeAdjustSlider(mNativeObj, virtualViewId, false);
default:
break;
}
@@ -431,6 +453,16 @@
mSelectionGranularity = 0;
mSelectionStartIndex = 0;
mSelectionEndIndex = 0;
+
+ // Calling nativeSetAccessibilityFocus will asynchronously load inline text boxes for
+ // this node and its subtree. If accessibility focus is on anything other than
+ // the root, do it - otherwise set it to -1 so we don't load inline text boxes
+ // for the whole subtree of the root.
+ if (mAccessibilityFocusId == mCurrentRootId)
+ nativeSetAccessibilityFocus(mNativeObj, -1);
+ else
+ nativeSetAccessibilityFocus(mNativeObj, mAccessibilityFocusId);
+
sendAccessibilityEvent(mAccessibilityFocusId,
AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
return true;
@@ -518,7 +550,7 @@
}
// Populate the minimum required fields.
- result.setVisibleToUser(source.isVisibleToUser());
+ result.setVisibleToUser(source.isVisibleToUser() && mVisible);
result.setEnabled(source.isEnabled());
result.setPackageName(source.getPackageName());
result.setClassName(source.getClassName());
@@ -575,6 +607,11 @@
}
@CalledByNative
+ private void handleSliderChanged(int id) {
+ sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_SCROLLED);
+ }
+
+ @CalledByNative
private void handleContentChanged(int id) {
int rootId = nativeGetRootId(mNativeObj);
if (rootId != mCurrentRootId) {
@@ -631,9 +668,10 @@
@CalledByNative
private void setAccessibilityNodeInfoBooleanAttributes(AccessibilityNodeInfo node,
- int virtualViewId, boolean checkable, boolean checked, boolean clickable,
- boolean editableText, boolean enabled, boolean focusable, boolean focused,
- boolean password, boolean scrollable, boolean selected, boolean visibleToUser) {
+ int virtualViewId, boolean canScrollForward, boolean canScrollBackward,
+ boolean checkable, boolean checked, boolean clickable, boolean editableText,
+ boolean enabled, boolean focusable, boolean focused, boolean password,
+ boolean scrollable, boolean selected, boolean visibleToUser) {
node.setCheckable(checkable);
node.setChecked(checked);
node.setClickable(clickable);
@@ -643,7 +681,7 @@
node.setPassword(password);
node.setScrollable(scrollable);
node.setSelected(selected);
- node.setVisibleToUser(visibleToUser);
+ node.setVisibleToUser(visibleToUser && mVisible);
node.addAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT);
node.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT);
@@ -659,6 +697,14 @@
node.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
}
+ if (canScrollForward) {
+ node.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+ }
+
+ if (canScrollBackward) {
+ node.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+ }
+
if (focusable) {
if (focused) {
node.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS);
@@ -670,7 +716,7 @@
if (mAccessibilityFocusId == virtualViewId) {
node.setAccessibilityFocused(true);
node.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
- } else {
+ } else if (mVisible) {
node.setAccessibilityFocused(false);
node.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
}
@@ -924,4 +970,8 @@
private native boolean nativePreviousAtGranularity(
long nativeBrowserAccessibilityManagerAndroid,
int selectionGranularity, boolean extendSelection, int id, int cursorIndex);
+ private native boolean nativeAdjustSlider(
+ long nativeBrowserAccessibilityManagerAndroid, int id, boolean increment);
+ private native void nativeSetAccessibilityFocus(
+ long nativeBrowserAccessibilityManagerAndroid, int id);
}
diff --git a/content/renderer/accessibility/blink_ax_tree_source.cc b/content/renderer/accessibility/blink_ax_tree_source.cc
index a930982..22c66ac 100644
--- a/content/renderer/accessibility/blink_ax_tree_source.cc
+++ b/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -108,7 +108,8 @@
BlinkAXTreeSource::BlinkAXTreeSource(RenderFrameImpl* render_frame)
: render_frame_(render_frame),
node_to_frame_routing_id_map_(NULL),
- node_to_browser_plugin_instance_id_map_(NULL) {
+ node_to_browser_plugin_instance_id_map_(NULL),
+ accessibility_focus_id_(-1) {
}
BlinkAXTreeSource::~BlinkAXTreeSource() {
@@ -147,6 +148,17 @@
void BlinkAXTreeSource::GetChildren(
blink::WebAXObject parent,
std::vector<blink::WebAXObject>* out_children) const {
+ if (parent.role() == blink::WebAXRoleStaticText) {
+ blink::WebAXObject ancestor = parent;
+ while (!ancestor.isDetached()) {
+ if (ancestor.axID() == accessibility_focus_id_) {
+ parent.loadInlineTextBoxes();
+ break;
+ }
+ ancestor = ancestor.parentObject();
+ }
+ }
+
bool is_iframe = false;
WebNode node = parent.node();
if (!node.isNull() && node.isElementNode()) {
diff --git a/content/renderer/accessibility/blink_ax_tree_source.h b/content/renderer/accessibility/blink_ax_tree_source.h
index fe338b9..b08108b 100644
--- a/content/renderer/accessibility/blink_ax_tree_source.h
+++ b/content/renderer/accessibility/blink_ax_tree_source.h
@@ -29,6 +29,12 @@
// Walks up the ancestor chain to see if this is a descendant of the root.
bool IsInTree(blink::WebAXObject node) const;
+ // Set the id of the node with accessibility focus. The node with
+ // accessibility focus will force loading inline text box children,
+ // which aren't always loaded by default on all platforms.
+ int accessibility_focus_id() { return accessibility_focus_id_; }
+ void set_accessiblity_focus_id(int id) { accessibility_focus_id_ = id; }
+
// AXTreeSource implementation.
blink::WebAXObject GetRoot() const override;
blink::WebAXObject GetFromId(int32 id) const override;
@@ -50,6 +56,7 @@
RenderFrameImpl* render_frame_;
std::map<int32, int>* node_to_frame_routing_id_map_;
std::map<int32, int>* node_to_browser_plugin_instance_id_map_;
+ int accessibility_focus_id_;
};
} // namespace content
diff --git a/content/renderer/accessibility/renderer_accessibility.cc b/content/renderer/accessibility/renderer_accessibility.cc
index 3f580f1..ac83a76 100644
--- a/content/renderer/accessibility/renderer_accessibility.cc
+++ b/content/renderer/accessibility/renderer_accessibility.cc
@@ -43,14 +43,16 @@
WebSettings* settings = web_view->settings();
settings->setAccessibilityEnabled(true);
- // TODO(dmazzoni): remove this on Android while still supporting
- // moving by granularities.
- settings->setInlineTextBoxAccessibilityEnabled(true);
-
#if defined(OS_ANDROID)
+ // Password values are only passed through on Android.
settings->setAccessibilityPasswordValuesEnabled(true);
#endif
+#if !defined(OS_ANDROID)
+ // Inline text boxes are enabled for all nodes on all except Android.
+ settings->setInlineTextBoxAccessibilityEnabled(true);
+#endif
+
const WebDocument& document = GetMainDocument();
if (!document.isNull()) {
// It's possible that the webview has already loaded a webpage without
@@ -75,6 +77,8 @@
IPC_MESSAGE_HANDLER(AccessibilityMsg_SetTextSelection, OnSetTextSelection)
IPC_MESSAGE_HANDLER(AccessibilityMsg_SetValue, OnSetValue)
IPC_MESSAGE_HANDLER(AccessibilityMsg_HitTest, OnHitTest)
+ IPC_MESSAGE_HANDLER(AccessibilityMsg_SetAccessibilityFocus,
+ OnSetAccessibilityFocus)
IPC_MESSAGE_HANDLER(AccessibilityMsg_Reset, OnReset)
IPC_MESSAGE_HANDLER(AccessibilityMsg_FatalError, OnFatalError)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -345,6 +349,26 @@
HandleAXEvent(obj, ui::AX_EVENT_HOVER);
}
+void RendererAccessibility::OnSetAccessibilityFocus(int acc_obj_id) {
+ if (tree_source_.accessibility_focus_id() == acc_obj_id)
+ return;
+
+ tree_source_.set_accessiblity_focus_id(acc_obj_id);
+
+ const WebDocument& document = GetMainDocument();
+ if (document.isNull())
+ return;
+
+ WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id);
+
+ // This object may not be a leaf node. Force the whole subtree to be
+ // re-serialized.
+ serializer_.DeleteClientSubtree(obj);
+
+ // Explicitly send a tree change update event now.
+ HandleAXEvent(obj, ui::AX_EVENT_TREE_CHANGED);
+}
+
void RendererAccessibility::OnReset(int reset_token) {
reset_token_ = reset_token;
serializer_.Reset();
@@ -464,6 +488,7 @@
}
obj.setValue(value);
+ HandleAXEvent(obj, ui::AX_EVENT_VALUE_CHANGED);
}
} // namespace content
diff --git a/content/renderer/accessibility/renderer_accessibility.h b/content/renderer/accessibility/renderer_accessibility.h
index 151d193..2c3d8e8 100644
--- a/content/renderer/accessibility/renderer_accessibility.h
+++ b/content/renderer/accessibility/renderer_accessibility.h
@@ -96,6 +96,7 @@
void OnEventsAck();
void OnFatalError();
void OnHitTest(gfx::Point point);
+ void OnSetAccessibilityFocus(int acc_obj_id);
void OnReset(int reset_token);
void OnScrollToMakeVisible(int acc_obj_id, gfx::Rect subfocus);
void OnScrollToPoint(int acc_obj_id, gfx::Point point);
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 8566532..6984b13 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -1464,6 +1464,8 @@
}
void RenderThreadImpl::OnUpdateTimezone() {
+ if (!blink_platform_impl_)
+ return;
NotifyTimezoneChange();
}
diff --git a/content/test/data/accessibility/aria-valuemax-expected-android.txt b/content/test/data/accessibility/aria-valuemax-expected-android.txt
index 0c5f244..20bfb69 100644
--- a/content/test/data/accessibility/aria-valuemax-expected-android.txt
+++ b/content/test/data/accessibility/aria-valuemax-expected-android.txt
@@ -1,5 +1,5 @@
android.webkit.WebView focusable focused scrollable
- android.widget.ProgressBar range item_index=51 item_count=101 range_min=1 range_max=101 range_current_value=51
+ android.widget.ProgressBar range item_index=50 item_count=100 range_min=1 range_max=101 range_current_value=51
android.view.View range range_min=2 range_max=102 range_current_value=52
- android.widget.SeekBar range item_index=53 item_count=103 range_min=3 range_max=103 range_current_value=53
- android.widget.EditText range_min=4 range_max=104 range_current_value=54
+ android.widget.SeekBar range item_index=50 item_count=100 range_min=3 range_max=103 range_current_value=53
+ android.widget.EditText range_min=4 range_max=104 range_current_value=54
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria-valuemin-expected-android.txt b/content/test/data/accessibility/aria-valuemin-expected-android.txt
index 0c5f244..20bfb69 100644
--- a/content/test/data/accessibility/aria-valuemin-expected-android.txt
+++ b/content/test/data/accessibility/aria-valuemin-expected-android.txt
@@ -1,5 +1,5 @@
android.webkit.WebView focusable focused scrollable
- android.widget.ProgressBar range item_index=51 item_count=101 range_min=1 range_max=101 range_current_value=51
+ android.widget.ProgressBar range item_index=50 item_count=100 range_min=1 range_max=101 range_current_value=51
android.view.View range range_min=2 range_max=102 range_current_value=52
- android.widget.SeekBar range item_index=53 item_count=103 range_min=3 range_max=103 range_current_value=53
- android.widget.EditText range_min=4 range_max=104 range_current_value=54
+ android.widget.SeekBar range item_index=50 item_count=100 range_min=3 range_max=103 range_current_value=53
+ android.widget.EditText range_min=4 range_max=104 range_current_value=54
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria-valuenow-expected-android.txt b/content/test/data/accessibility/aria-valuenow-expected-android.txt
index 9d59be2..9bc7f1d 100644
--- a/content/test/data/accessibility/aria-valuenow-expected-android.txt
+++ b/content/test/data/accessibility/aria-valuenow-expected-android.txt
@@ -1,2 +1,2 @@
android.webkit.WebView focusable focused scrollable
- android.widget.ProgressBar range item_index=3 range_current_value=3
+ android.widget.ProgressBar range item_count=100 range_current_value=3
\ No newline at end of file
diff --git a/content/test/data/accessibility/input-color-expected-android.txt b/content/test/data/accessibility/input-color-expected-android.txt
index 947af64..daa591a 100644
--- a/content/test/data/accessibility/input-color-expected-android.txt
+++ b/content/test/data/accessibility/input-color-expected-android.txt
@@ -1,3 +1,3 @@
android.webkit.WebView focusable focused scrollable
android.view.View
- android.view.View focusable
+ android.widget.Spinner clickable focusable name='#FF9900'
diff --git a/content/test/data/accessibility/input-date-expected-android.txt b/content/test/data/accessibility/input-date-expected-android.txt
index 3873afa..263e690 100644
--- a/content/test/data/accessibility/input-date-expected-android.txt
+++ b/content/test/data/accessibility/input-date-expected-android.txt
@@ -1,4 +1,3 @@
android.webkit.WebView focusable focused scrollable
android.view.View
- android.view.View focusable input_type=20
- android.view.View
+ android.widget.Spinner clickable focusable name='2008-09-01' input_type=20
diff --git a/content/test/data/accessibility/input-date-expected-mac.txt b/content/test/data/accessibility/input-date-expected-mac.txt
index 01b10ed..351a3ee 100644
--- a/content/test/data/accessibility/input-date-expected-mac.txt
+++ b/content/test/data/accessibility/input-date-expected-mac.txt
@@ -1,14 +1,14 @@
-AXWebArea
- AXGroup
- AXUnknown
- AXGroup
- AXGroup
- AXSlider AXValue='0'
- AXStaticText AXValue='/'
- AXSlider AXValue='0'
- AXStaticText AXValue='/'
- AXSlider AXValue='0'
- AXPopUpButton
- AXSlider AXValue='0'
- AXButton
- AXButton
+AXWebArea AXRoleDescription='HTML content'
+ AXGroup AXRoleDescription='group'
+ AXDateField AXRoleDescription='date field' AXValue='2008-09-01'
+ AXGroup AXRoleDescription='group'
+ AXGroup AXRoleDescription='group'
+ AXIncrementor AXRoleDescription='stepper' AXValue='9'
+ AXStaticText AXRoleDescription='text' AXValue='/'
+ AXIncrementor AXRoleDescription='stepper' AXValue='1'
+ AXStaticText AXRoleDescription='text' AXValue='/'
+ AXIncrementor AXRoleDescription='stepper' AXValue='2008'
+ AXPopUpButton AXRoleDescription='pop up button'
+ AXIncrementor AXRoleDescription='stepper' AXValue='0'
+ AXButton AXRoleDescription='button'
+ AXButton AXRoleDescription='button'
diff --git a/content/test/data/accessibility/input-date.html b/content/test/data/accessibility/input-date.html
index 7bf6e0d..e6dd2ab 100644
--- a/content/test/data/accessibility/input-date.html
+++ b/content/test/data/accessibility/input-date.html
@@ -2,7 +2,7 @@
<html>
<body>
- <input type="date">
+ <input type="date" value="2008-09-01">
</body>
</html>
diff --git a/content/test/data/accessibility/input-range-expected-android.txt b/content/test/data/accessibility/input-range-expected-android.txt
index 8e8d7f4..d4165d5 100644
--- a/content/test/data/accessibility/input-range-expected-android.txt
+++ b/content/test/data/accessibility/input-range-expected-android.txt
@@ -1,3 +1,3 @@
android.webkit.WebView focusable focused scrollable
android.view.View
- android.widget.SeekBar focusable range item_index=5 item_count=10 range_min=1 range_max=10 range_current_value=5
+ android.widget.SeekBar focusable range item_index=44 item_count=100 range_min=1 range_max=10 range_current_value=5
diff --git a/content/test/data/accessibility/input-time-expected-android.txt b/content/test/data/accessibility/input-time-expected-android.txt
index 254953a..7bfa623 100644
--- a/content/test/data/accessibility/input-time-expected-android.txt
+++ b/content/test/data/accessibility/input-time-expected-android.txt
@@ -1,4 +1,3 @@
android.webkit.WebView focusable focused scrollable
android.view.View
- android.view.View focusable input_type=36
- android.view.View
+ android.widget.Spinner clickable focusable name='00:00:00' input_type=36
diff --git a/content/test/data/accessibility/input-time-expected-mac.txt b/content/test/data/accessibility/input-time-expected-mac.txt
index 1dfa0b4..34bbed4 100644
--- a/content/test/data/accessibility/input-time-expected-mac.txt
+++ b/content/test/data/accessibility/input-time-expected-mac.txt
@@ -1,12 +1,12 @@
AXWebArea AXRoleDescription='HTML content'
AXGroup AXRoleDescription='group'
- AXUnknown AXRoleDescription='unknown'
+ AXTimeField AXRoleDescription='time field' AXValue='00:00:00'
AXGroup AXRoleDescription='group'
AXGroup AXRoleDescription='group'
- AXSlider AXRoleDescription='stepper' AXValue='0'
+ AXIncrementor AXRoleDescription='stepper' AXValue='12'
AXStaticText AXRoleDescription='text' AXValue=':'
- AXSlider AXRoleDescription='stepper' AXValue='0'
- AXSlider AXRoleDescription='stepper' AXValue='0'
- AXSlider AXRoleDescription='stepper' AXValue='0'
+ AXIncrementor AXRoleDescription='stepper' AXValue='0'
+ AXIncrementor AXRoleDescription='stepper' AXValue='1'
+ AXIncrementor AXRoleDescription='stepper' AXValue='0'
AXButton AXRoleDescription='button'
AXButton AXRoleDescription='button'
diff --git a/content/test/data/accessibility/input-time.html b/content/test/data/accessibility/input-time.html
index b1b2bf2..9fe33f7 100644
--- a/content/test/data/accessibility/input-time.html
+++ b/content/test/data/accessibility/input-time.html
@@ -4,6 +4,6 @@
-->
<html>
<body>
- <input type="time">
+ <input type="time" value="00:00:00">
</body>
</html>
diff --git a/content/test/data/accessibility/input-types-expected-android.txt b/content/test/data/accessibility/input-types-expected-android.txt
index c9af06b..f02b9bf 100644
--- a/content/test/data/accessibility/input-types-expected-android.txt
+++ b/content/test/data/accessibility/input-types-expected-android.txt
@@ -9,7 +9,7 @@
android.widget.CheckBox checkable clickable focusable name='Checkbox: '
android.view.View
android.view.View clickable name='Color:'
- android.view.View focusable
+ android.widget.Spinner clickable focusable name='#000000'
android.view.View
android.view.View clickable name='Email:'
android.widget.EditText editable_text focusable input_type=209
@@ -28,7 +28,7 @@
android.widget.RadioButton checkable clickable focusable name='Radio: '
android.view.View
android.view.View clickable name='Range:'
- android.widget.SeekBar focusable range item_index=50 item_count=100 range_max=100 range_current_value=50
+ android.widget.SeekBar clickable focusable range name='50' item_index=50 item_count=100 range_max=100 range_current_value=50
android.view.View
android.view.View clickable name='Reset:'
android.widget.Button clickable focusable name='Reset'
diff --git a/content/test/data/accessibility/select-expected-android.txt b/content/test/data/accessibility/select-expected-android.txt
index c7b982f..0655931 100644
--- a/content/test/data/accessibility/select-expected-android.txt
+++ b/content/test/data/accessibility/select-expected-android.txt
@@ -1,5 +1,5 @@
android.webkit.WebView focusable focused scrollable
android.view.View
- android.widget.Button clickable focusable name='Placeholder option'
- android.widget.Button clickable focusable name='Option 2'
- android.widget.Button clickable focusable name='Option 1'
+ android.widget.Spinner clickable focusable name='Placeholder option'
+ android.widget.Spinner clickable focusable name='Option 2'
+ android.widget.Spinner clickable focusable name='Option 1'
diff --git a/device/hid/hid_service_mac.cc b/device/hid/hid_service_mac.cc
index 6e091a8..7d40cae 100644
--- a/device/hid/hid_service_mac.cc
+++ b/device/hid/hid_service_mac.cc
@@ -133,6 +133,11 @@
base::ScopedCFTypeRef<IOHIDDeviceRef> hid_device(
IOHIDDeviceCreate(kCFAllocatorDefault, service));
+ if (!hid_device) {
+ VLOG(1) << "Unable to create IOHIDDevice object.";
+ return;
+ }
+
device_info->device_id = service_path;
device_info->vendor_id =
GetHidIntProperty(hid_device, CFSTR(kIOHIDVendorIDKey));
@@ -285,6 +290,12 @@
base::ScopedCFTypeRef<IOHIDDeviceRef> hid_device(
IOHIDDeviceCreate(kCFAllocatorDefault, service));
+ if (!hid_device) {
+ VLOG(1) << "Unable to create IOHIDDevice object.";
+ task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr));
+ return;
+ }
+
IOReturn result = IOHIDDeviceOpen(hid_device, kIOHIDOptionsTypeNone);
if (result != kIOReturnSuccess) {
VLOG(1) << "Failed to open device: "
diff --git a/device/usb/usb_device_handle_impl.cc b/device/usb/usb_device_handle_impl.cc
index 50c2609..6f0e286 100644
--- a/device/usb/usb_device_handle_impl.cc
+++ b/device/usb/usb_device_handle_impl.cc
@@ -498,9 +498,8 @@
scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer>
UsbDeviceHandleImpl::GetClaimedInterfaceForEndpoint(unsigned char endpoint) {
- unsigned char address = endpoint & LIBUSB_ENDPOINT_ADDRESS_MASK;
- if (ContainsKey(endpoint_map_, address))
- return claimed_interfaces_[endpoint_map_[address]];
+ if (ContainsKey(endpoint_map_, endpoint))
+ return claimed_interfaces_[endpoint_map_[endpoint]];
return NULL;
}
diff --git a/extensions/browser/updater/extension_downloader.cc b/extensions/browser/updater/extension_downloader.cc
index 3068027..da4ff41 100644
--- a/extensions/browser/updater/extension_downloader.cc
+++ b/extensions/browser/updater/extension_downloader.cc
@@ -952,13 +952,8 @@
const GURL& update_url,
int request_id) {
ManifestFetchData::PingMode ping_mode = ManifestFetchData::NO_PING;
- if (update_url.DomainIs(ping_enabled_domain_.c_str())) {
- if (enable_extra_update_metrics_) {
- ping_mode = ManifestFetchData::PING_WITH_METRICS;
- } else {
- ping_mode = ManifestFetchData::PING;
- }
- }
+ if (update_url.DomainIs(ping_enabled_domain_.c_str()))
+ ping_mode = ManifestFetchData::PING_WITH_ENABLED_STATE;
return new ManifestFetchData(
update_url, request_id, brand_code_, manifest_query_params_, ping_mode);
}
diff --git a/extensions/browser/updater/manifest_fetch_data.cc b/extensions/browser/updater/manifest_fetch_data.cc
index 2f73acb..6511a1e 100644
--- a/extensions/browser/updater/manifest_fetch_data.cc
+++ b/extensions/browser/updater/manifest_fetch_data.cc
@@ -22,7 +22,7 @@
// request. We want to stay under 2K because of proxies, etc.
const int kExtensionsManifestMaxURLSize = 2000;
-void AddMetricsToPing(std::string* ping_value,
+void AddEnabledStateToPing(std::string* ping_value,
const ManifestFetchData::PingData* ping_data) {
*ping_value += "&e=" + std::string(ping_data->is_enabled ? "1" : "0");
if (!ping_data->is_enabled) {
@@ -125,8 +125,8 @@
if (ping_data->rollcall_days == kNeverPinged ||
ping_data->rollcall_days > 0) {
ping_value += "r=" + base::IntToString(ping_data->rollcall_days);
- if (ping_mode_ == PING_WITH_METRICS)
- AddMetricsToPing(&ping_value, ping_data);
+ if (ping_mode_ == PING_WITH_ENABLED_STATE)
+ AddEnabledStateToPing(&ping_value, ping_data);
pings_[id].rollcall_days = ping_data->rollcall_days;
pings_[id].is_enabled = ping_data->is_enabled;
}
diff --git a/extensions/browser/updater/manifest_fetch_data.h b/extensions/browser/updater/manifest_fetch_data.h
index 8f33ab3..6ff3396 100644
--- a/extensions/browser/updater/manifest_fetch_data.h
+++ b/extensions/browser/updater/manifest_fetch_data.h
@@ -30,8 +30,8 @@
// Ping without extra metrics.
PING,
- // Ping with extra metrics.
- PING_WITH_METRICS,
+ // Ping with information about enabled/disabled state.
+ PING_WITH_ENABLED_STATE,
};
// Each ping type is sent at most once per day.
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json
index 5cb571e..262bae2 100644
--- a/extensions/common/api/_api_features.json
+++ b/extensions/common/api/_api_features.json
@@ -302,11 +302,6 @@
"dependencies": ["permission:usb"],
"contexts": ["blessed_extension"]
},
- "usb.getUserSelectedDevices": {
- "channel": "dev",
- "dependencies": ["permission:usb"],
- "contexts": ["blessed_extension"]
- },
"vpnProvider": {
"dependencies": ["permission:vpnProvider"],
"contexts": ["blessed_extension"]
diff --git a/extensions/common/csp_validator.cc b/extensions/common/csp_validator.cc
index 65edd0a..23af91c 100644
--- a/extensions/common/csp_validator.cc
+++ b/extensions/common/csp_validator.cc
@@ -54,6 +54,12 @@
if (end_of_host == std::string::npos)
end_of_host = url.size();
+ // A missing host such as "chrome-extension://" is invalid, but for backwards-
+ // compatibility, accept such CSP parts. They will be ignored by Blink anyway.
+ // TODO(robwu): Remove this special case once crbug.com/434773 is fixed.
+ if (start_of_host == end_of_host)
+ return true;
+
// Note: It is sufficient to only compare the first character against '*'
// because the CSP only allows wildcards at the start of a directive, see
// host-source and host-part at http://www.w3.org/TR/CSP2/#source-list-syntax
diff --git a/extensions/common/csp_validator_unittest.cc b/extensions/common/csp_validator_unittest.cc
index 9778a5a..436d450 100644
--- a/extensions/common/csp_validator_unittest.cc
+++ b/extensions/common/csp_validator_unittest.cc
@@ -98,7 +98,9 @@
"default-src 'self' *:*/", Manifest::TYPE_EXTENSION));
EXPECT_FALSE(ContentSecurityPolicyIsSecure(
"default-src 'self' *:*/path", Manifest::TYPE_EXTENSION));
- EXPECT_FALSE(ContentSecurityPolicyIsSecure(
+ // "https://" is an invalid CSP, so it will be ignored by Blink.
+ // TODO(robwu): Change to EXPECT_FALSE once http://crbug.com/434773 is fixed.
+ EXPECT_TRUE(ContentSecurityPolicyIsSecure(
"default-src 'self' https://", Manifest::TYPE_EXTENSION));
EXPECT_FALSE(ContentSecurityPolicyIsSecure(
"default-src 'self' https://*:*", Manifest::TYPE_EXTENSION));
@@ -167,6 +169,11 @@
"default-src 'self' https://*.googleapis.com", Manifest::TYPE_EXTENSION));
EXPECT_TRUE(ContentSecurityPolicyIsSecure(
"default-src 'self' https://x.googleapis.com", Manifest::TYPE_EXTENSION));
+ // "chrome-extension://" is an invalid CSP and ignored by Blink, but extension
+ // authors have been using this string anyway, so we cannot refuse this string
+ // until extensions can be loaded with an invalid CSP. http://crbug.com/434773
+ EXPECT_TRUE(ContentSecurityPolicyIsSecure(
+ "default-src 'self' chrome-extension://", Manifest::TYPE_EXTENSION));
}
TEST(ExtensionCSPValidator, IsSandboxed) {
diff --git a/google_apis/gaia/oauth2_mint_token_flow.cc b/google_apis/gaia/oauth2_mint_token_flow.cc
index 1b040cc..99562b0 100644
--- a/google_apis/gaia/oauth2_mint_token_flow.cc
+++ b/google_apis/gaia/oauth2_mint_token_flow.cc
@@ -41,6 +41,8 @@
"&scope=%s"
"&client_id=%s"
"&origin=%s";
+const char kOAuth2IssueTokenBodyFormatDeviceIdAddendum[] =
+ "&device_id=%s&device_type=chrome";
const char kIssueAdviceKey[] = "issueAdvice";
const char kIssueAdviceValueConsent[] = "consent";
const char kAccessTokenKey[] = "token";
@@ -101,8 +103,13 @@
const std::string& eid,
const std::string& cid,
const std::vector<std::string>& scopes_arg,
+ const std::string& device_id,
Mode mode_arg)
- : extension_id(eid), client_id(cid), scopes(scopes_arg), mode(mode_arg) {
+ : extension_id(eid),
+ client_id(cid),
+ scopes(scopes_arg),
+ device_id(device_id),
+ mode(mode_arg) {
}
OAuth2MintTokenFlow::Parameters::~Parameters() {}
@@ -151,7 +158,7 @@
(parameters_.mode == MODE_MINT_TOKEN_NO_FORCE ||
parameters_.mode == MODE_MINT_TOKEN_FORCE)
? kResponseTypeValueToken : kResponseTypeValueNone;
- return base::StringPrintf(
+ std::string body = base::StringPrintf(
kOAuth2IssueTokenBodyFormat,
net::EscapeUrlEncodedData(force_value, true).c_str(),
net::EscapeUrlEncodedData(response_type_value, true).c_str(),
@@ -159,6 +166,12 @@
JoinString(parameters_.scopes, ' '), true).c_str(),
net::EscapeUrlEncodedData(parameters_.client_id, true).c_str(),
net::EscapeUrlEncodedData(parameters_.extension_id, true).c_str());
+ if (!parameters_.device_id.empty()) {
+ body.append(base::StringPrintf(
+ kOAuth2IssueTokenBodyFormatDeviceIdAddendum,
+ net::EscapeUrlEncodedData(parameters_.device_id, true).c_str()));
+ }
+ return body;
}
void OAuth2MintTokenFlow::ProcessApiCallSuccess(
diff --git a/google_apis/gaia/oauth2_mint_token_flow.h b/google_apis/gaia/oauth2_mint_token_flow.h
index 1f4180d..9fe3b88 100644
--- a/google_apis/gaia/oauth2_mint_token_flow.h
+++ b/google_apis/gaia/oauth2_mint_token_flow.h
@@ -58,7 +58,7 @@
// scoped "master" OAuth2 token for the user logged in to Chrome.
class OAuth2MintTokenFlow : public OAuth2ApiCallFlow {
public:
- // There are four differnt modes when minting a token to grant
+ // There are four different modes when minting a token to grant
// access to third-party app for a user.
enum Mode {
// Get the messages to display to the user without minting a token.
@@ -78,12 +78,14 @@
Parameters(const std::string& eid,
const std::string& cid,
const std::vector<std::string>& scopes_arg,
+ const std::string& device_id,
Mode mode_arg);
~Parameters();
std::string extension_id;
std::string client_id;
std::vector<std::string> scopes;
+ std::string device_id;
Mode mode;
};
diff --git a/google_apis/gaia/oauth2_mint_token_flow_unittest.cc b/google_apis/gaia/oauth2_mint_token_flow_unittest.cc
index cd5508e..c60ad31 100644
--- a/google_apis/gaia/oauth2_mint_token_flow_unittest.cc
+++ b/google_apis/gaia/oauth2_mint_token_flow_unittest.cc
@@ -154,17 +154,23 @@
protected:
void CreateFlow(OAuth2MintTokenFlow::Mode mode) {
- return CreateFlow(&delegate_, mode);
+ return CreateFlow(&delegate_, mode, "");
+ }
+
+ void CreateFlowWithDeviceId(const std::string& device_id) {
+ return CreateFlow(&delegate_, OAuth2MintTokenFlow::MODE_ISSUE_ADVICE,
+ device_id);
}
void CreateFlow(MockDelegate* delegate,
- OAuth2MintTokenFlow::Mode mode) {
+ OAuth2MintTokenFlow::Mode mode,
+ const std::string& device_id) {
std::string ext_id = "ext1";
std::string client_id = "client1";
std::vector<std::string> scopes(CreateTestScopes());
flow_.reset(new MockMintTokenFlow(
- delegate,
- OAuth2MintTokenFlow::Parameters(ext_id, client_id, scopes, mode)));
+ delegate, OAuth2MintTokenFlow::Parameters(ext_id, client_id, scopes,
+ device_id, mode)));
}
// Helper to parse the given string to DictionaryValue.
@@ -184,11 +190,11 @@
CreateFlow(OAuth2MintTokenFlow::MODE_ISSUE_ADVICE);
std::string body = flow_->CreateApiCallBody();
std::string expected_body(
- "force=false"
- "&response_type=none"
- "&scope=http://scope1+http://scope2"
- "&client_id=client1"
- "&origin=ext1");
+ "force=false"
+ "&response_type=none"
+ "&scope=http://scope1+http://scope2"
+ "&client_id=client1"
+ "&origin=ext1");
EXPECT_EQ(expected_body, body);
}
{ // Record grant mode.
@@ -224,6 +230,19 @@
"&origin=ext1");
EXPECT_EQ(expected_body, body);
}
+ { // Mint token with device_id.
+ CreateFlowWithDeviceId("device_id1");
+ std::string body = flow_->CreateApiCallBody();
+ std::string expected_body(
+ "force=false"
+ "&response_type=none"
+ "&scope=http://scope1+http://scope2"
+ "&client_id=client1"
+ "&origin=ext1"
+ "&device_id=device_id1"
+ "&device_type=chrome");
+ EXPECT_EQ(expected_body, body);
+ }
}
TEST_F(OAuth2MintTokenFlowTest, ParseMintTokenResponse) {
@@ -332,7 +351,7 @@
{ // Null delegate should work fine.
TestURLFetcher url_fetcher(1, GURL("http://www.google.com"), NULL);
url_fetcher.set_status(URLRequestStatus(URLRequestStatus::FAILED, 101));
- CreateFlow(NULL, OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE);
+ CreateFlow(NULL, OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE, "");
flow_->ProcessApiCallFailure(&url_fetcher);
}
diff --git a/google_apis/gcm/engine/account_mapping.cc b/google_apis/gcm/engine/account_mapping.cc
index e154077..db7b3a1 100644
--- a/google_apis/gcm/engine/account_mapping.cc
+++ b/google_apis/gcm/engine/account_mapping.cc
@@ -100,10 +100,8 @@
if (!StringToStatus(values[kStatusIndex], &temp_status))
return false;
- if (values.size() == kSizeWithNoMessage &&
- (temp_status == REMOVING || temp_status == ADDING)) {
+ if (values.size() == kSizeWithNoMessage && temp_status == ADDING)
return false;
- }
int64 status_change_ts_internal = 0LL;
if (!base::StringToInt64(values[kStatusChangeTimestampIndex],
diff --git a/google_apis/gcm/engine/account_mapping_unittest.cc b/google_apis/gcm/engine/account_mapping_unittest.cc
index 5ce5d05..f4764f1 100644
--- a/google_apis/gcm/engine/account_mapping_unittest.cc
+++ b/google_apis/gcm/engine/account_mapping_unittest.cc
@@ -45,6 +45,12 @@
account_mapping.email = "test@gmail.com";
account_mapping.access_token = "access_token"; // should be ignored.
account_mapping.status = AccountMapping::REMOVING;
+
+ // Serialize removing message without a message_id.
+ EXPECT_EQ("test@gmail.com&removing&1305797421259977",
+ account_mapping.SerializeAsString());
+
+ // Add a message ID and serialize again.
account_mapping.last_message_id = "last_message_id_2";
EXPECT_EQ("test@gmail.com&removing&1305797421259977&last_message_id_2",
@@ -102,6 +108,16 @@
EXPECT_EQ(base::Time::FromInternalValue(1305797421259977LL),
account_mapping.status_change_timestamp);
EXPECT_EQ("last_message_id_2", account_mapping.last_message_id);
+
+ EXPECT_TRUE(account_mapping.ParseFromString(
+ "test@gmail.com&removing&1305797421259935"));
+ EXPECT_EQ("acc_id", account_mapping.account_id);
+ EXPECT_EQ("test@gmail.com", account_mapping.email);
+ EXPECT_TRUE(account_mapping.access_token.empty());
+ EXPECT_EQ(AccountMapping::REMOVING, account_mapping.status);
+ EXPECT_EQ(base::Time::FromInternalValue(1305797421259935LL),
+ account_mapping.status_change_timestamp);
+ EXPECT_TRUE(account_mapping.last_message_id.empty());
}
TEST(AccountMappingTest, DeserializeAccountMappingInvalidInput) {
@@ -112,9 +128,6 @@
"test@example.com&adding&1305797421259935&last_message_id_1&stuff_here"));
// Too few arguments.
EXPECT_FALSE(account_mapping.ParseFromString(
- "test@example.com&removing&1305797421259935"));
- // Too few arguments.
- EXPECT_FALSE(account_mapping.ParseFromString(
"test@example.com&adding&1305797421259935"));
// Too few arguments.
EXPECT_FALSE(account_mapping.ParseFromString(
@@ -137,9 +150,6 @@
// Last mapping status change timestamp not parseable.
EXPECT_FALSE(account_mapping.ParseFromString(
"test@gmail.com&removing&asdfjkl&last_message_id_2"));
- // Missing last message ID.
- EXPECT_FALSE(account_mapping.ParseFromString(
- "test@example.com&removing&1305797421259935&"));
}
} // namespace
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 241056c..de53a6e 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -296,8 +296,11 @@
WaitForCmd();
query_tracker_.reset();
- if (support_client_side_arrays_)
+ // GLES2Implementation::Initialize() could fail before allocating
+ // reserved_ids_, so we need delete them carefully.
+ if (support_client_side_arrays_ && reserved_ids_[0]) {
DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]);
+ }
// Release any per-context data in share group.
share_group_->FreeContext(this);
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc
index 799618c..a004e38 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest.cc
+++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -93,7 +93,8 @@
CommandBuffer* command_buffer,
unsigned int size,
unsigned int result_size,
- unsigned int alignment)
+ unsigned int alignment,
+ bool initialize_fail)
: command_buffer_(command_buffer),
size_(size),
result_size_(result_size),
@@ -102,7 +103,8 @@
expected_buffer_index_(0),
last_alloc_(NULL),
expected_offset_(result_size),
- actual_offset_(result_size) {
+ actual_offset_(result_size),
+ initialize_fail_(initialize_fail) {
// We have to allocate the buffers here because
// we need to know their address before GLES2Implementation::Initialize
// is called.
@@ -220,6 +222,7 @@
void* last_alloc_;
uint32 expected_offset_;
uint32 actual_offset_;
+ bool initialize_fail_;
DISALLOW_COPY_AND_ASSIGN(MockTransferBuffer);
};
@@ -234,7 +237,7 @@
// Just check they match.
return size_ == starting_buffer_size &&
result_size_ == result_size &&
- alignment_ == alignment;
+ alignment_ == alignment && !initialize_fail_;
};
int MockTransferBuffer::GetShmId() {
@@ -394,7 +397,8 @@
bool Initialize(ShareGroup* share_group,
bool bind_generates_resource_client,
bool bind_generates_resource_service,
- bool lose_context_when_out_of_memory) {
+ bool lose_context_when_out_of_memory,
+ bool transfer_buffer_initialize_fail) {
command_buffer_.reset(new StrictMock<MockClientCommandBuffer>());
if (!command_buffer_->Initialize())
return false;
@@ -403,7 +407,8 @@
new MockTransferBuffer(command_buffer_.get(),
kTransferBufferSize,
GLES2Implementation::kStartingOffset,
- GLES2Implementation::kAlignment));
+ GLES2Implementation::kAlignment,
+ transfer_buffer_initialize_fail));
helper_.reset(new GLES2CmdHelper(command_buffer()));
helper_->Initialize(kCommandBufferSizeBytes);
@@ -530,11 +535,13 @@
ContextInitOptions()
: bind_generates_resource_client(true),
bind_generates_resource_service(true),
- lose_context_when_out_of_memory(false) {}
+ lose_context_when_out_of_memory(false),
+ transfer_buffer_initialize_fail(false) {}
bool bind_generates_resource_client;
bool bind_generates_resource_service;
bool lose_context_when_out_of_memory;
+ bool transfer_buffer_initialize_fail;
};
bool Initialize(const ContextInitOptions& init_options) {
@@ -546,7 +553,8 @@
share_group_.get(),
init_options.bind_generates_resource_client,
init_options.bind_generates_resource_service,
- init_options.lose_context_when_out_of_memory))
+ init_options.lose_context_when_out_of_memory,
+ init_options.transfer_buffer_initialize_fail))
success = false;
}
@@ -3410,6 +3418,12 @@
EXPECT_FALSE(Initialize(init_options));
}
+TEST_F(GLES2ImplementationManualInitTest, FailInitOnTransferBufferFail) {
+ ContextInitOptions init_options;
+ init_options.transfer_buffer_initialize_fail = true;
+ EXPECT_FALSE(Initialize(init_options));
+}
+
#include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h"
} // namespace gles2
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index 9be747d..b06292a 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -842,6 +842,9 @@
if (workarounds_.disable_egl_khr_fence_sync) {
gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync = false;
}
+ if (workarounds_.disable_egl_khr_wait_sync) {
+ gfx::g_driver_egl.ext.b_EGL_KHR_wait_sync = false;
+ }
#endif
if (workarounds_.disable_arb_sync)
gfx::g_driver_gl.ext.b_GL_ARB_sync = false;
diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc
index c9b5335..e1e9650 100644
--- a/gpu/config/gpu_driver_bug_list_json.cc
+++ b/gpu/config/gpu_driver_bug_list_json.cc
@@ -19,7 +19,7 @@
{
"name": "gpu driver bug list",
// Please update the version number whenever you change this file.
- "version": "7.7",
+ "version": "7.8",
"entries": [
{
"id": 1,
@@ -1046,6 +1046,27 @@
"features": [
"disable_async_readpixels"
]
+ },
+ {
+ "id": 94,
+ "description": "Disable EGL_KHR_wait_sync on NVIDIA with GLES 3.1",
+ "cr_bugs": [433057],
+ "os": {
+ "type": "android",
+ "version": {
+ "op": "<=",
+ "value": "5.0.0"
+ }
+ },
+ "gl_vendor": "NVIDIA.*",
+ "gl_type": "gles",
+ "gl_version": {
+ "op": "=",
+ "value": "3.1"
+ },
+ "features": [
+ "disable_egl_khr_wait_sync"
+ ]
}
]
}
diff --git a/gpu/config/gpu_driver_bug_workaround_type.h b/gpu/config/gpu_driver_bug_workaround_type.h
index 871798e..0cd9761 100644
--- a/gpu/config/gpu_driver_bug_workaround_type.h
+++ b/gpu/config/gpu_driver_bug_workaround_type.h
@@ -28,6 +28,8 @@
disable_depth_texture) \
GPU_OP(DISABLE_EGL_KHR_FENCE_SYNC, \
disable_egl_khr_fence_sync) \
+ GPU_OP(DISABLE_EGL_KHR_WAIT_SYNC, \
+ disable_egl_khr_wait_sync) \
GPU_OP(DISABLE_EXT_DISCARD_FRAMEBUFFER, \
disable_ext_discard_framebuffer) \
GPU_OP(DISABLE_EXT_DRAW_BUFFERS, \
diff --git a/media/audio/mac/audio_low_latency_input_mac.cc b/media/audio/mac/audio_low_latency_input_mac.cc
index 6e01eda..fdd072a 100644
--- a/media/audio/mac/audio_low_latency_input_mac.cc
+++ b/media/audio/mac/audio_low_latency_input_mac.cc
@@ -466,15 +466,18 @@
// |mDataByteSize| needs to be exactly mapping to |number_of_frames|,
// otherwise it will put CoreAudio into bad state and results in
// AudioUnitRender() returning -50 for the new created stream.
+ // We have also seen kAudioUnitErr_TooManyFramesToProcess (-10874) and
+ // kAudioUnitErr_CannotDoInCurrentContext (-10863) as error codes.
// See crbug/428706 for details.
UInt32 new_size = number_of_frames * audio_input->format_.mBytesPerFrame;
AudioBuffer* audio_buffer = audio_input->audio_buffer_list()->mBuffers;
if (new_size != audio_buffer->mDataByteSize) {
if (new_size > audio_buffer->mDataByteSize) {
- // This can happen iff the device is unpluged during recording. In such
- // case the buffer will not be used anymore since |audio_unit_| becomes
- // invalid. We allocate enough memory here to avoid depending on
- // how CoreAudio handles it.
+ // This can happen if the device is unpluged during recording. We
+ // allocate enough memory here to avoid depending on how CoreAudio
+ // handles it.
+ // See See http://www.crbug.com/434681 for one example when we can enter
+ // this scope.
audio_input->audio_data_buffer_.reset(new uint8[new_size]);
audio_buffer->mData = audio_input->audio_data_buffer_.get();
}
@@ -492,7 +495,7 @@
audio_input->audio_buffer_list());
if (result) {
UMA_HISTOGRAM_SPARSE_SLOWLY("Media.AudioInputCbErrorMac", result);
- OSSTATUS_DLOG(ERROR, result) << "AudioUnitRender() failed.";
+ OSSTATUS_DLOG(ERROR, result) << "AudioUnitRender() failed ";
return result;
}
@@ -522,6 +525,21 @@
if (!audio_data)
return kAudioUnitErr_InvalidElement;
+ // Dynamically increase capacity of the FIFO to handle larger buffers from
+ // CoreAudio. This can happen in combination with Apple Thunderbolt Displays
+ // when the Display Audio is used as capture source and the cable is first
+ // remove and then inserted again.
+ // See http://www.crbug.com/434681 for details.
+ if (static_cast<int>(number_of_frames) > fifo_.GetUnfilledFrames()) {
+ // Derive required increase in number of FIFO blocks. The increase is
+ // typically one block.
+ const int blocks =
+ static_cast<int>((number_of_frames - fifo_.GetUnfilledFrames()) /
+ number_of_frames_) + 1;
+ DLOG(WARNING) << "Increasing FIFO capacity by " << blocks << " blocks";
+ fifo_.IncreaseCapacity(blocks);
+ }
+
// Copy captured (and interleaved) data into FIFO.
fifo_.Push(audio_data, number_of_frames, format_.mBitsPerChannel / 8);
diff --git a/native_client_sdk/src/build_tools/build_sdk.py b/native_client_sdk/src/build_tools/build_sdk.py
index cac1e0c..1d9c6ed 100755
--- a/native_client_sdk/src/build_tools/build_sdk.py
+++ b/native_client_sdk/src/build_tools/build_sdk.py
@@ -57,7 +57,7 @@
PKGVER = os.path.join(BUILD_DIR, 'package_version', 'package_version.py')
NACLPORTS_URL = 'https://chromium.googlesource.com/external/naclports.git'
-NACLPORTS_REV = '873ca4910a5f9d4206306aacb4ed79c587c6a5f3'
+NACLPORTS_REV = 'e53078c33d99b0b3cbadbbbbb92cccf7a48d5dc1'
GYPBUILD_DIR = 'gypbuild'
diff --git a/native_client_sdk/src/gonacl_appengine/src/bullet/build.sh b/native_client_sdk/src/gonacl_appengine/src/bullet/build.sh
index 0c49958..55a0fd9 100755
--- a/native_client_sdk/src/gonacl_appengine/src/bullet/build.sh
+++ b/native_client_sdk/src/gonacl_appengine/src/bullet/build.sh
@@ -11,7 +11,7 @@
OUT_DIR=out
NACLPORTS_URL=https://chromium.googlesource.com/external/naclports.git
-NACLPORTS_SHA=873ca4910a5f9d4206306aacb4ed79c587c6a5f3
+NACLPORTS_SHA=e53078c33d99b0b3cbadbbbbb92cccf7a48d5dc1
NACLPORTS_DIR=${OUT_DIR}/naclports
NACLAM_URL=https://github.com/johnmccutchan/NaClAMBase
NACLAM_DIR=${OUT_DIR}/NaClAMBase
diff --git a/native_client_sdk/src/gonacl_appengine/src/lua/build.sh b/native_client_sdk/src/gonacl_appengine/src/lua/build.sh
index ac14759..c1afeb0 100755
--- a/native_client_sdk/src/gonacl_appengine/src/lua/build.sh
+++ b/native_client_sdk/src/gonacl_appengine/src/lua/build.sh
@@ -11,7 +11,7 @@
OUT_DIR=out
NACLPORTS_URL=https://chromium.googlesource.com/external/naclports.git
-NACLPORTS_REV=873ca4910a5f9d4206306aacb4ed79c587c6a5f3
+NACLPORTS_REV=e53078c33d99b0b3cbadbbbbb92cccf7a48d5dc1
NACLPORTS_DIR=${OUT_DIR}/naclports
if [ -z "${NACL_SDK_ROOT:-}" ]; then
diff --git a/net/http/disk_cache_based_quic_server_info.cc b/net/http/disk_cache_based_quic_server_info.cc
index 4ed2bfa..148df3f 100644
--- a/net/http/disk_cache_based_quic_server_info.cc
+++ b/net/http/disk_cache_based_quic_server_info.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/callback.h"
+#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "net/base/completion_callback.h"
@@ -56,6 +57,7 @@
http_cache_(http_cache),
backend_(NULL),
entry_(NULL),
+ last_failure_(NO_FAILURE),
weak_factory_(this) {
io_callback_ =
base::Bind(&DiskCacheBasedQuicServerInfo::OnIOComplete,
@@ -66,6 +68,7 @@
void DiskCacheBasedQuicServerInfo::Start() {
DCHECK(CalledOnValidThread());
DCHECK_EQ(GET_BACKEND, state_);
+ DCHECK_EQ(last_failure_, NO_FAILURE);
RecordQuicServerInfoStatus(QUIC_SERVER_INFO_START);
load_start_time_ = base::TimeTicks::Now();
DoLoop(OK);
@@ -77,18 +80,19 @@
DCHECK_NE(GET_BACKEND, state_);
RecordQuicServerInfoStatus(QUIC_SERVER_INFO_WAIT_FOR_DATA_READY);
- if (ready_)
+ if (ready_) {
+ RecordLastFailure();
return OK;
+ }
if (!callback.is_null()) {
// Prevent a new callback for WaitForDataReady overwriting an existing
- // pending callback (|user_callback_|).
- // TODO(rtenneti): Rename user_callback_ as wait_for_ready_callback_.
- if (!user_callback_.is_null()) {
+ // pending callback (|wait_for_ready_callback_|).
+ if (!wait_for_ready_callback_.is_null()) {
RecordQuicServerInfoFailure(WAIT_FOR_DATA_READY_INVALID_ARGUMENT_FAILURE);
return ERR_INVALID_ARGUMENT;
}
- user_callback_ = callback;
+ wait_for_ready_callback_ = callback;
}
return ERR_IO_PENDING;
@@ -98,8 +102,10 @@
DCHECK(CalledOnValidThread());
RecordQuicServerInfoStatus(QUIC_SERVER_INFO_WAIT_FOR_DATA_READY_CANCEL);
- if (!user_callback_.is_null())
- user_callback_.Reset();
+ if (!wait_for_ready_callback_.is_null()) {
+ RecordLastFailure();
+ wait_for_ready_callback_.Reset();
+ }
}
bool DiskCacheBasedQuicServerInfo::IsDataReady() {
@@ -131,10 +137,10 @@
void DiskCacheBasedQuicServerInfo::PersistInternal() {
DCHECK(CalledOnValidThread());
DCHECK_NE(GET_BACKEND, state_);
-
DCHECK(new_data_.empty());
CHECK(ready_);
- DCHECK(user_callback_.is_null());
+ DCHECK(wait_for_ready_callback_.is_null());
+
if (pending_write_data_.empty()) {
new_data_ = Serialize();
} else {
@@ -166,7 +172,7 @@
}
DiskCacheBasedQuicServerInfo::~DiskCacheBasedQuicServerInfo() {
- DCHECK(user_callback_.is_null());
+ DCHECK(wait_for_ready_callback_.is_null());
if (entry_)
entry_->Close();
}
@@ -181,10 +187,9 @@
rv = DoLoop(rv);
if (rv == ERR_IO_PENDING)
return;
- if (!user_callback_.is_null()) {
- CompletionCallback callback = user_callback_;
- user_callback_.Reset();
- callback.Run(rv);
+ if (!wait_for_ready_callback_.is_null()) {
+ RecordLastFailure();
+ base::ResetAndReturn(&wait_for_ready_callback_).Run(rv);
}
if (ready_ && !pending_write_data_.empty()) {
DCHECK_EQ(NONE, state_);
@@ -390,8 +395,19 @@
}
}
+void DiskCacheBasedQuicServerInfo::RecordLastFailure() {
+ if (last_failure_ != NO_FAILURE) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Net.QuicDiskCache.FailureReason.WaitForDataReady",
+ last_failure_, NUM_OF_FAILURES);
+ }
+ last_failure_ = NO_FAILURE;
+}
+
void DiskCacheBasedQuicServerInfo::RecordQuicServerInfoFailure(
FailureReason failure) {
+ last_failure_ = failure;
+
if (!backend_) {
UMA_HISTOGRAM_ENUMERATION("Net.QuicDiskCache.FailureReason.NoBackend",
failure, NUM_OF_FAILURES);
diff --git a/net/http/disk_cache_based_quic_server_info.h b/net/http/disk_cache_based_quic_server_info.h
index 0da2e1d..e95d535 100644
--- a/net/http/disk_cache_based_quic_server_info.h
+++ b/net/http/disk_cache_based_quic_server_info.h
@@ -85,7 +85,8 @@
READY_TO_PERSIST_FAILURE = 7,
PERSIST_NO_BACKEND_FAILURE = 8,
WRITE_FAILURE = 9,
- NUM_OF_FAILURES = 10,
+ NO_FAILURE = 10,
+ NUM_OF_FAILURES = 11,
};
~DiskCacheBasedQuicServerInfo() override;
@@ -126,9 +127,13 @@
void RecordQuicServerInfoStatus(QuicServerInfoAPICall call);
// Tracks in a histogram the failure reasons to read/load/write of
- // QuicServerInfo to and from disk cache.
+ // QuicServerInfo to and from disk cache. It also saves the |failure| in
+ // |last_failure_|.
void RecordQuicServerInfoFailure(FailureReason failure);
+ // Tracks in a histogram if |last_failure_| is not NO_FAILURE.
+ void RecordLastFailure();
+
CacheOperationDataShim* data_shim_; // Owned by |io_callback_|.
CompletionCallback io_callback_;
State state_;
@@ -140,13 +145,16 @@
HttpCache* const http_cache_;
disk_cache::Backend* backend_;
disk_cache::Entry* entry_;
- CompletionCallback user_callback_;
+ CompletionCallback wait_for_ready_callback_;
scoped_refptr<IOBuffer> read_buffer_;
scoped_refptr<IOBuffer> write_buffer_;
std::string data_;
base::TimeTicks load_start_time_;
+ FailureReason last_failure_;
base::WeakPtrFactory<DiskCacheBasedQuicServerInfo> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(DiskCacheBasedQuicServerInfo);
};
} // namespace net
diff --git a/net/proxy/proxy_config_service_android.cc b/net/proxy/proxy_config_service_android.cc
index f1a0b6c..50407fe 100644
--- a/net/proxy/proxy_config_service_android.cc
+++ b/net/proxy/proxy_config_service_android.cc
@@ -197,7 +197,8 @@
: jni_delegate_(this),
network_task_runner_(network_task_runner),
jni_task_runner_(jni_task_runner),
- get_property_callback_(get_property_callback) {
+ get_property_callback_(get_property_callback),
+ exclude_pac_url_(false) {
}
void SetupJNI() {
@@ -271,13 +272,22 @@
const std::vector<std::string>& exclusion_list) {
DCHECK(OnJNIThread());
ProxyConfig proxy_config;
- CreateStaticProxyConfig(host, port, pac_url, exclusion_list, &proxy_config);
+ if (exclude_pac_url_) {
+ CreateStaticProxyConfig(host, port, "", exclusion_list, &proxy_config);
+ } else {
+ CreateStaticProxyConfig(host, port, pac_url, exclusion_list,
+ &proxy_config);
+ }
network_task_runner_->PostTask(
FROM_HERE,
base::Bind(
&Delegate::SetNewConfigOnNetworkThread, this, proxy_config));
}
+ void set_exclude_pac_url(bool enabled) {
+ exclude_pac_url_ = enabled;
+ }
+
private:
friend class base::RefCountedThreadSafe<Delegate>;
@@ -344,6 +354,7 @@
scoped_refptr<base::SequencedTaskRunner> jni_task_runner_;
GetPropertyCallback get_property_callback_;
ProxyConfig proxy_config_;
+ bool exclude_pac_url_;
DISALLOW_COPY_AND_ASSIGN(Delegate);
};
@@ -366,6 +377,10 @@
return RegisterNativesImpl(env);
}
+void ProxyConfigServiceAndroid::set_exclude_pac_url(bool enabled) {
+ delegate_->set_exclude_pac_url(enabled);
+}
+
void ProxyConfigServiceAndroid::AddObserver(Observer* observer) {
delegate_->AddObserver(observer);
}
diff --git a/net/proxy/proxy_config_service_android.h b/net/proxy/proxy_config_service_android.h
index d642d37..cb15bc5 100644
--- a/net/proxy/proxy_config_service_android.h
+++ b/net/proxy/proxy_config_service_android.h
@@ -64,6 +64,11 @@
// Register JNI bindings.
static bool Register(JNIEnv* env);
+ // Android provides a local HTTP proxy that does PAC resolution. When this
+ // setting is enabled, the proxy config service ignores the PAC URL and uses
+ // the local proxy for all proxy resolution.
+ void set_exclude_pac_url(bool enabled);
+
// ProxyConfigService:
// Called only on the network thread.
virtual void AddObserver(Observer* observer) override;
diff --git a/net/url_request/url_request_job_manager.h b/net/url_request/url_request_job_manager.h
index 9877bed..4fe6376 100644
--- a/net/url_request/url_request_job_manager.h
+++ b/net/url_request/url_request_job_manager.h
@@ -10,6 +10,7 @@
#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
+#include "net/base/net_export.h"
#include "net/url_request/url_request.h"
template <typename T> struct DefaultSingletonTraits;
@@ -24,7 +25,7 @@
// URLRequest is designed to have all consumers on a single thread, and
// so no attempt is made to support Interceptor instances being
// registered/unregistered or in any way poked on multiple threads.
-class URLRequestJobManager {
+class NET_EXPORT URLRequestJobManager {
public:
// Returns the singleton instance.
static URLRequestJobManager* GetInstance();
diff --git a/remoting/codec/video_encoder_vpx.cc b/remoting/codec/video_encoder_vpx.cc
index 3ee9e6a..d45da40 100644
--- a/remoting/codec/video_encoder_vpx.cc
+++ b/remoting/codec/video_encoder_vpx.cc
@@ -56,6 +56,9 @@
// Start emitting packets immediately.
config->g_lag_in_frames = 0;
+ // Since the transport layer is reliable, keyframes aren't necessary.
+ config->kf_mode = VPX_KF_DISABLED;
+
// Using 2 threads gives a great boost in performance for most systems with
// adequate processing power. NB: Going to multiple threads on low end
// windows systems can really hurt performance.
diff --git a/remoting/host/installer/linux/debian/postinst b/remoting/host/installer/linux/debian/postinst
index 10d6fc5..b7adfc4 100755
--- a/remoting/host/installer/linux/debian/postinst
+++ b/remoting/host/installer/linux/debian/postinst
@@ -22,8 +22,10 @@
case "$1" in
"configure")
# Kill host processes. The wrapper script will restart them.
+ # TODO(lambroslambrou): Remove the '-9' when the underlying problem with
+ # hosts not responding to SIGTERM has been fixed - http://crbug.com/420090
echo "Shutting down Chrome Remote Desktop hosts (they will restart automatically)..."
- killall -q chrome-remote-desktop-host || true
+ killall -9 -q chrome-remote-desktop-host || true
# If any files have changed that require the user to restart their virtual
# desktops (eg, the wrapper script itself) then notify them but don't do
# anything that would result in them losing state.
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc
index f880803..40bc6fb 100644
--- a/remoting/host/remoting_me2me_host.cc
+++ b/remoting/host/remoting_me2me_host.cc
@@ -936,20 +936,21 @@
void HostProcess::ApplyHostDomainPolicy() {
HOST_LOG << "Policy sets host domain: " << host_domain_;
- // If the user does not have a Google email, their client JID will not be
- // based on their email. In that case, the username/host domain policies would
- // be meaningless, since there is no way to check that the JID attempting to
- // connect actually corresponds to the owner email in question.
- if (host_owner_ != host_owner_email_) {
- LOG(ERROR) << "The username and host domain policies cannot be enabled for "
- << "accounts with a non-Google email.";
- ShutdownHost(kInvalidHostDomainExitCode);
- }
+ if (!host_domain_.empty()) {
+ // If the user does not have a Google email, their client JID will not be
+ // based on their email. In that case, the username/host domain policies
+ // would be meaningless, since there is no way to check that the JID
+ // trying to connect actually corresponds to the owner email in question.
+ if (host_owner_ != host_owner_email_) {
+ LOG(ERROR) << "The username and host domain policies cannot be enabled "
+ << "for accounts with a non-Google email.";
+ ShutdownHost(kInvalidHostDomainExitCode);
+ }
- if (!host_domain_.empty() &&
- !EndsWith(host_owner_, std::string("@") + host_domain_, false)) {
- LOG(ERROR) << "The host domain does not match the policy.";
- ShutdownHost(kInvalidHostDomainExitCode);
+ if (!EndsWith(host_owner_, std::string("@") + host_domain_, false)) {
+ LOG(ERROR) << "The host domain does not match the policy.";
+ ShutdownHost(kInvalidHostDomainExitCode);
+ }
}
}
@@ -967,15 +968,16 @@
}
void HostProcess::ApplyUsernamePolicy() {
- // See comment in ApplyHostDomainPolicy.
- if (host_owner_ != host_owner_email_) {
- LOG(ERROR) << "The username and host domain policies cannot be enabled for "
- << "accounts with a non-Google email.";
- ShutdownHost(kUsernameMismatchExitCode);
- }
-
if (host_username_match_required_) {
HOST_LOG << "Policy requires host username match.";
+
+ // See comment in ApplyHostDomainPolicy.
+ if (host_owner_ != host_owner_email_) {
+ LOG(ERROR) << "The username and host domain policies cannot be enabled "
+ << "for accounts with a non-Google email.";
+ ShutdownHost(kUsernameMismatchExitCode);
+ }
+
std::string username = GetUsername();
bool shutdown = username.empty() ||
!StartsWithASCII(host_owner_, username + std::string("@"),
diff --git a/remoting/webapp/crd/js/client_session.js b/remoting/webapp/crd/js/client_session.js
index 456f8ad..cbe22d4 100644
--- a/remoting/webapp/crd/js/client_session.js
+++ b/remoting/webapp/crd/js/client_session.js
@@ -993,6 +993,16 @@
* @param {boolean} ready True if the connection is ready.
*/
remoting.ClientSession.prototype.onConnectionReady_ = function(ready) {
+ // TODO(jamiewalch): Currently, the logic for determining whether or not the
+ // connection is available is based solely on whether or not any video frames
+ // have been received recently. which leads to poor UX on slow connections.
+ // Re-enable this once crbug.com/435315 has been fixed.
+ var ignoreVideoChannelState = true;
+ if (ignoreVideoChannelState) {
+ console.log('Video channel ' + (ready ? '' : 'not ') + 'ready.');
+ return;
+ }
+
if (!ready) {
this.container_.classList.add('session-client-inactive');
} else {
diff --git a/remoting/webapp/crd/js/host_controller.js b/remoting/webapp/crd/js/host_controller.js
index 7473c8c..45ef366 100644
--- a/remoting/webapp/crd/js/host_controller.js
+++ b/remoting/webapp/crd/js/host_controller.js
@@ -253,7 +253,8 @@
newHostId, hostPin, startHostWithHash.bind(
null, hostName, publicKey, privateKey,
remoting.identity.getCachedEmail(),
- remoting.oauth2.getRefreshToken()),
+ remoting.oauth2.getRefreshToken(),
+ remoting.identity.getCachedEmail()),
onError);
}
} else {
diff --git a/third_party/libaddressinput/BUILD.gn b/third_party/libaddressinput/BUILD.gn
index bb32d46..6f5d903 100644
--- a/third_party/libaddressinput/BUILD.gn
+++ b/third_party/libaddressinput/BUILD.gn
@@ -128,6 +128,57 @@
if (is_android) {
import("//build/config/android/rules.gni")
+ # GYP: //third_party/libaddressinput/libaddressinput.gyp:libaddressinput_android_strings_grd
+ java_strings_grd("libaddressinput_android_strings_grd") {
+ grd_file = "//chrome/app/address_input_strings_android.grd"
+ outputs = [
+ "values-am/address_input_strings.xml",
+ "values-ar/address_input_strings.xml",
+ "values-bg/address_input_strings.xml",
+ "values-ca/address_input_strings.xml",
+ "values-cs/address_input_strings.xml",
+ "values-da/address_input_strings.xml",
+ "values-de/address_input_strings.xml",
+ "values-el/address_input_strings.xml",
+ "values-en-rGB/address_input_strings.xml",
+ "values-es-rUS/address_input_strings.xml",
+ "values-es/address_input_strings.xml",
+ "values-fa/address_input_strings.xml",
+ "values-fi/address_input_strings.xml",
+ "values-fr/address_input_strings.xml",
+ "values-hi/address_input_strings.xml",
+ "values-hr/address_input_strings.xml",
+ "values-hu/address_input_strings.xml",
+ "values-in/address_input_strings.xml",
+ "values-it/address_input_strings.xml",
+ "values-iw/address_input_strings.xml",
+ "values-ja/address_input_strings.xml",
+ "values-ko/address_input_strings.xml",
+ "values-lt/address_input_strings.xml",
+ "values-lv/address_input_strings.xml",
+ "values-nb/address_input_strings.xml",
+ "values-nl/address_input_strings.xml",
+ "values-pl/address_input_strings.xml",
+ "values-pt-rBR/address_input_strings.xml",
+ "values-pt-rPT/address_input_strings.xml",
+ "values-ro/address_input_strings.xml",
+ "values-ru/address_input_strings.xml",
+ "values-sk/address_input_strings.xml",
+ "values-sl/address_input_strings.xml",
+ "values-sr/address_input_strings.xml",
+ "values-sv/address_input_strings.xml",
+ "values-sw/address_input_strings.xml",
+ "values-th/address_input_strings.xml",
+ "values-tl/address_input_strings.xml",
+ "values-tr/address_input_strings.xml",
+ "values-uk/address_input_strings.xml",
+ "values-vi/address_input_strings.xml",
+ "values-zh-rCN/address_input_strings.xml",
+ "values-zh-rTW/address_input_strings.xml",
+ "values/address_input_strings.xml",
+ ]
+ }
+
android_resources("android_addressinput_widget_resources") {
custom_package = "com.android.i18n.addressinput"
resource_dirs = [ "src/java/res" ]
@@ -137,7 +188,10 @@
# GYP: //third_party/libaddressinput/libaddressinput.gyp:android_addressinput_widget
android_library("android_addressinput_widget_java") {
DEPRECATED_java_in_dir = "src/java/src"
- deps = [ ":android_addressinput_widget_resources" ]
+ deps = [
+ ":android_addressinput_widget_resources",
+ ":libaddressinput_android_strings_grd",
+ ]
}
} else {
# The list of files in libaddressinput.gypi.
diff --git a/third_party/libaddressinput/libaddressinput.gyp b/third_party/libaddressinput/libaddressinput.gyp
index db2b466..2ea754b 100644
--- a/third_party/libaddressinput/libaddressinput.gyp
+++ b/third_party/libaddressinput/libaddressinput.gyp
@@ -165,6 +165,18 @@
['OS=="android"', {
'targets': [
{
+ # GN: //third_party/libaddressinput:libaddressinput_android_strings_grd
+ 'target_name': 'libaddressinput_android_strings_grd',
+ 'type': 'none',
+ 'android_unmangled_name': 1,
+ 'variables': {
+ 'grd_file': '../../chrome/app/address_input_strings_android.grd',
+ },
+ 'includes': [
+ '../../build/java_strings_grd.gypi',
+ ],
+ },
+ {
# GN: //third_party/libaddressinput:android_addressinput_widget_java
'target_name': 'android_addressinput_widget',
'type': 'none',
@@ -179,6 +191,9 @@
'includes': [
'../../build/java.gypi',
],
+ 'dependencies': [
+ 'libaddressinput_android_strings_grd',
+ ],
},
],
},],
diff --git a/third_party/libaddressinput/libaddressinput_strings.target.darwin-arm.mk b/third_party/libaddressinput/libaddressinput_strings.target.darwin-arm.mk
index 3607f11..993ef7e 100644
--- a/third_party/libaddressinput/libaddressinput_strings.target.darwin-arm.mk
+++ b/third_party/libaddressinput/libaddressinput_strings.target.darwin-arm.mk
@@ -20,7 +20,7 @@
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/resources/address_input_strings_am.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ar.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bg.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ca.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_cs.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_da.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_de.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_el.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_en-GB.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es-419.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_et.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fa.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fil.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_gu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_id.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_it.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_iw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ja.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_kn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ko.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lt.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ml.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_mr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ms.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_nl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_no.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-BR.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-PT.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ro.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ru.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ta.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_te.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_th.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_tr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_uk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_vi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-CN.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-TW.xtb $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/address_input_strings_translations.grdp $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from ../../chrome/app/address_input_strings.grd ($@)"
$(hide)cd $(gyp_local_path)/third_party/libaddressinput; mkdir -p $(gyp_shared_intermediate_dir)/third_party/libaddressinput; python ../../tools/grit/grit.py -i ../../chrome/app/address_input_strings.grd build -f ../../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/third_party/libaddressinput/" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" --no-output-all-resource-defines -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc -D enable_notifications
diff --git a/third_party/libaddressinput/libaddressinput_strings.target.darwin-arm64.mk b/third_party/libaddressinput/libaddressinput_strings.target.darwin-arm64.mk
index 3607f11..993ef7e 100644
--- a/third_party/libaddressinput/libaddressinput_strings.target.darwin-arm64.mk
+++ b/third_party/libaddressinput/libaddressinput_strings.target.darwin-arm64.mk
@@ -20,7 +20,7 @@
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/resources/address_input_strings_am.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ar.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bg.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ca.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_cs.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_da.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_de.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_el.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_en-GB.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es-419.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_et.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fa.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fil.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_gu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_id.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_it.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_iw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ja.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_kn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ko.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lt.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ml.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_mr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ms.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_nl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_no.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-BR.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-PT.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ro.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ru.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ta.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_te.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_th.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_tr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_uk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_vi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-CN.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-TW.xtb $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/address_input_strings_translations.grdp $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from ../../chrome/app/address_input_strings.grd ($@)"
$(hide)cd $(gyp_local_path)/third_party/libaddressinput; mkdir -p $(gyp_shared_intermediate_dir)/third_party/libaddressinput; python ../../tools/grit/grit.py -i ../../chrome/app/address_input_strings.grd build -f ../../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/third_party/libaddressinput/" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" --no-output-all-resource-defines -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc -D enable_notifications
diff --git a/third_party/libaddressinput/libaddressinput_strings.target.darwin-mips.mk b/third_party/libaddressinput/libaddressinput_strings.target.darwin-mips.mk
index 3607f11..993ef7e 100644
--- a/third_party/libaddressinput/libaddressinput_strings.target.darwin-mips.mk
+++ b/third_party/libaddressinput/libaddressinput_strings.target.darwin-mips.mk
@@ -20,7 +20,7 @@
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/resources/address_input_strings_am.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ar.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bg.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ca.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_cs.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_da.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_de.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_el.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_en-GB.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es-419.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_et.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fa.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fil.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_gu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_id.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_it.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_iw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ja.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_kn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ko.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lt.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ml.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_mr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ms.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_nl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_no.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-BR.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-PT.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ro.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ru.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ta.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_te.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_th.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_tr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_uk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_vi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-CN.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-TW.xtb $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/address_input_strings_translations.grdp $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from ../../chrome/app/address_input_strings.grd ($@)"
$(hide)cd $(gyp_local_path)/third_party/libaddressinput; mkdir -p $(gyp_shared_intermediate_dir)/third_party/libaddressinput; python ../../tools/grit/grit.py -i ../../chrome/app/address_input_strings.grd build -f ../../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/third_party/libaddressinput/" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" --no-output-all-resource-defines -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc -D enable_notifications
diff --git a/third_party/libaddressinput/libaddressinput_strings.target.darwin-mips64.mk b/third_party/libaddressinput/libaddressinput_strings.target.darwin-mips64.mk
index 3607f11..993ef7e 100644
--- a/third_party/libaddressinput/libaddressinput_strings.target.darwin-mips64.mk
+++ b/third_party/libaddressinput/libaddressinput_strings.target.darwin-mips64.mk
@@ -20,7 +20,7 @@
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/resources/address_input_strings_am.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ar.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bg.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ca.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_cs.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_da.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_de.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_el.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_en-GB.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es-419.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_et.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fa.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fil.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_gu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_id.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_it.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_iw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ja.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_kn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ko.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lt.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ml.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_mr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ms.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_nl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_no.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-BR.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-PT.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ro.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ru.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ta.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_te.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_th.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_tr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_uk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_vi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-CN.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-TW.xtb $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/address_input_strings_translations.grdp $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from ../../chrome/app/address_input_strings.grd ($@)"
$(hide)cd $(gyp_local_path)/third_party/libaddressinput; mkdir -p $(gyp_shared_intermediate_dir)/third_party/libaddressinput; python ../../tools/grit/grit.py -i ../../chrome/app/address_input_strings.grd build -f ../../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/third_party/libaddressinput/" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" --no-output-all-resource-defines -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc -D enable_notifications
diff --git a/third_party/libaddressinput/libaddressinput_strings.target.darwin-x86.mk b/third_party/libaddressinput/libaddressinput_strings.target.darwin-x86.mk
index 3607f11..993ef7e 100644
--- a/third_party/libaddressinput/libaddressinput_strings.target.darwin-x86.mk
+++ b/third_party/libaddressinput/libaddressinput_strings.target.darwin-x86.mk
@@ -20,7 +20,7 @@
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/resources/address_input_strings_am.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ar.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bg.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ca.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_cs.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_da.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_de.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_el.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_en-GB.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es-419.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_et.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fa.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fil.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_gu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_id.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_it.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_iw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ja.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_kn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ko.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lt.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ml.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_mr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ms.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_nl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_no.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-BR.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-PT.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ro.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ru.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ta.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_te.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_th.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_tr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_uk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_vi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-CN.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-TW.xtb $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/address_input_strings_translations.grdp $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from ../../chrome/app/address_input_strings.grd ($@)"
$(hide)cd $(gyp_local_path)/third_party/libaddressinput; mkdir -p $(gyp_shared_intermediate_dir)/third_party/libaddressinput; python ../../tools/grit/grit.py -i ../../chrome/app/address_input_strings.grd build -f ../../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/third_party/libaddressinput/" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" --no-output-all-resource-defines -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc -D enable_notifications
diff --git a/third_party/libaddressinput/libaddressinput_strings.target.darwin-x86_64.mk b/third_party/libaddressinput/libaddressinput_strings.target.darwin-x86_64.mk
index 3607f11..993ef7e 100644
--- a/third_party/libaddressinput/libaddressinput_strings.target.darwin-x86_64.mk
+++ b/third_party/libaddressinput/libaddressinput_strings.target.darwin-x86_64.mk
@@ -20,7 +20,7 @@
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/resources/address_input_strings_am.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ar.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bg.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ca.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_cs.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_da.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_de.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_el.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_en-GB.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es-419.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_et.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fa.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fil.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_gu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_id.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_it.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_iw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ja.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_kn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ko.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lt.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ml.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_mr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ms.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_nl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_no.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-BR.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-PT.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ro.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ru.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ta.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_te.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_th.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_tr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_uk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_vi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-CN.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-TW.xtb $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/address_input_strings_translations.grdp $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from ../../chrome/app/address_input_strings.grd ($@)"
$(hide)cd $(gyp_local_path)/third_party/libaddressinput; mkdir -p $(gyp_shared_intermediate_dir)/third_party/libaddressinput; python ../../tools/grit/grit.py -i ../../chrome/app/address_input_strings.grd build -f ../../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/third_party/libaddressinput/" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" --no-output-all-resource-defines -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc -D enable_notifications
diff --git a/third_party/libaddressinput/libaddressinput_strings.target.linux-arm.mk b/third_party/libaddressinput/libaddressinput_strings.target.linux-arm.mk
index 3607f11..993ef7e 100644
--- a/third_party/libaddressinput/libaddressinput_strings.target.linux-arm.mk
+++ b/third_party/libaddressinput/libaddressinput_strings.target.linux-arm.mk
@@ -20,7 +20,7 @@
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/resources/address_input_strings_am.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ar.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bg.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ca.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_cs.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_da.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_de.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_el.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_en-GB.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es-419.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_et.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fa.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fil.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_gu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_id.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_it.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_iw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ja.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_kn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ko.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lt.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ml.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_mr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ms.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_nl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_no.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-BR.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-PT.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ro.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ru.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ta.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_te.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_th.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_tr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_uk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_vi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-CN.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-TW.xtb $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/address_input_strings_translations.grdp $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from ../../chrome/app/address_input_strings.grd ($@)"
$(hide)cd $(gyp_local_path)/third_party/libaddressinput; mkdir -p $(gyp_shared_intermediate_dir)/third_party/libaddressinput; python ../../tools/grit/grit.py -i ../../chrome/app/address_input_strings.grd build -f ../../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/third_party/libaddressinput/" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" --no-output-all-resource-defines -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc -D enable_notifications
diff --git a/third_party/libaddressinput/libaddressinput_strings.target.linux-arm64.mk b/third_party/libaddressinput/libaddressinput_strings.target.linux-arm64.mk
index 3607f11..993ef7e 100644
--- a/third_party/libaddressinput/libaddressinput_strings.target.linux-arm64.mk
+++ b/third_party/libaddressinput/libaddressinput_strings.target.linux-arm64.mk
@@ -20,7 +20,7 @@
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/resources/address_input_strings_am.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ar.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bg.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ca.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_cs.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_da.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_de.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_el.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_en-GB.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es-419.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_et.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fa.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fil.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_gu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_id.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_it.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_iw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ja.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_kn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ko.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lt.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ml.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_mr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ms.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_nl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_no.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-BR.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-PT.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ro.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ru.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ta.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_te.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_th.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_tr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_uk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_vi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-CN.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-TW.xtb $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/address_input_strings_translations.grdp $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from ../../chrome/app/address_input_strings.grd ($@)"
$(hide)cd $(gyp_local_path)/third_party/libaddressinput; mkdir -p $(gyp_shared_intermediate_dir)/third_party/libaddressinput; python ../../tools/grit/grit.py -i ../../chrome/app/address_input_strings.grd build -f ../../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/third_party/libaddressinput/" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" --no-output-all-resource-defines -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc -D enable_notifications
diff --git a/third_party/libaddressinput/libaddressinput_strings.target.linux-mips.mk b/third_party/libaddressinput/libaddressinput_strings.target.linux-mips.mk
index 3607f11..993ef7e 100644
--- a/third_party/libaddressinput/libaddressinput_strings.target.linux-mips.mk
+++ b/third_party/libaddressinput/libaddressinput_strings.target.linux-mips.mk
@@ -20,7 +20,7 @@
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/resources/address_input_strings_am.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ar.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bg.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ca.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_cs.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_da.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_de.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_el.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_en-GB.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es-419.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_et.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fa.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fil.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_gu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_id.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_it.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_iw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ja.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_kn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ko.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lt.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ml.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_mr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ms.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_nl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_no.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-BR.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-PT.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ro.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ru.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ta.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_te.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_th.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_tr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_uk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_vi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-CN.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-TW.xtb $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/address_input_strings_translations.grdp $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from ../../chrome/app/address_input_strings.grd ($@)"
$(hide)cd $(gyp_local_path)/third_party/libaddressinput; mkdir -p $(gyp_shared_intermediate_dir)/third_party/libaddressinput; python ../../tools/grit/grit.py -i ../../chrome/app/address_input_strings.grd build -f ../../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/third_party/libaddressinput/" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" --no-output-all-resource-defines -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc -D enable_notifications
diff --git a/third_party/libaddressinput/libaddressinput_strings.target.linux-mips64.mk b/third_party/libaddressinput/libaddressinput_strings.target.linux-mips64.mk
index 3607f11..993ef7e 100644
--- a/third_party/libaddressinput/libaddressinput_strings.target.linux-mips64.mk
+++ b/third_party/libaddressinput/libaddressinput_strings.target.linux-mips64.mk
@@ -20,7 +20,7 @@
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/resources/address_input_strings_am.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ar.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bg.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ca.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_cs.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_da.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_de.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_el.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_en-GB.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es-419.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_et.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fa.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fil.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_gu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_id.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_it.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_iw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ja.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_kn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ko.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lt.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ml.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_mr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ms.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_nl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_no.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-BR.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-PT.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ro.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ru.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ta.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_te.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_th.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_tr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_uk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_vi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-CN.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-TW.xtb $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/address_input_strings_translations.grdp $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from ../../chrome/app/address_input_strings.grd ($@)"
$(hide)cd $(gyp_local_path)/third_party/libaddressinput; mkdir -p $(gyp_shared_intermediate_dir)/third_party/libaddressinput; python ../../tools/grit/grit.py -i ../../chrome/app/address_input_strings.grd build -f ../../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/third_party/libaddressinput/" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" --no-output-all-resource-defines -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc -D enable_notifications
diff --git a/third_party/libaddressinput/libaddressinput_strings.target.linux-x86.mk b/third_party/libaddressinput/libaddressinput_strings.target.linux-x86.mk
index 3607f11..993ef7e 100644
--- a/third_party/libaddressinput/libaddressinput_strings.target.linux-x86.mk
+++ b/third_party/libaddressinput/libaddressinput_strings.target.linux-x86.mk
@@ -20,7 +20,7 @@
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/resources/address_input_strings_am.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ar.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bg.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ca.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_cs.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_da.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_de.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_el.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_en-GB.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es-419.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_et.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fa.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fil.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_gu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_id.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_it.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_iw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ja.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_kn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ko.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lt.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ml.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_mr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ms.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_nl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_no.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-BR.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-PT.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ro.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ru.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ta.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_te.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_th.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_tr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_uk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_vi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-CN.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-TW.xtb $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/address_input_strings_translations.grdp $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from ../../chrome/app/address_input_strings.grd ($@)"
$(hide)cd $(gyp_local_path)/third_party/libaddressinput; mkdir -p $(gyp_shared_intermediate_dir)/third_party/libaddressinput; python ../../tools/grit/grit.py -i ../../chrome/app/address_input_strings.grd build -f ../../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/third_party/libaddressinput/" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" --no-output-all-resource-defines -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc -D enable_notifications
diff --git a/third_party/libaddressinput/libaddressinput_strings.target.linux-x86_64.mk b/third_party/libaddressinput/libaddressinput_strings.target.linux-x86_64.mk
index 3607f11..993ef7e 100644
--- a/third_party/libaddressinput/libaddressinput_strings.target.linux-x86_64.mk
+++ b/third_party/libaddressinput/libaddressinput_strings.target.linux-x86_64.mk
@@ -20,7 +20,7 @@
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/resources/address_input_strings_am.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ar.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bg.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_bn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ca.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_cs.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_da.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_de.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_el.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_en-GB.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es-419.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_es.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_et.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fa.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fil.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_fr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_gu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_hu.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_id.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_it.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_iw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ja.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_kn.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ko.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lt.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_lv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ml.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_mr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ms.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_nl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_no.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-BR.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_pt-PT.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ro.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ru.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sl.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sv.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_sw.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_ta.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_te.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_th.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_tr.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_uk.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_vi.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-CN.xtb $(LOCAL_PATH)/chrome/app/resources/address_input_strings_zh-TW.xtb $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/third_party/libaddressinput/messages.h: $(LOCAL_PATH)/chrome/app/address_input_strings.grdp $(LOCAL_PATH)/chrome/app/address_input_strings.grd $(LOCAL_PATH)/chrome/app/address_input_strings_translations.grdp $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating resources from ../../chrome/app/address_input_strings.grd ($@)"
$(hide)cd $(gyp_local_path)/third_party/libaddressinput; mkdir -p $(gyp_shared_intermediate_dir)/third_party/libaddressinput; python ../../tools/grit/grit.py -i ../../chrome/app/address_input_strings.grd build -f ../../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/third_party/libaddressinput/" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" --no-output-all-resource-defines -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc -D enable_notifications
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 915dec4..113c961 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -22597,6 +22597,10 @@
<histogram name="PasswordManager.TimesGeneratedPasswordUsed">
<owner>gcasto@chromium.org</owner>
<owner>vabr@chromium.org</owner>
+ <obsolete>
+ Deprecated as of 11/11/14. New statistic is
+ PasswordManager.TimesPasswordUsed.AutoGenerated.
+ </obsolete>
<summary>
The number of times each generated password has been used to log in.
Recorded by iterating over stored passwords once per run. This information
@@ -43414,6 +43418,8 @@
<int value="278" label="Extension Settings"/>
<int value="279" label="SSL minimum version"/>
<int value="280" label="SSL fallback minimum version"/>
+ <int value="281"
+ label="Control the availability of the Contextual Search feature."/>
</enum>
<enum name="EnterprisePolicyInvalidations" type="int">
@@ -58479,6 +58485,10 @@
<suffix name="NoBackend" label="DiskCache didn't have a backend"/>
<suffix name="DiskCache" label="DiskCache backend is using disk cache."/>
<suffix name="MemoryCache" label="DiskCache backend is using memory cache."/>
+ <suffix name="WaitForDataReady"
+ label="Tracks the last failure reason until WaitForDataReady or its
+ callback is executed. This is recorded when data is ready in
+ WaitForDataReady or when the callback is executed"/>
<affected-histogram name="Net.QuicDiskCache.APICall"/>
<affected-histogram name="Net.QuicDiskCache.FailureReason"/>
</histogram_suffixes>
@@ -58624,8 +58634,20 @@
<suffix name="WithCustomPassphrase"/>
<suffix name="WithoutCustomPassphrase"/>
<affected-histogram name="PasswordManager.AccountsPerSite"/>
+ <affected-histogram name="PasswordManager.AccountsPerSite.AutoGenerated"/>
+ <affected-histogram name="PasswordManager.AccountsPerSite.UserCreated"/>
<affected-histogram name="PasswordManager.BlacklistedSites"/>
<affected-histogram name="PasswordManager.TimesGeneratedPasswordUsed"/>
+ <affected-histogram name="PasswordManager.TimesPasswordUsed.AutoGenerated"/>
+ <affected-histogram name="PasswordManager.TimesPasswordUsed.UserCreated"/>
+ <affected-histogram name="PasswordManager.TotalAccounts.AutoGenerated"/>
+ <affected-histogram name="PasswordManager.TotalAccounts.UserCreated"/>
+</histogram_suffixes>
+
+<histogram_suffixes name="PasswordGenerated" separator=".">
+ <suffix name="UserCreated"/>
+ <suffix name="AutoGenerated"/>
+ <affected-histogram name="PasswordManager.AccountsPerSite"/>
<affected-histogram name="PasswordManager.TimesPasswordUsed"/>
<affected-histogram name="PasswordManager.TotalAccounts"/>
</histogram_suffixes>
diff --git a/ui/accessibility/ax_enums.idl b/ui/accessibility/ax_enums.idl
index ede09ef..1c53875 100644
--- a/ui/accessibility/ax_enums.idl
+++ b/ui/accessibility/ax_enums.idl
@@ -56,6 +56,9 @@
show, // Remove: http://crbug.com/392502
text_changed,
text_selection_changed,
+ tree_changed, // Accessibility tree changed. Don't
+ // explicitly fire an accessibility event,
+ // only implicitly due to the change.
value_changed
};
diff --git a/ui/android/java/res/layout/dropdown_item.xml b/ui/android/java/res/layout/dropdown_item.xml
index 248b4dc..1652fcb 100644
--- a/ui/android/java/res/layout/dropdown_item.xml
+++ b/ui/android/java/res/layout/dropdown_item.xml
@@ -11,11 +11,12 @@
android:layout_height="wrap_content"
android:gravity="center_vertical">
- <LinearLayout
+ <LinearLayout android:id="@+id/dropdown_label_wrapper"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:gravity="center_vertical">
<TextView android:id="@+id/dropdown_label"
android:layout_width="wrap_content"
diff --git a/ui/android/java/src/org/chromium/ui/DropdownAdapter.java b/ui/android/java/src/org/chromium/ui/DropdownAdapter.java
index 051b836..e4a4a18 100644
--- a/ui/android/java/src/org/chromium/ui/DropdownAdapter.java
+++ b/ui/android/java/src/org/chromium/ui/DropdownAdapter.java
@@ -14,6 +14,7 @@
import android.widget.AbsListView.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.TextView;
import org.chromium.base.ApiCompatibilityUtils;
@@ -80,7 +81,14 @@
R.color.dropdown_divider_color));
}
}
- layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, height));
+
+ // Note: trying to set the height of the root LinearLayout breaks accessibility,
+ // so we have to adjust the height of this LinearLayout that wraps the TextViews instead.
+ // If you need to modify this layout, don't forget to test it with TalkBack and make sure
+ // it doesn't regress.
+ // http://crbug.com/429364
+ View wrapper = layout.findViewById(R.id.dropdown_label_wrapper);
+ wrapper.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, height));
DropdownItem item = getItem(position);
TextView labelView = (TextView) layout.findViewById(R.id.dropdown_label);
diff --git a/ui/android/java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java b/ui/android/java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java
index 6448804..5c76f3a 100644
--- a/ui/android/java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java
+++ b/ui/android/java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java
@@ -5,22 +5,31 @@
package org.chromium.ui.widget;
import android.content.Context;
+import android.os.Bundle;
+import android.text.Layout;
import android.text.SpannableString;
import android.text.style.ClickableSpan;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.MotionEvent;
import android.view.View;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.PopupMenu;
import android.widget.TextView;
/**
- * ClickableSpan isn't accessible by default, so we create a simple subclass
- * of TextView that addresses this by adding click and longpress handlers.
- * If there's only one ClickableSpan, we activate it. If there's more than
- * one, we pop up a Spinner to disambiguate.
+ * ClickableSpan isn't accessible by default, so we create a subclass
+ * of TextView that tries to handle the case where a user clicks on a view
+ * and not directly on one of the clickable spans. We do nothing if it's a
+ * touch event directly on a ClickableSpan. Otherwise if there's only one
+ * ClickableSpan, we activate it. If there's more than one, we pop up a
+ * PopupMenu to disambiguate.
*/
public class TextViewWithClickableSpans extends TextView {
+ private AccessibilityManager mAccessibilityManager;
+
public TextViewWithClickableSpans(Context context) {
super(context);
init();
@@ -37,21 +46,74 @@
}
private void init() {
- setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- handleClick();
- }
- });
+ mAccessibilityManager = (AccessibilityManager)
+ getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
+ if (!mAccessibilityManager.isTouchExplorationEnabled()) {
+ return false;
+ }
openDisambiguationMenu();
return true;
}
});
}
+ @Override
+ public boolean performAccessibilityAction(int action, Bundle arguments) {
+ // BrailleBack will generate an accessibility click event directly
+ // on this view, make sure we handle that correctly.
+ if (action == AccessibilityNodeInfo.ACTION_CLICK) {
+ handleAccessibilityClick();
+ return true;
+ }
+ return super.performAccessibilityAction(action, arguments);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ boolean superResult = super.onTouchEvent(event);
+
+ if (event.getAction() != MotionEvent.ACTION_UP
+ && mAccessibilityManager.isTouchExplorationEnabled()
+ && !touchIntersectsAnyClickableSpans(event)) {
+ handleAccessibilityClick();
+ return true;
+ }
+
+ return superResult;
+ }
+
+ private boolean touchIntersectsAnyClickableSpans(MotionEvent event) {
+ // This logic is borrowed from android.text.method.LinkMovementMethod.
+ //
+ // ClickableSpan doesn't stop propagation of the event in its click handler,
+ // so we should only try to simplify clicking on a clickable span if the touch event
+ // isn't already over a clickable span.
+
+ CharSequence text = getText();
+ if (!(text instanceof SpannableString)) return false;
+ SpannableString spannable = (SpannableString) text;
+
+ int x = (int) event.getX();
+ int y = (int) event.getY();
+
+ x -= getTotalPaddingLeft();
+ y -= getTotalPaddingTop();
+
+ x += getScrollX();
+ y += getScrollY();
+
+ Layout layout = getLayout();
+ int line = layout.getLineForVertical(y);
+ int off = layout.getOffsetForHorizontal(line, x);
+
+ ClickableSpan[] clickableSpans =
+ spannable.getSpans(off, off, ClickableSpan.class);
+ return clickableSpans.length > 0;
+ }
+
private ClickableSpan[] getClickableSpans() {
CharSequence text = getText();
if (!(text instanceof SpannableString)) return null;
@@ -60,7 +122,7 @@
return spannable.getSpans(0, spannable.length(), ClickableSpan.class);
}
- private void handleClick() {
+ private void handleAccessibilityClick() {
ClickableSpan[] clickableSpans = getClickableSpans();
if (clickableSpans == null || clickableSpans.length == 0) {
return;
diff --git a/ui/file_manager/file_manager/background/js/volume_manager.js b/ui/file_manager/file_manager/background/js/volume_manager.js
index e5c645b..13d91b3 100644
--- a/ui/file_manager/file_manager/background/js/volume_manager.js
+++ b/ui/file_manager/file_manager/background/js/volume_manager.js
@@ -464,7 +464,8 @@
*/
this.driveConnectionState_ = {
type: VolumeManagerCommon.DriveConnectionType.OFFLINE,
- reason: VolumeManagerCommon.DriveConnectionReason.NO_SERVICE
+ reason: VolumeManagerCommon.DriveConnectionReason.NO_SERVICE,
+ hasCellularNetworkAccess: false
};
chrome.fileManagerPrivate.onDriveConnectionStatusChanged.addListener(
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js
index e2ed10e..3f3597f 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -1941,7 +1941,7 @@
* @return {boolean} True if those setting items should be shown.
*/
FileManager.prototype.shouldShowDriveSettings = function() {
- return this.isOnDrive() && this.isSecretGearMenuShown_;
+ return this.isOnDrive();
};
/**
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
index 0b96747..58d4e1e 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -508,7 +508,9 @@
* @param {!FileManager} fileManager FileManager to use.
*/
canExecute: function(event, fileManager) {
- event.canExecute = fileManager.shouldShowDriveSettings();
+ event.canExecute = fileManager.shouldShowDriveSettings() &&
+ fileManager.volumeManager.getDriveConnectionState().
+ hasCellularNetworkAccess;
event.command.setHidden(!event.canExecute);
}
});
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
index 1ca874a..87e650b 100644
--- a/ui/gfx/render_text.cc
+++ b/ui/gfx/render_text.cc
@@ -398,9 +398,14 @@
}
RenderText* RenderText::CreateInstance() {
- return CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableHarfBuzzRenderText) ? CreateNativeInstance() :
- new RenderTextHarfBuzz;
+#if defined(OS_MACOSX) && !defined(TOOLKIT_VIEWS)
+ static const bool use_harfbuzz = CommandLine::ForCurrentProcess()->
+ HasSwitch(switches::kEnableHarfBuzzRenderText);
+#else
+ static const bool use_harfbuzz = !CommandLine::ForCurrentProcess()->
+ HasSwitch(switches::kDisableHarfBuzzRenderText);
+#endif
+ return use_harfbuzz ? new RenderTextHarfBuzz : CreateNativeInstance();
}
void RenderText::SetText(const base::string16& text) {
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc
index 876c8a8..859689b 100644
--- a/ui/gfx/render_text_unittest.cc
+++ b/ui/gfx/render_text_unittest.cc
@@ -2332,7 +2332,7 @@
#if !defined(OS_WIN)
// Ensure that RenderText examines all of the fonts in its FontList before
// falling back to other fonts.
-TEST_F(RenderTextTest, FontListFallback) {
+TEST_F(RenderTextTest, HarfBuzz_FontListFallback) {
// Double-check that the requested fonts are present.
FontList font_list("Arial, Symbol, 12px");
const std::vector<Font>& fonts = font_list.GetFonts();
@@ -2344,11 +2344,11 @@
// "⊕" (CIRCLED PLUS) should be rendered with Symbol rather than falling back
// to some other font that's present on the system.
- scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
- render_text->SetFontList(font_list);
- render_text->SetText(UTF8ToUTF16("\xE2\x8A\x95"));
+ RenderTextHarfBuzz render_text;
+ render_text.SetFontList(font_list);
+ render_text.SetText(UTF8ToUTF16("\xE2\x8A\x95"));
const std::vector<RenderText::FontSpan> spans =
- render_text->GetFontSpansForTesting();
+ render_text.GetFontSpansForTesting();
ASSERT_EQ(static_cast<size_t>(1), spans.size());
EXPECT_EQ("Symbol", spans[0].first.GetFontName());
}
diff --git a/ui/gl/gl_context.cc b/ui/gl/gl_context.cc
index 533b7d3..e358069 100644
--- a/ui/gl/gl_context.cc
+++ b/ui/gl/gl_context.cc
@@ -82,6 +82,10 @@
void GLContext::SetSafeToForceGpuSwitch() {
}
+bool GLContext::ForceGpuSwitchIfNeeded() {
+ return true;
+}
+
void GLContext::SetUnbindFboOnMakeCurrent() {
NOTIMPLEMENTED();
}
@@ -199,6 +203,8 @@
bool GLContext::MakeVirtuallyCurrent(
GLContext* virtual_context, GLSurface* surface) {
DCHECK(virtual_gl_api_);
+ if (!ForceGpuSwitchIfNeeded())
+ return false;
return virtual_gl_api_->MakeCurrent(virtual_context, surface);
}
diff --git a/ui/gl/gl_context.h b/ui/gl/gl_context.h
index 372f513..cdebd68 100644
--- a/ui/gl/gl_context.h
+++ b/ui/gl/gl_context.h
@@ -90,6 +90,10 @@
// transitioning can cause corruption and hangs (OS X only).
virtual void SetSafeToForceGpuSwitch();
+ // Attempt to force the context to move to the GPU of its sharegroup. Return
+ // false only in the event of an unexpected error on the context.
+ virtual bool ForceGpuSwitchIfNeeded();
+
// Indicate that the real context switches should unbind the FBO first
// (For an Android work-around only).
virtual void SetUnbindFboOnMakeCurrent();
diff --git a/ui/gl/gl_context_cgl.cc b/ui/gl/gl_context_cgl.cc
index 10f854a..277780a 100644
--- a/ui/gl/gl_context_cgl.cc
+++ b/ui/gl/gl_context_cgl.cc
@@ -136,7 +136,7 @@
}
}
-bool GLContextCGL::MakeCurrent(GLSurface* surface) {
+bool GLContextCGL::ForceGpuSwitchIfNeeded() {
DCHECK(context_);
// The call to CGLSetVirtualScreen can hang on some AMD drivers
@@ -174,6 +174,14 @@
renderer_id_ = renderer_id;
}
}
+ return true;
+}
+
+bool GLContextCGL::MakeCurrent(GLSurface* surface) {
+ DCHECK(context_);
+
+ if (!ForceGpuSwitchIfNeeded())
+ return false;
if (IsCurrent(surface))
return true;
diff --git a/ui/gl/gl_context_cgl.h b/ui/gl/gl_context_cgl.h
index beeb9f9..456ea08 100644
--- a/ui/gl/gl_context_cgl.h
+++ b/ui/gl/gl_context_cgl.h
@@ -29,6 +29,7 @@
void SetSwapInterval(int interval) override;
bool GetTotalGpuMemory(size_t* bytes) override;
void SetSafeToForceGpuSwitch() override;
+ bool ForceGpuSwitchIfNeeded() override;
protected:
~GLContextCGL() override;
diff --git a/ui/message_center/BUILD.gn b/ui/message_center/BUILD.gn
index 19f7ccd..31e9a89 100644
--- a/ui/message_center/BUILD.gn
+++ b/ui/message_center/BUILD.gn
@@ -24,7 +24,7 @@
defines = [ "MESSAGE_CENTER_IMPLEMENTATION" ]
- if (enable_notifications) {
+ if (enable_notifications && !is_android) {
sources = [
"cocoa/notification_controller.h",
"cocoa/notification_controller.mm",
@@ -197,7 +197,7 @@
"//url",
]
- if (enable_notifications) {
+ if (enable_notifications && !is_android) {
sources += [
"cocoa/notification_controller_unittest.mm",
"cocoa/popup_collection_unittest.mm",
@@ -232,5 +232,5 @@
"//ui/views:test_support",
]
}
- } # enable_notifications
+ } # enable_notifications && !is_android
}