diff --git a/DEPS b/DEPS index 9e3e3199..aa93e94 100644 --- a/DEPS +++ b/DEPS
@@ -40,7 +40,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '8da9e940721168143d6296f578b6d7423de55d69', + 'skia_revision': 'e393a629491e9a52dd6662983d2bfd424541957e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '5c1961dfa0b1828eb2db38dc637548584c5cc704', + 'pdfium_revision': 'e472622d33bdca2316a22ff5ff8d77ac975c2eb2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'aa4354795733e91c5caf2a25b111240bf3637b5f', + 'catapult_revision': '5cdfbfc974591fbaca53645b670c8191cb89f8aa', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -404,7 +404,7 @@ # For Linux and Chromium OS. 'src/third_party/cros_system_api': - Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + '7c84418f4f0479eabc607d8c4cb678269aee01c4', + Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + 'ce814837221c4a4d385fd92094b7673bf4601c9f', 'src/third_party/freetype/src': Var('chromium_git') + '/chromium/src/third_party/freetype2.git' + '@' + Var('freetype_revision'),
diff --git a/android_webview/tools/automated_ui_tests/javatests/src/org/chromium/webview_ui_test/test/ActionModeTest.java b/android_webview/tools/automated_ui_tests/javatests/src/org/chromium/webview_ui_test/test/ActionModeTest.java index ffbcca9..eb9dc56 100644 --- a/android_webview/tools/automated_ui_tests/javatests/src/org/chromium/webview_ui_test/test/ActionModeTest.java +++ b/android_webview/tools/automated_ui_tests/javatests/src/org/chromium/webview_ui_test/test/ActionModeTest.java
@@ -94,7 +94,7 @@ private static final String MORE_OPTIONS_ACTION = "More options"; private static final String PASTE_ACTION = "Paste"; private static final String SHARE_ACTION = "Share"; - private static final String SELECT_ALL_ACTION = "Select All"; + private static final String SELECT_ALL_ACTION = "Select all"; private static final String WEB_SEARCH_ACTION = "Web search"; private static final String QUICK_SEARCH_BOX_PKG = "com.google.android.googlequicksearchbox"; @@ -147,7 +147,7 @@ @UseLayout("edittext_webview") public void testSelectAll() { longClickOnLastWord(R.id.webview); - clickPopupAction("Select all"); + clickPopupAction(SELECT_ALL_ACTION); clickPopupAction(COPY_ACTION); longClickOnLastWord(R.id.edittext); clickPopupAction(PASTE_ACTION); @@ -246,6 +246,14 @@ .perform(click()); onData(new MenuItemMatcher(equalTo(name))).inRoot(rootMatcher).perform(click()); } + + /** + * After select all action is clicked, the PopUp Menu may disappear + * briefly due to selection change, wait for the menu to reappear + */ + if (name.equals(SELECT_ALL_ACTION)) { + mActionBarIdlingResource.start(); + } } /** @@ -286,11 +294,6 @@ private boolean mActionStarting; private ResourceCallback mResourceCallback; - ActionBarIdlingResource() { - mActionStarting = false; - mResourceCallback = null; - } - @Override public String getName() { return "ActionBarIdlingResource";
diff --git a/ash/common/shelf/shelf_constants.cc b/ash/common/shelf/shelf_constants.cc index c260855..25a8fe3 100644 --- a/ash/common/shelf/shelf_constants.cc +++ b/ash/common/shelf/shelf_constants.cc
@@ -23,7 +23,7 @@ const SkColor kShelfIconColor = SK_ColorWHITE; const int kShelfTranslucentAlpha = 153; const int kShelfTranslucentColorDarkenAlpha = 102; -const int kShelfOpaqueColorDarkenAlpha = 230; +const int kShelfOpaqueColorDarkenAlpha = 178; const int kOverflowButtonSize = 32; const int kOverflowButtonCornerRadius = 2; const int kAppListButtonRadius = kOverflowButtonSize / 2;
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py index c5db1b24..d2b8197 100755 --- a/build/vs_toolchain.py +++ b/build/vs_toolchain.py
@@ -238,8 +238,8 @@ """Copy the VS runtime DLLs, only if the target doesn't exist, but the target directory does exist. Handles VS 2013, VS 2015, and VS 2017.""" suffix = "d.dll" if debug else ".dll" - if GetVisualStudioVersion() == '2015' or GetVisualStudioVersion() == '2017': - # VS 2017 RC uses the same CRT DLLs as VS 2015. + if GetVisualStudioVersion() in ['2015', '2017']: + # VS 2017 uses the same CRT DLLs as VS 2015. _CopyUCRTRuntime(target_dir, source_dir, '%s140' + suffix, suffix) else: _CopyRuntime2013(target_dir, source_dir, 'msvc%s120' + suffix) @@ -343,8 +343,10 @@ if GetVisualStudioVersion() == '2015': # Update 3 final with patches with 10.0.14393.0 SDK. return ['d3cb0e37bdd120ad0ac4650b674b09e81be45616'] - else: + elif GetVisualStudioVersion() == '2013': return ['03a4e939cd325d6bc5216af41b92d02dda1366a6'] + else: + raise Exception('Unsupported VS version %s' % GetVisualStudioVersion()) def ShouldUpdateToolchain():
diff --git a/cc/resources/resource_pool.cc b/cc/resources/resource_pool.cc index c200375..50eef3c4 100644 --- a/cc/resources/resource_pool.cc +++ b/cc/resources/resource_pool.cc
@@ -24,8 +24,35 @@ using base::trace_event::MemoryDumpLevelOfDetail; namespace cc { +namespace { +bool ResourceMeetsSizeRequirements(const gfx::Size& requested_size, + const gfx::Size& actual_size) { + const float kReuseThreshold = 2.0f; + + // Allocating new resources is expensive, and we'd like to re-use our + // existing ones within reason. Allow a larger resource to be used for a + // smaller request. + if (actual_size.width() < requested_size.width() || + actual_size.height() < requested_size.height()) + return false; + + // GetArea will crash on overflow, however all sizes in use are tile sizes. + // These are capped at ResourceProvider::max_texture_size(), and will not + // overflow. + float actual_area = actual_size.GetArea(); + float requested_area = requested_size.GetArea(); + // Don't use a resource that is more than |kReuseThreshold| times the + // requested pixel area, as we want to free unnecessarily large resources. + if (actual_area / requested_area > kReuseThreshold) + return false; + + return true; +} + +} // namespace + base::TimeDelta ResourcePool::kDefaultExpirationDelay = - base::TimeDelta::FromSeconds(1); + base::TimeDelta::FromSeconds(5); void ResourcePool::PoolResource::OnMemoryDump( base::trace_event::ProcessMemoryDump* pmd, @@ -119,7 +146,7 @@ if (resource->format() != format) continue; - if (resource->size() != size) + if (!ResourceMeetsSizeRequirements(size, resource->size())) continue; if (resource->color_space() != color_space) continue;
diff --git a/cc/resources/resource_pool_unittest.cc b/cc/resources/resource_pool_unittest.cc index aa8e853e..ec9bae41 100644 --- a/cc/resources/resource_pool_unittest.cc +++ b/cc/resources/resource_pool_unittest.cc
@@ -33,6 +33,12 @@ } protected: + void CheckAndReturnResource(Resource* resource) { + EXPECT_NE(nullptr, resource); + resource_pool_->ReleaseResource(resource); + resource_pool_->CheckBusyResources(); + } + scoped_refptr<TestContextProvider> context_provider_; std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_; std::unique_ptr<ResourceProvider> resource_provider_; @@ -105,32 +111,28 @@ gfx::ColorSpace color_space1; gfx::ColorSpace color_space2 = gfx::ColorSpace::CreateSRGB(); - Resource* resource = - resource_pool_->AcquireResource(size, format, color_space1); - resource_pool_->ReleaseResource(resource); - resource_pool_->CheckBusyResources(); + CheckAndReturnResource( + resource_pool_->AcquireResource(size, format, color_space1)); EXPECT_EQ(1u, resource_provider_->num_resources()); // Same size/format should re-use resource. - resource = resource_pool_->AcquireResource(size, format, color_space1); + Resource* resource = + resource_pool_->AcquireResource(size, format, color_space1); EXPECT_EQ(1u, resource_provider_->num_resources()); - resource_pool_->ReleaseResource(resource); - resource_pool_->CheckBusyResources(); + CheckAndReturnResource(resource); EXPECT_EQ(1u, resource_provider_->num_resources()); // Different size/format should allocate new resource. resource = resource_pool_->AcquireResource(gfx::Size(50, 50), LUMINANCE_8, color_space1); EXPECT_EQ(2u, resource_provider_->num_resources()); - resource_pool_->ReleaseResource(resource); - resource_pool_->CheckBusyResources(); + CheckAndReturnResource(resource); EXPECT_EQ(2u, resource_provider_->num_resources()); // Different color space should allocate new resource. resource = resource_pool_->AcquireResource(size, format, color_space2); EXPECT_EQ(3u, resource_provider_->num_resources()); - resource_pool_->ReleaseResource(resource); - resource_pool_->CheckBusyResources(); + CheckAndReturnResource(resource); EXPECT_EQ(3u, resource_provider_->num_resources()); } @@ -317,25 +319,47 @@ ResourceFormat format = RGBA_8888; gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB(); - // Create unused resources with sizes close to 100, 100. - resource_pool_->ReleaseResource( - resource_pool_->CreateResource(gfx::Size(99, 100), format, color_space)); - resource_pool_->ReleaseResource( - resource_pool_->CreateResource(gfx::Size(99, 99), format, color_space)); - resource_pool_->ReleaseResource( - resource_pool_->CreateResource(gfx::Size(100, 99), format, color_space)); - resource_pool_->ReleaseResource( - resource_pool_->CreateResource(gfx::Size(101, 101), format, color_space)); - resource_pool_->CheckBusyResources(); + // Create unused resource with size 100x100. + CheckAndReturnResource( + resource_pool_->CreateResource(gfx::Size(100, 100), format, color_space)); - gfx::Size size(100, 100); - Resource* resource = resource_pool_->ReuseResource(size, format, color_space); - EXPECT_EQ(nullptr, resource); - size = gfx::Size(100, 99); - resource = resource_pool_->ReuseResource(size, format, color_space); - EXPECT_NE(nullptr, resource); - ASSERT_EQ(nullptr, resource_pool_->ReuseResource(size, format, color_space)); - resource_pool_->ReleaseResource(resource); + // Try some cases that are too large, none should succeed. + EXPECT_EQ(nullptr, resource_pool_->ReuseResource(gfx::Size(101, 100), format, + color_space)); + EXPECT_EQ(nullptr, resource_pool_->ReuseResource(gfx::Size(100, 101), format, + color_space)); + EXPECT_EQ(nullptr, resource_pool_->ReuseResource(gfx::Size(90, 120), format, + color_space)); + EXPECT_EQ(nullptr, resource_pool_->ReuseResource(gfx::Size(120, 120), format, + color_space)); + + // Try some cases that are more than 2x smaller than 100x100 in area and + // won't be re-used. + EXPECT_EQ(nullptr, resource_pool_->ReuseResource(gfx::Size(49, 100), format, + color_space)); + EXPECT_EQ(nullptr, resource_pool_->ReuseResource(gfx::Size(100, 49), format, + color_space)); + EXPECT_EQ(nullptr, resource_pool_->ReuseResource(gfx::Size(50, 50), format, + color_space)); + EXPECT_EQ(nullptr, resource_pool_->ReuseResource(gfx::Size(70, 70), format, + color_space)); + + // Try some cases that are smaller than 100x100, but within 2x area. Reuse + // should succeed. + CheckAndReturnResource( + resource_pool_->ReuseResource(gfx::Size(50, 100), format, color_space)); + CheckAndReturnResource( + resource_pool_->ReuseResource(gfx::Size(100, 50), format, color_space)); + CheckAndReturnResource( + resource_pool_->ReuseResource(gfx::Size(71, 71), format, color_space)); + + // 100x100 is an exact match and should succeed. A subsequent request for + // the same size should fail (the resource is already in use). + Resource* resource = + resource_pool_->ReuseResource(gfx::Size(100, 100), format, color_space); + EXPECT_EQ(nullptr, resource_pool_->ReuseResource(gfx::Size(100, 100), format, + color_space)); + CheckAndReturnResource(resource); } TEST_F(ResourcePoolTest, MemoryStateSuspended) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 88ddbec..52c4b8ee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -761,7 +761,7 @@ return false; } - getTabCreator(false).launchUrl(UrlConstants.NTP_URL, TabLaunchType.FROM_CHROME_UI); + getTabCreator(false).launchUrl(UrlConstants.NTP_URL, TabLaunchType.FROM_EXTERNAL_APP); return true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastReceiver.java index 913965b..becd503 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastReceiver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastReceiver.java
@@ -62,8 +62,12 @@ intent, DownloadNotificationService.EXTRA_DOWNLOAD_FILE_PATH); boolean isSupportedMimeType = IntentUtils.safeGetBooleanExtra( intent, DownloadNotificationService.EXTRA_IS_SUPPORTED_MIME_TYPE, false); + boolean isOffTheRecord = IntentUtils.safeGetBooleanExtra( + intent, DownloadNotificationService.EXTRA_IS_OFF_THE_RECORD, false); + String downloadGuid = IntentUtils.safeGetStringExtra( + intent, DownloadNotificationService.EXTRA_DOWNLOAD_GUID); DownloadManagerService.openDownloadedContent( - context, downloadFilename, isSupportedMimeType, id); + context, downloadFilename, isSupportedMimeType, isOffTheRecord, downloadGuid, id); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java index 855c911..c1c51ac 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
@@ -1065,13 +1065,11 @@ ? false : ExternalNavigationDelegateImpl.resolveIntent(intent, true); } - /** See {@link #openDownloadedContent(Context, String, boolean, long)}. */ + /** See {@link #openDownloadedContent(Context, String, boolean, boolean, String, long)}. */ protected void openDownloadedContent(final DownloadInfo downloadInfo, final long downloadId) { - // TODO(shaktisahu): Move this to the broader openDownloadedContent() or a better place if - // possible. - updateLastAccessTime(downloadInfo.getDownloadGuid(), downloadInfo.isOffTheRecord()); openDownloadedContent(mContext, downloadInfo.getFilePath(), - isSupportedMimeType(downloadInfo.getMimeType()), downloadId); + isSupportedMimeType(downloadInfo.getMimeType()), downloadInfo.isOffTheRecord(), + downloadInfo.getDownloadGuid(), downloadId); } /** @@ -1081,10 +1079,13 @@ * @param context Context to use. * @param filePath Path to the downloaded item. * @param isSupportedMimeType MIME type of the downloaded item. + * @param isOffTheRecord Whether the download was for a off the record profile. + * @param downloadGuid GUID of the download item in DownloadManager. * @param downloadId ID of the download item in DownloadManager. */ protected static void openDownloadedContent(final Context context, final String filePath, - final boolean isSupportedMimeType, final long downloadId) { + final boolean isSupportedMimeType, final boolean isOffTheRecord, + final String downloadGuid, final long downloadId) { new AsyncTask<Void, Void, Intent>() { @Override public Intent doInBackground(Void... params) { @@ -1098,6 +1099,10 @@ || !ExternalNavigationDelegateImpl.resolveIntent(intent, true) || !DownloadUtils.fireOpenIntentForDownload(context, intent)) { openDownloadsPage(context); + } else { + DownloadManagerService service = + DownloadManagerService.getDownloadManagerService(context); + service.updateLastAccessTime(downloadGuid, isOffTheRecord); } } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); @@ -1786,6 +1791,8 @@ */ @Override public void updateLastAccessTime(String downloadGuid, boolean isOffTheRecord) { + if (TextUtils.isEmpty(downloadGuid)) return; + nativeUpdateLastAccessTime(getNativeDownloadManagerService(), downloadGuid, isOffTheRecord); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java index c30c373..bc4f784 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java
@@ -876,9 +876,9 @@ * user click on the snackbar. */ @VisibleForTesting - public int notifyDownloadSuccessful( - String downloadGuid, String filePath, String fileName, long systemDownloadId, - boolean isOfflinePage, boolean isSupportedMimeType) { + public int notifyDownloadSuccessful(String downloadGuid, String filePath, String fileName, + long systemDownloadId, boolean isOffTheRecord, boolean isOfflinePage, + boolean isSupportedMimeType) { int notificationId = getNotificationId(downloadGuid); ChromeNotificationBuilder builder = buildNotification(R.drawable.offline_pin, fileName, mContext.getResources().getString(R.string.download_notification_completed)); @@ -893,6 +893,8 @@ intent.putExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS, idArray); intent.putExtra(EXTRA_DOWNLOAD_FILE_PATH, filePath); intent.putExtra(EXTRA_IS_SUPPORTED_MIME_TYPE, isSupportedMimeType); + intent.putExtra(EXTRA_IS_OFF_THE_RECORD, isOffTheRecord); + intent.putExtra(EXTRA_DOWNLOAD_GUID, downloadGuid); } intent.setComponent(component); builder.setContentIntent(PendingIntent.getBroadcast(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java index 67d2f88..f958dc8e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
@@ -469,12 +469,13 @@ * Opens a file in Chrome or in another app if appropriate. * @param file path to the file to open. * @param mimeType mime type of the file. + * @param downloadGuid The associated download GUID. * @param isOffTheRecord whether we are in an off the record context. * @return whether the file could successfully be opened. */ - public static boolean openFile(File file, String mimeType, boolean isOffTheRecord) { + public static boolean openFile( + File file, String mimeType, String downloadGuid, boolean isOffTheRecord) { Context context = ContextUtils.getApplicationContext(); - Intent viewIntent = createViewIntentForDownloadItem(getUriForItem(file), mimeType); DownloadManagerService service = DownloadManagerService.getDownloadManagerService(context); // Check if Chrome should open the file itself. @@ -488,12 +489,15 @@ Intent intent = getMediaViewerIntentForDownloadItem(fileUri, contentUri, normalizedMimeType); IntentHandler.startActivityForTrustedIntent(intent); + service.updateLastAccessTime(downloadGuid, isOffTheRecord); return true; } // Check if any apps can open the file. try { + Intent viewIntent = createViewIntentForDownloadItem(getUriForItem(file), mimeType); context.startActivity(viewIntent); + service.updateLastAccessTime(downloadGuid, isOffTheRecord); return true; } catch (ActivityNotFoundException e) { // Can't launch the Intent.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java b/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java index 85a6c77..8c5aee9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java
@@ -281,8 +281,8 @@ case DOWNLOAD_NOTIFICATION_TYPE_SUCCESS: final int notificationId = mBoundService.notifyDownloadSuccessful( info.getDownloadGuid(), info.getFilePath(), info.getFileName(), - notificationInfo.systemDownloadId, info.isOfflinePage(), - notificationInfo.isSupportedMimeType); + notificationInfo.systemDownloadId, info.isOffTheRecord(), + info.isOfflinePage(), notificationInfo.isSupportedMimeType); onSuccessNotificationShown(notificationInfo, notificationId); break; case DOWNLOAD_NOTIFICATION_TYPE_FAILURE:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java index e36debb..c368bbc5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java
@@ -329,9 +329,8 @@ return; } - if (DownloadUtils.openFile(getFile(), getMimeType(), isOffTheRecord())) { - mBackendProvider.getDownloadDelegate().updateLastAccessTime( - mItem.getId(), isOffTheRecord()); + if (DownloadUtils.openFile(getFile(), getMimeType(), + mItem.getDownloadInfo().getDownloadGuid(), isOffTheRecord())) { recordOpenSuccess(); } else { recordOpenFailure();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/OWNERS index 92e42be0..a5ae8db 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/OWNERS
@@ -1,2 +1,4 @@ +set noparent + dfalcantara@chromium.org twellington@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/DuplicateDownloadInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/DuplicateDownloadInfoBar.java index 01b5b76..1e62c4f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/DuplicateDownloadInfoBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/DuplicateDownloadInfoBar.java
@@ -74,7 +74,7 @@ return getMessageText(template, filename, new ClickableSpan() { @Override public void onClick(View view) { - DownloadUtils.openFile(file, mimeType, mIsIncognito); + DownloadUtils.openFile(file, mimeType, null, mIsIncognito); } }); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticle.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticle.java index 96409080..9f3bead 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticle.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticle.java
@@ -59,6 +59,9 @@ /** Whether the linked article represents an asset download. */ private boolean mIsAssetDownload; + /** The GUID of the asset download (only for asset download articles). */ + private String mAssetDownloadGuid; + /** The path to the asset download (only for asset download articles). */ private File mAssetDownloadFile; @@ -132,6 +135,16 @@ } /** + * @return the GUID of the asset download. May only be called if {@link #mIsAssetDownload} is + * {@code true} (which implies that this snippet belongs to the DOWNLOADS category). + */ + public String getAssetDownloadGuid() { + assert isDownload(); + assert mIsAssetDownload; + return mAssetDownloadGuid; + } + + /** * @return the asset download path. May only be called if {@link #mIsAssetDownload} is * {@code true} (which implies that this snippet belongs to the DOWNLOADS category). */ @@ -155,9 +168,10 @@ * Marks the article suggestion as an asset download with the given path and mime type. May only * be called if this snippet belongs to DOWNLOADS category. */ - public void setAssetDownloadData(String filePath, String mimeType) { + public void setAssetDownloadData(String downloadGuid, String filePath, String mimeType) { assert isDownload(); mIsAssetDownload = true; + mAssetDownloadGuid = downloadGuid; mAssetDownloadFile = new File(filePath); mAssetDownloadMimeType = mimeType; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java index 767af465..15d272e5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java
@@ -271,8 +271,8 @@ @CalledByNative private static void setAssetDownloadDataForSuggestion( - SnippetArticle suggestion, String filePath, String mimeType) { - suggestion.setAssetDownloadData(filePath, mimeType); + SnippetArticle suggestion, String downloadGuid, String filePath, String mimeType) { + suggestion.setAssetDownloadData(downloadGuid, filePath, mimeType); } @CalledByNative
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PhysicalWeb.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PhysicalWeb.java index 20e2d429..0b0f6c2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PhysicalWeb.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PhysicalWeb.java
@@ -4,6 +4,10 @@ package org.chromium.chrome.browser.physicalweb; +import android.annotation.TargetApi; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothManager; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; @@ -153,4 +157,28 @@ new Intent(Intent.ACTION_VIEW, Uri.parse(UrlConstants.PHYSICAL_WEB_URL)) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } + + /** + * Check if bluetooth is on and enabled. + */ + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public static boolean bluetoothIsEnabled() { + Context context = ContextUtils.getApplicationContext(); + BluetoothManager bluetoothManager = + (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); + BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter(); + return bluetoothAdapter != null && bluetoothAdapter.isEnabled(); + } + + /** + * Check if the device bluetooth hardware supports BLE advertisements. + */ + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public static boolean hasBleAdvertiseCapability() { + Context context = ContextUtils.getApplicationContext(); + BluetoothManager bluetoothManager = + (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); + BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter(); + return bluetoothAdapter != null && bluetoothAdapter.getBluetoothLeAdvertiser() != null; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PhysicalWebShareActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PhysicalWebShareActivity.java index 3b6dbcb..09891aa8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PhysicalWebShareActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PhysicalWebShareActivity.java
@@ -26,11 +26,15 @@ /** * Returns whether we should show this sharing option in the share sheet. * Pre-conditions for Physical Web Sharing to be enabled: + * Device has hardware BLE advertising capabilities. + * Device had Bluetooth on. * Device is Marshmallow or above. * Device has sharing feature enabled. * @return {@code true} if the feature should be enabled. */ public static boolean featureIsAvailable() { - return PhysicalWeb.sharingIsEnabled() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false; + return PhysicalWeb.hasBleAdvertiseCapability() && PhysicalWeb.bluetoothIsEnabled() + && PhysicalWeb.sharingIsEnabled(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegateImpl.java index bc6bc00..6fc318b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegateImpl.java
@@ -97,8 +97,8 @@ assert windowOpenDisposition == WindowOpenDisposition.CURRENT_TAB || windowOpenDisposition == WindowOpenDisposition.NEW_WINDOW || windowOpenDisposition == WindowOpenDisposition.NEW_BACKGROUND_TAB; - DownloadUtils.openFile( - article.getAssetDownloadFile(), article.getAssetDownloadMimeType(), false); + DownloadUtils.openFile(article.getAssetDownloadFile(), + article.getAssetDownloadMimeType(), article.getAssetDownloadGuid(), false); return; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarTablet.java index d40f46b2..1a2c0137 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarTablet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarTablet.java
@@ -333,8 +333,11 @@ super.onTabOrModelChanged(); boolean incognito = isIncognito(); if (mUseLightColorAssets == null || mUseLightColorAssets != incognito) { - setBackgroundResource(incognito - ? R.color.incognito_primary_color : R.color.default_primary_color); + int colorResource = + incognito ? R.color.incognito_primary_color : R.color.default_primary_color; + setBackgroundResource(colorResource); + getProgressBar().setThemeColor( + ApiCompatibilityUtils.getColor(getResources(), colorResource), isIncognito()); mMenuButton.setTint(incognito ? mLightModeTint : mDarkModeTint); mHomeButton.setTint(incognito ? mLightModeTint : mDarkModeTint);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java index a41d5a46..7775861 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java
@@ -289,7 +289,8 @@ sharedPrefs, DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS); assertEquals(3, entries.size()); - service.notifyDownloadSuccessful(guid1, "/path/to/success", "success", 100L, false, false); + service.notifyDownloadSuccessful( + guid1, "/path/to/success", "success", 100L, false, false, false); entries = DownloadManagerService.getStoredDownloadInfo( sharedPrefs, DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS); assertEquals(2, entries.size()); @@ -315,7 +316,7 @@ startNotificationService(); DownloadNotificationService service = bindNotificationService(); String guid = UUID.randomUUID().toString(); - service.notifyDownloadSuccessful(guid, "/path/to/test", "test", 100L, false, false); + service.notifyDownloadSuccessful(guid, "/path/to/test", "test", 100L, false, false, false); assertEquals(1, getService().getNotificationIds().size()); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/MockDownloadNotificationService.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/MockDownloadNotificationService.java index c5b99f67..6bc32bc7 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/MockDownloadNotificationService.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/MockDownloadNotificationService.java
@@ -93,15 +93,14 @@ } @Override - public int notifyDownloadSuccessful( - final String downloadGuid, final String filePath, final String fileName, - final long systemDownloadId, final boolean isOfflinePage, - final boolean isSupportedMimeType) { + public int notifyDownloadSuccessful(final String downloadGuid, final String filePath, + final String fileName, final long systemDownloadId, final boolean isOffTheRecord, + final boolean isOfflinePage, final boolean isSupportedMimeType) { return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Integer>() { @Override public Integer call() throws Exception { - return MockDownloadNotificationService.super.notifyDownloadSuccessful( - downloadGuid, filePath, fileName, systemDownloadId, isOfflinePage, + return MockDownloadNotificationService.super.notifyDownloadSuccessful(downloadGuid, + filePath, fileName, systemDownloadId, isOffTheRecord, isOfflinePage, isSupportedMimeType); } });
diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc index 7bac0755..cf40708b 100644 --- a/chrome/app/chrome_exe_main_win.cc +++ b/chrome/app/chrome_exe_main_win.cc
@@ -230,6 +230,7 @@ HINSTANCE instance = GetModuleHandle(nullptr); #endif install_static::InitializeFromPrimaryModule(); + SignalInitializeCrashReporting(); // Initialize the CommandLine singleton from the environment. base::CommandLine::Init(0, nullptr);
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index 8991b14d..8a4e8f2e 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc
@@ -62,12 +62,13 @@ #if defined(OS_WIN) #include <atlbase.h> #include <malloc.h> + #include <algorithm> + #include "base/debug/close_handle_hook_win.h" #include "chrome/browser/downgrade/user_data_downgrade.h" #include "chrome/child/v8_breakpad_support_win.h" #include "chrome/common/child_process_logging.h" -#include "components/crash/content/app/crashpad.h" #include "sandbox/win/src/sandbox.h" #include "ui/base/resource/resource_bundle_win.h" #endif @@ -78,7 +79,6 @@ #include "chrome/browser/mac/relauncher.h" #include "chrome/browser/shell_integration.h" #include "chrome/common/mac/cfbundle_blocker.h" -#include "components/crash/content/app/crashpad.h" #include "components/crash/core/common/objc_zombie.h" #include "ui/base/l10n/l10n_util_mac.h" #endif @@ -127,6 +127,7 @@ #if defined(OS_MACOSX) || defined(OS_WIN) #include "chrome/browser/policy/policy_path_parser.h" +#include "components/crash/content/app/crashpad.h" #endif #if defined(OS_CHROMEOS) @@ -222,7 +223,7 @@ #endif // defined(OS_WIN) #if defined(OS_LINUX) -static void AdjustLinuxOOMScore(const std::string& process_type) { +void AdjustLinuxOOMScore(const std::string& process_type) { // Browsers and zygotes should still be killable, but killed last. const int kZygoteScore = 0; // The minimum amount to bump a score by. This is large enough that @@ -271,6 +272,9 @@ } else { NOTREACHED() << "Unknown process type"; } + // In the case of a 0 score, still try to adjust it. Most likely the score is + // 0 already, but it may not be if this process inherited a higher score from + // its parent process. if (score > -1) base::AdjustOOMScore(base::GetCurrentProcId(), score); }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 20521d5..0af3e63 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -12580,6 +12580,21 @@ <message name="IDS_PIN_KEYBOARD_DELETE_ACCESSIBLE_NAME" desc="Text to be spoken when the focus is set to the delete button of the PIN keyboard."> Delete </message> + <message name="IDS_FINGERPRINT_HINT_TEXT" desc="Text to display in the password field for user pod when user moves his mouse over the fingerprint icon."> + Touch to sign in + </message> + <message name="IDS_FINGERPRINT_LOGIN_TEXT" desc="Text to display in the password field for user pod when user is trying to login with fingerprint."> + Signing in... + </message> + <message name="IDS_FINGERPRINT_LOGIN_FAILED_TEXT" desc="Text to display in the password field for user pod when user failed to login with fingerprint."> + Not recognized + </message> + <message name="IDS_FINGERPRINT_ICON_MESSAGE" desc="Message to display when user moves his mouse over the fingerprint icon in the user pod."> + Place your finger on the fingerprint sensor to unlock the device. + </message> + <message name="IDS_LOGIN_ERROR_FINGERPRINT_MAX_ATTEMPT" desc="Couldn't sign in because fingerprint unlock has reached maximum attempt"> + Sorry, your fingerprint is still not recognized. Please enter your password. + </message> </if> <message name="IDS_LOGIN_ERROR_AUTHENTICATING" desc="Couldn't sign in because password is invalid"> Sorry, your password could not be verified. Please try again.
diff --git a/chrome/browser/android/ntp/ntp_snippets_bridge.cc b/chrome/browser/android/ntp/ntp_snippets_bridge.cc index b5d38e19..e8e554c 100644 --- a/chrome/browser/android/ntp/ntp_snippets_bridge.cc +++ b/chrome/browser/android/ntp/ntp_snippets_bridge.cc
@@ -71,6 +71,8 @@ if (suggestion.download_suggestion_extra()->is_download_asset) { Java_SnippetsBridge_setAssetDownloadDataForSuggestion( env, java_suggestion, + ConvertUTF8ToJavaString( + env, suggestion.download_suggestion_extra()->download_guid), ConvertUTF8ToJavaString(env, suggestion.download_suggestion_extra() ->target_file_path.value()), ConvertUTF8ToJavaString(
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 765ca42..8ee0da30 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -211,7 +211,6 @@ #include "chrome/browser/win/browser_util.h" #include "chrome/browser/win/chrome_select_file_dialog_factory.h" #include "chrome/install_static/install_util.h" -#include "components/crash/content/app/crashpad.h" #include "ui/base/l10n/l10n_util_win.h" #include "ui/shell_dialogs/select_file_dialog.h" #endif // defined(OS_WIN) @@ -1417,18 +1416,6 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() { TRACE_EVENT0("startup", "ChromeBrowserMainParts::PreMainMessageLoopRunImpl"); -#if defined(OS_WIN) - HMODULE chrome_elf = GetModuleHandle(chrome::kChromeElfDllName); - if (chrome_elf) { - auto block_until_handler_started = reinterpret_cast<void (*)()>( - GetProcAddress(chrome_elf, "BlockUntilHandlerStartedImpl")); - if (block_until_handler_started) { - SCOPED_UMA_HISTOGRAM_TIMER("Startup.BlockForCrashpadHandlerStartupTime"); - block_until_handler_started(); - } - } -#endif - SCOPED_UMA_HISTOGRAM_LONG_TIMER("Startup.PreMainMessageLoopRunImplLongTime"); const base::TimeTicks start_time_step1 = base::TimeTicks::Now();
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_screen_browsertest.cc b/chrome/browser/chromeos/login/enrollment/enrollment_screen_browsertest.cc index d1029f88..534381c 100644 --- a/chrome/browser/chromeos/login/enrollment/enrollment_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/enrollment/enrollment_screen_browsertest.cc
@@ -41,8 +41,8 @@ IN_PROC_BROWSER_TEST_F(EnrollmentScreenTest, TestCancel) { ASSERT_TRUE(WizardController::default_controller()); - EnrollmentScreen* enrollment_screen = - EnrollmentScreen::Get(WizardController::default_controller()); + EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get( + WizardController::default_controller()->screen_manager()); ASSERT_TRUE(enrollment_screen); base::RunLoop run_loop; @@ -69,8 +69,8 @@ ASSERT_TRUE(WizardController::default_controller()); EXPECT_FALSE(StartupUtils::IsOobeCompleted()); - EnrollmentScreen* enrollment_screen = - EnrollmentScreen::Get(WizardController::default_controller()); + EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get( + WizardController::default_controller()->screen_manager()); ASSERT_TRUE(enrollment_screen); base::RunLoop run_loop; @@ -105,8 +105,8 @@ IN_PROC_BROWSER_TEST_F(AttestationAuthEnrollmentScreenTest, TestCancel) { ASSERT_TRUE(WizardController::default_controller()); - EnrollmentScreen* enrollment_screen = - EnrollmentScreen::Get(WizardController::default_controller()); + EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get( + WizardController::default_controller()->screen_manager()); ASSERT_TRUE(enrollment_screen); base::RunLoop run_loop; @@ -133,7 +133,8 @@ WizardController* wcontroller = WizardController::default_controller(); ASSERT_TRUE(wcontroller); - EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get(wcontroller); + EnrollmentScreen* enrollment_screen = + EnrollmentScreen::Get(wcontroller->screen_manager()); ASSERT_TRUE(enrollment_screen); EnrollmentScreenView* view = enrollment_screen->GetView(); @@ -177,8 +178,8 @@ IN_PROC_BROWSER_TEST_F(ForcedAttestationAuthEnrollmentScreenTest, TestCancel) { ASSERT_TRUE(WizardController::default_controller()); - EnrollmentScreen* enrollment_screen = - EnrollmentScreen::Get(WizardController::default_controller()); + EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get( + WizardController::default_controller()->screen_manager()); ASSERT_TRUE(enrollment_screen); base::RunLoop run_loop; @@ -224,8 +225,8 @@ IN_PROC_BROWSER_TEST_F(MultiAuthEnrollmentScreenTest, TestCancel) { ASSERT_TRUE(WizardController::default_controller()); - EnrollmentScreen* enrollment_screen = - EnrollmentScreen::Get(WizardController::default_controller()); + EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get( + WizardController::default_controller()->screen_manager()); ASSERT_TRUE(enrollment_screen); base::RunLoop run_loop; @@ -269,8 +270,8 @@ IN_PROC_BROWSER_TEST_F(ProvisionedEnrollmentScreenTest, TestBackButton) { ASSERT_TRUE(WizardController::default_controller()); - EnrollmentScreen* enrollment_screen = - EnrollmentScreen::Get(WizardController::default_controller()); + EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get( + WizardController::default_controller()->screen_manager()); ASSERT_TRUE(enrollment_screen); base::RunLoop run_loop;
diff --git a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc index 41f22f90..7b602e2 100644 --- a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc +++ b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc
@@ -201,7 +201,8 @@ // Helper method to return the current EnrollmentScreen instance. EnrollmentScreen* enrollment_screen() { - return EnrollmentScreen::Get(WizardController::default_controller()); + return EnrollmentScreen::Get( + WizardController::default_controller()->screen_manager()); } private:
diff --git a/chrome/browser/chromeos/login/oobe_localization_browsertest.cc b/chrome/browser/chromeos/login/oobe_localization_browsertest.cc index 8dd3473..b389b27 100644 --- a/chrome/browser/chromeos/login/oobe_localization_browsertest.cc +++ b/chrome/browser/chromeos/login/oobe_localization_browsertest.cc
@@ -94,8 +94,8 @@ class LanguageListWaiter : public NetworkScreen::Observer { public: LanguageListWaiter() - : network_screen_( - NetworkScreen::Get(WizardController::default_controller())), + : network_screen_(NetworkScreen::Get( + WizardController::default_controller()->screen_manager())), loop_(base::TimeDelta::FromSeconds(kTimeoutSeconds), "LanguageList") { network_screen_->AddObserver(this); CheckLanguageList();
diff --git a/chrome/browser/chromeos/login/screen_manager.cc b/chrome/browser/chromeos/login/screen_manager.cc index 8457c5a6..23ee4fa 100644 --- a/chrome/browser/chromeos/login/screen_manager.cc +++ b/chrome/browser/chromeos/login/screen_manager.cc
@@ -4,22 +4,24 @@ #include "chrome/browser/chromeos/login/screen_manager.h" +#include "base/memory/ptr_util.h" +#include "chrome/browser/chromeos/login/wizard_controller.h" + namespace chromeos { -ScreenManager::ScreenManager() { -} +ScreenManager::ScreenManager(WizardController* wizard_controller) + : wizard_controller_(wizard_controller) {} -ScreenManager::~ScreenManager() { -} +ScreenManager::~ScreenManager() {} BaseScreen* ScreenManager::GetScreen(OobeScreen screen) { auto iter = screens_.find(screen); if (iter != screens_.end()) return iter->second.get(); - BaseScreen* result = CreateScreen(screen); + BaseScreen* result = wizard_controller_->CreateScreen(screen); DCHECK(result) << "Can not create screen named " << GetOobeScreenName(screen); - screens_[screen] = make_linked_ptr(result); + screens_[screen] = base::WrapUnique(result); return result; }
diff --git a/chrome/browser/chromeos/login/screen_manager.h b/chrome/browser/chromeos/login/screen_manager.h index 360d2b2..e0b1383 100644 --- a/chrome/browser/chromeos/login/screen_manager.h +++ b/chrome/browser/chromeos/login/screen_manager.h
@@ -6,26 +6,26 @@ #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREEN_MANAGER_H_ #include <map> +#include <memory> #include <string> #include "base/gtest_prod_util.h" #include "base/macros.h" -#include "base/memory/linked_ptr.h" #include "chrome/browser/chromeos/login/screens/base_screen.h" namespace chromeos { +class WizardController; + // Class that manages creation and ownership of screens. class ScreenManager { public: - ScreenManager(); - virtual ~ScreenManager(); + // |wizard_controller| is not owned by this class. + explicit ScreenManager(WizardController* wizard_controller); + ~ScreenManager(); // Getter for screen with lazy initialization. - virtual BaseScreen* GetScreen(OobeScreen screen); - - // Factory for screen instances. - virtual BaseScreen* CreateScreen(OobeScreen screen) = 0; + BaseScreen* GetScreen(OobeScreen screen); bool HasScreen(OobeScreen screen); @@ -37,8 +37,11 @@ friend class WizardInProcessBrowserTest; friend class WizardControllerBrokenLocalStateTest; - // Screens. - std::map<OobeScreen, linked_ptr<BaseScreen>> screens_; + // Created screens. + std::map<OobeScreen, std::unique_ptr<BaseScreen>> screens_; + + // Used to allocate BaseScreen instances. Unowned. + WizardController* wizard_controller_; DISALLOW_COPY_AND_ASSIGN(ScreenManager); };
diff --git a/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc index 55da5eb..3337dee 100644 --- a/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc
@@ -71,8 +71,8 @@ WizardInProcessBrowserTest::SetUpOnMainThread(); mock_base_screen_delegate_.reset(new MockBaseScreenDelegate()); ASSERT_TRUE(WizardController::default_controller() != nullptr); - network_screen_ = - NetworkScreen::Get(WizardController::default_controller()); + network_screen_ = NetworkScreen::Get( + WizardController::default_controller()->screen_manager()); ASSERT_TRUE(network_screen_ != nullptr); ASSERT_EQ(WizardController::default_controller()->current_screen(), network_screen_);
diff --git a/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc index 0eff6659..84dbbc8 100644 --- a/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc
@@ -83,9 +83,10 @@ WizardInProcessBrowserTest::SetUpOnMainThread(); - ASSERT_TRUE(WizardController::default_controller() != NULL); - update_screen_ = UpdateScreen::Get(WizardController::default_controller()); - ASSERT_TRUE(update_screen_ != NULL); + ASSERT_TRUE(WizardController::default_controller() != nullptr); + update_screen_ = UpdateScreen::Get( + WizardController::default_controller()->screen_manager()); + ASSERT_TRUE(update_screen_ != nullptr); ASSERT_EQ(WizardController::default_controller()->current_screen(), update_screen_); update_screen_->base_screen_delegate_ = mock_base_screen_delegate_.get();
diff --git a/chrome/browser/chromeos/login/supervised/supervised_user_creation_flow.cc b/chrome/browser/chromeos/login/supervised/supervised_user_creation_flow.cc index 394046d..ff70fbbd 100644 --- a/chrome/browser/chromeos/login/supervised/supervised_user_creation_flow.cc +++ b/chrome/browser/chromeos/login/supervised/supervised_user_creation_flow.cc
@@ -18,8 +18,8 @@ SupervisedUserCreationScreen* GetScreen(LoginDisplayHost* host) { DCHECK(host); DCHECK(host->GetWizardController()); - SupervisedUserCreationScreen* result = - SupervisedUserCreationScreen::Get(host->GetWizardController()); + SupervisedUserCreationScreen* result = SupervisedUserCreationScreen::Get( + host->GetWizardController()->screen_manager()); DCHECK(result); return result; }
diff --git a/chrome/browser/chromeos/login/users/avatar/user_image_sync_observer.cc b/chrome/browser/chromeos/login/users/avatar/user_image_sync_observer.cc index 9ec5471..747c037 100644 --- a/chrome/browser/chromeos/login/users/avatar/user_image_sync_observer.cc +++ b/chrome/browser/chromeos/login/users/avatar/user_image_sync_observer.cc
@@ -189,7 +189,8 @@ bool UserImageSyncObserver::CanUpdateLocalImageNow() { if (WizardController* wizard_controller = WizardController::default_controller()) { - UserImageScreen* screen = UserImageScreen::Get(wizard_controller); + UserImageScreen* screen = + UserImageScreen::Get(wizard_controller->screen_manager()); if (wizard_controller->current_screen() == screen) { if (screen->user_selected_image()) return false;
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index eeb7042c..b06e37f 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -251,7 +251,10 @@ PrefService* WizardController::local_state_for_testing_ = nullptr; WizardController::WizardController(LoginDisplayHost* host, OobeUI* oobe_ui) - : host_(host), oobe_ui_(oobe_ui), weak_factory_(this) { + : screen_manager_(this), + host_(host), + oobe_ui_(oobe_ui), + weak_factory_(this) { DCHECK(default_controller_ == nullptr); default_controller_ = this; if (!ash_util::IsRunningInMash()) { @@ -358,7 +361,7 @@ BaseScreen* WizardController::GetScreen(OobeScreen screen) { if (screen == OobeScreen::SCREEN_ERROR_MESSAGE) return GetErrorScreen(); - return ScreenManager::GetScreen(screen); + return screen_manager_.GetScreen(screen); } BaseScreen* WizardController::CreateScreen(OobeScreen screen) { @@ -430,7 +433,8 @@ VLOG(1) << "Showing network screen."; // Hide the status area initially; it only appears after OOBE first animates // in. Keep it visible if the user goes back to the existing network screen. - SetStatusAreaVisible(HasScreen(OobeScreen::SCREEN_OOBE_NETWORK)); + SetStatusAreaVisible( + screen_manager_.HasScreen(OobeScreen::SCREEN_OOBE_NETWORK)); SetCurrentScreen(GetScreen(OobeScreen::SCREEN_OOBE_NETWORK)); // There are two possible screens where we listen to the incoming Bluetooth @@ -582,7 +586,8 @@ void WizardController::ShowAutoEnrollmentCheckScreen() { VLOG(1) << "Showing Auto-enrollment check screen."; SetStatusAreaVisible(true); - AutoEnrollmentCheckScreen* screen = AutoEnrollmentCheckScreen::Get(this); + AutoEnrollmentCheckScreen* screen = + AutoEnrollmentCheckScreen::Get(screen_manager()); if (retry_auto_enrollment_check_) screen->ClearState(); screen->set_auto_enrollment_controller(host_->GetAutoEnrollmentController()); @@ -893,7 +898,7 @@ void WizardController::StartOOBEUpdate() { VLOG(1) << "StartOOBEUpdate"; SetCurrentScreenSmooth(GetScreen(OobeScreen::SCREEN_OOBE_UPDATE), true); - UpdateScreen::Get(this)->StartNetworkCheck(); + UpdateScreen::Get(screen_manager())->StartNetworkCheck(); } void WizardController::StartTimezoneResolve() { @@ -1195,7 +1200,7 @@ void WizardController::SetHostNetwork() { if (!shark_controller_) return; - NetworkScreen* network_screen = NetworkScreen::Get(this); + NetworkScreen* network_screen = NetworkScreen::Get(screen_manager()); std::string onc_spec; network_screen->GetConnectedWifiNetwork(&onc_spec); if (!onc_spec.empty()) @@ -1205,7 +1210,7 @@ void WizardController::SetHostConfiguration() { if (!shark_controller_) return; - NetworkScreen* network_screen = NetworkScreen::Get(this); + NetworkScreen* network_screen = NetworkScreen::Get(screen_manager()); shark_controller_->SetHostConfiguration( true, // Eula must be accepted before we get this far. network_screen->GetApplicationLocale(), network_screen->GetTimezone(), @@ -1224,7 +1229,7 @@ StartupUtils::MarkEulaAccepted(); SetUsageStatisticsReporting(send_reports); - NetworkScreen* network_screen = NetworkScreen::Get(this); + NetworkScreen* network_screen = NetworkScreen::Get(screen_manager()); network_screen->SetApplicationLocaleAndInputMethod(lang, keyboard_layout); network_screen->SetTimezone(timezone); @@ -1241,7 +1246,7 @@ remora_controller_->OnNetworkConnectivityChanged( pairing_chromeos::HostPairingController::CONNECTIVITY_CONNECTING); - NetworkScreen* network_screen = NetworkScreen::Get(this); + NetworkScreen* network_screen = NetworkScreen::Get(screen_manager()); const chromeos::NetworkState* network_state = chromeos::NetworkHandler::Get() ->network_state_handler() ->DefaultNetwork(); @@ -1506,7 +1511,7 @@ : policy::EnrollmentConfig::MODE_MANUAL_REENROLLMENT; } - EnrollmentScreen* screen = EnrollmentScreen::Get(this); + EnrollmentScreen* screen = EnrollmentScreen::Get(screen_manager()); screen->SetParameters(effective_config, shark_controller_.get()); SetStatusAreaVisible(true); SetCurrentScreen(screen);
diff --git a/chrome/browser/chromeos/login/wizard_controller.h b/chrome/browser/chromeos/login/wizard_controller.h index d11dffc..8e9d150 100644 --- a/chrome/browser/chromeos/login/wizard_controller.h +++ b/chrome/browser/chromeos/login/wizard_controller.h
@@ -51,7 +51,6 @@ // Class that manages control flow between wizard screens. Wizard controller // interacts with screen controllers to move the user between screens. class WizardController : public BaseScreenDelegate, - public ScreenManager, public EulaScreen::Delegate, public ControllerPairingScreen::Delegate, public HostPairingScreen::Delegate, @@ -113,13 +112,19 @@ // Returns true if the current wizard instance has reached the login screen. bool login_screen_started() const { return login_screen_started_; } - // ScreenManager implementation. - BaseScreen* GetScreen(OobeScreen screen) override; - BaseScreen* CreateScreen(OobeScreen screen) override; + // Returns a given screen. Creates it lazily. + BaseScreen* GetScreen(OobeScreen screen); + + // Returns the current ScreenManager instance. + ScreenManager* screen_manager() { return &screen_manager_; } // Volume percent at which spoken feedback is still audible. static const int kMinAudibleOutputVolumePercent; + // Allocate a given BaseScreen for the given |Screen|. Used by + // |screen_manager_|. + BaseScreen* CreateScreen(OobeScreen screen); + private: // Show specific screen. void ShowNetworkScreen(); @@ -300,6 +305,8 @@ // attestation-based enrollment if appropriate. void StartEnrollmentScreen(bool force_interactive); + ScreenManager screen_manager_; + // Whether to skip any screens that may normally be shown after login // (registration, Terms of Service, user image selection). static bool skip_post_login_screens_;
diff --git a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc index bb21659..fc2123da 100644 --- a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc +++ b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
@@ -222,20 +222,22 @@ std::unique_ptr<H> view_; }; -#define MOCK(mock_var, screen_name, mocked_class, view_class) \ - mock_var = new MockOutShowHide<mocked_class, view_class>( \ - WizardController::default_controller(), new view_class); \ - WizardController::default_controller()->screens_[screen_name] = \ - make_linked_ptr(mock_var); \ - EXPECT_CALL(*mock_var, Show()).Times(0); \ +#define MOCK(mock_var, screen_name, mocked_class, view_class) \ + mock_var = new MockOutShowHide<mocked_class, view_class>( \ + WizardController::default_controller(), new view_class); \ + WizardController::default_controller() \ + ->screen_manager() \ + ->screens_[screen_name] = base::WrapUnique(mock_var); \ + EXPECT_CALL(*mock_var, Show()).Times(0); \ EXPECT_CALL(*mock_var, Hide()).Times(0); #define MOCK_WITH_DELEGATE(mock_var, screen_name, mocked_class, view_class) \ mock_var = new MockOutShowHide<mocked_class, view_class>( \ WizardController::default_controller(), \ WizardController::default_controller(), new view_class); \ - WizardController::default_controller()->screens_[screen_name] = \ - make_linked_ptr(mock_var); \ + WizardController::default_controller() \ + ->screen_manager() \ + ->screens_[screen_name] = base::WrapUnique(mock_var); \ EXPECT_CALL(*mock_var, Show()).Times(0); \ EXPECT_CALL(*mock_var, Hide()).Times(0); @@ -419,11 +421,13 @@ NetworkHandler::Get()->network_state_handler()->SetCheckPortalList(""); // Set up the mocks for all screens. - mock_network_screen_.reset(new MockNetworkScreen( + mock_network_screen_ = new MockNetworkScreen( WizardController::default_controller(), - WizardController::default_controller(), GetOobeUI()->GetNetworkView())); + WizardController::default_controller(), GetOobeUI()->GetNetworkView()); WizardController::default_controller() - ->screens_[OobeScreen::SCREEN_OOBE_NETWORK] = mock_network_screen_; + ->screen_manager() + ->screens_[OobeScreen::SCREEN_OOBE_NETWORK] + .reset(mock_network_screen_); EXPECT_CALL(*mock_network_screen_, Show()).Times(0); EXPECT_CALL(*mock_network_screen_, Hide()).Times(0); @@ -442,9 +446,10 @@ OobeScreen::SCREEN_OOBE_ENABLE_DEBUGGING, MockEnableDebuggingScreen, MockEnableDebuggingScreenView); device_disabled_screen_view_.reset(new MockDeviceDisabledScreenView); - wizard_controller->screens_[OobeScreen::SCREEN_DEVICE_DISABLED] = - make_linked_ptr(new DeviceDisabledScreen( - wizard_controller, device_disabled_screen_view_.get())); + wizard_controller->screen_manager() + ->screens_[OobeScreen::SCREEN_DEVICE_DISABLED] = + base::MakeUnique<DeviceDisabledScreen>( + wizard_controller, device_disabled_screen_view_.get()); EXPECT_CALL(*device_disabled_screen_view_, Show()).Times(0); // Switch to the initial screen. @@ -454,7 +459,7 @@ } void TearDownOnMainThread() override { - mock_network_screen_.reset(); + mock_network_screen_ = nullptr; device_disabled_screen_view_.reset(); WizardControllerTest::TearDownOnMainThread(); } @@ -512,7 +517,7 @@ } void ResetAutoEnrollmentCheckScreen() { - WizardController::default_controller()->screens_.erase( + WizardController::default_controller()->screen_manager()->screens_.erase( OobeScreen::SCREEN_AUTO_ENROLLMENT_CHECK); } @@ -567,7 +572,7 @@ ->GetCurrentTimezoneID())); } - linked_ptr<MockNetworkScreen> mock_network_screen_; + MockNetworkScreen* mock_network_screen_; // Unowned ptr. MockOutShowHide<MockUpdateScreen, MockUpdateView>* mock_update_screen_; MockOutShowHide<MockEulaScreen, MockEulaView>* mock_eula_screen_; MockOutShowHide<MockEnrollmentScreen, MockEnrollmentScreenView>*
diff --git a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc index d333cb9..9806dd7b 100644 --- a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc +++ b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc
@@ -33,6 +33,9 @@ // The rate in milliseconds at which we will poll CUPS for print job updates. const int kPollRate = 1000; +// Threshold for giving up on communicating with CUPS. +const int kRetryMax = 6; + // Returns the equivalient CupsPrintJob#State from a CupsJob#JobState. chromeos::CupsPrintJob::State ConvertState(printing::CupsJob::JobState state) { using cpj = chromeos::CupsPrintJob::State; @@ -61,6 +64,13 @@ return cpj::STATE_NONE; } +chromeos::QueryResult QueryCups(::printing::CupsConnection* connection, + const std::vector<std::string>& printer_ids) { + chromeos::QueryResult result; + result.success = connection->GetJobs(printer_ids, &result.queues); + return result; +} + } // namespace namespace chromeos { @@ -134,6 +144,7 @@ total_page_number); std::string key = cpj->GetUniqueId(); jobs_[key] = std::move(cpj); + CupsPrintJob* job = jobs_[key].get(); NotifyJobCreated(job); @@ -153,36 +164,67 @@ void CupsPrintJobManagerImpl::ScheduleQuery(const base::TimeDelta& delay) { if (!in_query_) { in_query_ = true; - content::BrowserThread::PostDelayedTask( - content::BrowserThread::FILE_USER_BLOCKING, FROM_HERE, - base::Bind(&CupsPrintJobManagerImpl::QueryCups, + + base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&CupsPrintJobManagerImpl::PostQuery, weak_ptr_factory_.GetWeakPtr()), - base::TimeDelta::FromMilliseconds(kPollRate)); + delay); } } -// Query CUPS asynchronously. Post results back to UI thread. -void CupsPrintJobManagerImpl::QueryCups() { - std::vector<::printing::CupsJob> jobs = cups_connection_.GetJobs(); +void CupsPrintJobManagerImpl::PostQuery() { + // The set of active printers is expected to be small. + std::set<std::string> printer_ids; + for (const auto& entry : jobs_) { + printer_ids.insert(entry.second->printer().id()); + } + std::vector<std::string> ids{printer_ids.begin(), printer_ids.end()}; - content::BrowserThread::PostTask( - content::BrowserThread::ID::UI, FROM_HERE, + content::BrowserThread::PostTaskAndReplyWithResult( + content::BrowserThread::FILE_USER_BLOCKING, FROM_HERE, + base::Bind(&QueryCups, &cups_connection_, ids), base::Bind(&CupsPrintJobManagerImpl::UpdateJobs, - weak_ptr_factory_.GetWeakPtr(), jobs)); + weak_ptr_factory_.GetWeakPtr())); } // Use job information to update local job states. Previously completed jobs // could be in |jobs| but those are ignored as we will not emit updates for them // after they are completed. -void CupsPrintJobManagerImpl::UpdateJobs( - const std::vector<::printing::CupsJob>& jobs) { +void CupsPrintJobManagerImpl::UpdateJobs(const QueryResult& result) { + const std::vector<::printing::QueueStatus>& queues = result.queues; + + // Query has completed. Allow more queries. in_query_ = false; + // If the query failed, either retry or purge. + if (!result.success) { + retry_count_++; + LOG(WARNING) << "Failed to query CUPS for queue status. Schedule retry (" + << retry_count_ << ")"; + if (retry_count_ > kRetryMax) { + LOG(ERROR) << "CUPS is unreachable. Giving up on all jobs."; + PurgeJobs(); + } else { + // Schedule another query with a larger delay. + DCHECK_GE(1, retry_count_); + ScheduleQuery( + base::TimeDelta::FromMilliseconds(kPollRate * retry_count_)); + } + return; + } + + // A query has completed. Reset retry counter. + retry_count_ = 0; + std::vector<std::string> active_jobs; - for (auto& job : jobs) { - std::string key = CupsPrintJob::GetUniqueId(job.printer_id, job.id); - const auto& entry = jobs_.find(key); - if (entry != jobs_.end()) { + for (const auto& queue : queues) { + for (auto& job : queue.jobs) { + std::string key = CupsPrintJob::GetUniqueId(job.printer_id, job.id); + const auto& entry = jobs_.find(key); + if (entry == jobs_.end()) + continue; + CupsPrintJob* print_job = entry->second.get(); // Update a job we're tracking. @@ -199,20 +241,25 @@ // Keep polling until all jobs complete or error. if (!active_jobs.empty()) { + // During normal operations, we poll at the default rate. ScheduleQuery(); } else if (!jobs_.empty()) { // We're tracking jobs that we didn't receive an update for. Something bad // has happened. LOG(ERROR) << "Lost track of (" << jobs_.size() << ") jobs"; - for (const auto& entry : jobs_) { - // Declare all lost jobs errors. - JobStateUpdated(entry.second.get(), CupsPrintJob::State::STATE_ERROR); - } - - jobs_.clear(); + PurgeJobs(); } } +void CupsPrintJobManagerImpl::PurgeJobs() { + for (const auto& entry : jobs_) { + // Declare all lost jobs errors. + JobStateUpdated(entry.second.get(), CupsPrintJob::State::STATE_ERROR); + } + + jobs_.clear(); +} + void CupsPrintJobManagerImpl::JobStateUpdated(CupsPrintJob* job, CupsPrintJob::State new_state) { if (job->state() == new_state)
diff --git a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.h b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.h index afd64c9..d32066d6 100644 --- a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.h +++ b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.h
@@ -23,6 +23,11 @@ namespace chromeos { +struct QueryResult { + bool success; + std::vector<::printing::QueueStatus> queues; +}; + class CupsPrintJobManagerImpl : public CupsPrintJobManager, public content::NotificationObserver { public: @@ -52,11 +57,15 @@ // Schedule a query of CUPS for print job status with a delay of |delay|. void ScheduleQuery(const base::TimeDelta& delay); - // Query CUPS for print job status. - void QueryCups(); + // Schedule the CUPS query off the UI thread. Posts results back to UI thread + // to UpdateJobs. + void PostQuery(); // Process jobs from CUPS and perform notifications. - void UpdateJobs(const std::vector<::printing::CupsJob>& jobs); + void UpdateJobs(const QueryResult& results); + + // Mark remaining jobs as errors and remove active jobs. + void PurgeJobs(); // Updates the state and performs the appropriate notifications. void JobStateUpdated(CupsPrintJob* job, CupsPrintJob::State new_state); @@ -67,6 +76,9 @@ // Prevents multiple queries from being scheduled simultaneously. bool in_query_ = false; + // Records the number of consecutive times the GetJobs query has failed. + int retry_count_ = 0; + ::printing::CupsConnection cups_connection_; content::NotificationRegistrar registrar_; base::WeakPtrFactory<CupsPrintJobManagerImpl> weak_ptr_factory_;
diff --git a/chrome/browser/extensions/signin/OWNERS b/chrome/browser/extensions/signin/OWNERS index 0a53d1b..35b5a0ac 100644 --- a/chrome/browser/extensions/signin/OWNERS +++ b/chrome/browser/extensions/signin/OWNERS
@@ -1,3 +1,4 @@ xiyuan@chromium.org -guohui@chromium.org rogerta@chromium.org + +# COMPONENT: Services>SignIn
diff --git a/chrome/browser/ntp_snippets/download_suggestions_provider.cc b/chrome/browser/ntp_snippets/download_suggestions_provider.cc index 9d38a9e..58dab7d 100644 --- a/chrome/browser/ntp_snippets/download_suggestions_provider.cc +++ b/chrome/browser/ntp_snippets/download_suggestions_provider.cc
@@ -617,6 +617,7 @@ suggestion.set_publisher_name( base::UTF8ToUTF16(download_item.GetURL().host())); auto extra = base::MakeUnique<ntp_snippets::DownloadSuggestionExtra>(); + extra->download_guid = download_item.GetGuid(); extra->target_file_path = download_item.GetTargetFilePath(); extra->mime_type = download_item.GetMimeType(); extra->is_download_asset = true;
diff --git a/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc b/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc index 0b0b51e..c5f2773b 100644 --- a/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc +++ b/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc
@@ -150,6 +150,7 @@ std::unique_ptr<FakeDownloadItem> item = base::MakeUnique<FakeDownloadItem>(); item->SetId(id); std::string id_string = base::IntToString(id); + item->SetGuid("XYZ-100032-EFZBDF-13323-PXZ" + id_string); item->SetTargetFilePath( base::FilePath::FromUTF8Unsafe("folder/file" + id_string + ".mhtml")); item->SetURL(GURL("http://download.com/redirected" + id_string));
diff --git a/chrome/browser/ntp_snippets/fake_download_item.cc b/chrome/browser/ntp_snippets/fake_download_item.cc index 05d8a52..39eb275 100644 --- a/chrome/browser/ntp_snippets/fake_download_item.cc +++ b/chrome/browser/ntp_snippets/fake_download_item.cc
@@ -55,6 +55,14 @@ return id_; } +void FakeDownloadItem::SetGuid(const std::string& guid) { + guid_ = guid; +} + +const std::string& FakeDownloadItem::GetGuid() const { + return guid_; +} + void FakeDownloadItem::SetURL(const GURL& url) { url_ = url; } @@ -156,11 +164,6 @@ NOTREACHED(); } -const std::string& FakeDownloadItem::GetGuid() const { - NOTREACHED(); - return dummy_string; -} - content::DownloadInterruptReason FakeDownloadItem::GetLastReason() const { NOTREACHED(); return content::DownloadInterruptReason();
diff --git a/chrome/browser/ntp_snippets/fake_download_item.h b/chrome/browser/ntp_snippets/fake_download_item.h index c91dfd9..37e36146 100644 --- a/chrome/browser/ntp_snippets/fake_download_item.h +++ b/chrome/browser/ntp_snippets/fake_download_item.h
@@ -39,6 +39,9 @@ void SetId(uint32_t id); uint32_t GetId() const override; + void SetGuid(const std::string& guid); + const std::string& GetGuid() const override; + void SetURL(const GURL& url); const GURL& GetURL() const override; @@ -73,7 +76,6 @@ void Remove() override; void OpenDownload() override; void ShowDownloadInShell() override; - const std::string& GetGuid() const override; content::DownloadInterruptReason GetLastReason() const override; bool IsPaused() const override; bool IsTemporary() const override; @@ -129,6 +131,7 @@ private: base::ObserverList<Observer> observers_; uint32_t id_; + std::string guid_; GURL url_; base::FilePath file_path_; bool is_file_externally_removed_;
diff --git a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc index 2b80325..29b01b3 100644 --- a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc
@@ -4,9 +4,13 @@ #include "chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/net/nqe/ui_network_quality_estimator_service.h" +#include "chrome/browser/net/nqe/ui_network_quality_estimator_service_factory.h" #include "chrome/browser/page_load_metrics/page_load_metrics_util.h" +#include "chrome/browser/profiles/profile.h" #include "components/ukm/ukm_entry_builder.h" #include "components/ukm/ukm_service.h" +#include "content/public/browser/web_contents.h" namespace internal { @@ -20,21 +24,39 @@ const char kUkmFirstMeaningfulPaintName[] = "Experimental.PaintTiming.NavigationToFirstMeaningfulPaint"; const char kUkmForegroundDurationName[] = "PageTiming.ForegroundDuration"; +const char kUkmEffectiveConnectionType[] = + "Net.EffectiveConnectionType.OnNavigationStart"; } // namespace internal +namespace { + +UINetworkQualityEstimatorService* GetNQEService( + content::WebContents* web_contents) { + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + if (!profile) + return nullptr; + return UINetworkQualityEstimatorServiceFactory::GetForProfile(profile); +} + +} // namespace + // static std::unique_ptr<page_load_metrics::PageLoadMetricsObserver> -UkmPageLoadMetricsObserver::CreateIfNeeded() { +UkmPageLoadMetricsObserver::CreateIfNeeded(content::WebContents* web_contents) { if (!g_browser_process->ukm_service()) { return nullptr; } - - return base::MakeUnique<UkmPageLoadMetricsObserver>(); + return base::MakeUnique<UkmPageLoadMetricsObserver>( + GetNQEService(web_contents)); } -UkmPageLoadMetricsObserver::UkmPageLoadMetricsObserver() - : source_id_(ukm::UkmService::GetNewSourceID()) {} +UkmPageLoadMetricsObserver::UkmPageLoadMetricsObserver( + net::NetworkQualityEstimator::NetworkQualityProvider* + network_quality_provider) + : network_quality_provider_(network_quality_provider), + source_id_(ukm::UkmService::GetNewSourceID()) {} UkmPageLoadMetricsObserver::~UkmPageLoadMetricsObserver() = default; @@ -45,8 +67,17 @@ if (!started_in_foreground) return STOP_OBSERVING; - ukm::UkmService* ukm_service = g_browser_process->ukm_service(); - ukm_service->UpdateSourceURL(source_id_, navigation_handle->GetURL()); + // When OnStart is invoked, we don't yet know whether we're observing a web + // page load, vs another kind of load (e.g. a download or a PDF). Thus, + // metrics and source information should not be recorded here. Instead, we + // store data we might want to persist in member variables below, and later + // record UKM metrics for that data once we've confirmed that we're observing + // a web page load. + + if (network_quality_provider_) { + effective_connection_type_ = + network_quality_provider_->GetEffectiveConnectionType(); + } return CONTINUE_OBSERVING; } @@ -54,17 +85,17 @@ UkmPageLoadMetricsObserver::FlushMetricsOnAppEnterBackground( const page_load_metrics::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& info) { - RecordTimingMetrics(timing); RecordPageLoadExtraInfoMetrics(info, base::TimeTicks::Now()); + RecordTimingMetrics(timing); return STOP_OBSERVING; } UkmPageLoadMetricsObserver::ObservePolicy UkmPageLoadMetricsObserver::OnHidden( const page_load_metrics::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& info) { - RecordTimingMetrics(timing); RecordPageLoadExtraInfoMetrics( info, base::TimeTicks() /* no app_background_time */); + RecordTimingMetrics(timing); return STOP_OBSERVING; } @@ -78,9 +109,9 @@ void UkmPageLoadMetricsObserver::OnComplete( const page_load_metrics::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& info) { - RecordTimingMetrics(timing); RecordPageLoadExtraInfoMetrics( info, base::TimeTicks() /* no app_background_time */); + RecordTimingMetrics(timing); } void UkmPageLoadMetricsObserver::RecordTimingMetrics( @@ -115,16 +146,20 @@ const page_load_metrics::PageLoadExtraInfo& info, base::TimeTicks app_background_time) { ukm::UkmService* ukm_service = g_browser_process->ukm_service(); + ukm_service->UpdateSourceURL(source_id_, info.start_url); ukm_service->UpdateSourceURL(source_id_, info.url); + std::unique_ptr<ukm::UkmEntryBuilder> builder = + ukm_service->GetEntryBuilder(source_id_, internal::kUkmPageLoadEventName); base::Optional<base::TimeDelta> foreground_duration = page_load_metrics::GetInitialForegroundDuration(info, app_background_time); if (foreground_duration) { - std::unique_ptr<ukm::UkmEntryBuilder> builder = - ukm_service->GetEntryBuilder(source_id_, - internal::kUkmPageLoadEventName); builder->AddMetric(internal::kUkmForegroundDurationName, foreground_duration.value().InMilliseconds()); } + if (effective_connection_type_ != net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) { + builder->AddMetric(internal::kUkmEffectiveConnectionType, + static_cast<int64_t>(effective_connection_type_)); + } }
diff --git a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.h index 59df31f..16dfbbb 100644 --- a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.h
@@ -7,6 +7,11 @@ #include "base/macros.h" #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h" +#include "net/nqe/network_quality_estimator.h" + +namespace content { +class WebContents; +} namespace internal { @@ -18,6 +23,7 @@ extern const char kUkmFirstContentfulPaintName[]; extern const char kUkmFirstMeaningfulPaintName[]; extern const char kUkmForegroundDurationName[]; +extern const char kUkmEffectiveConnectionType[]; } // namespace internal @@ -28,9 +34,11 @@ public: // Returns a UkmPageLoadMetricsObserver, or nullptr if it is not needed. static std::unique_ptr<page_load_metrics::PageLoadMetricsObserver> - CreateIfNeeded(); + CreateIfNeeded(content::WebContents* web_contents); - UkmPageLoadMetricsObserver(); + explicit UkmPageLoadMetricsObserver( + net::NetworkQualityEstimator::NetworkQualityProvider* + network_quality_provider); ~UkmPageLoadMetricsObserver() override; // page_load_metrics::PageLoadMetricsObserver implementation: @@ -65,9 +73,15 @@ const page_load_metrics::PageLoadExtraInfo& info, base::TimeTicks app_background_time); + net::NetworkQualityEstimator::NetworkQualityProvider* const + network_quality_provider_; + // Unique UKM identifier for the page load we are recording metrics for. const int32_t source_id_; + net::EffectiveConnectionType effective_connection_type_ = + net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN; + DISALLOW_COPY_AND_ASSIGN(UkmPageLoadMetricsObserver); };
diff --git a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc index e5bf87d..fa4dc6c 100644 --- a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc
@@ -12,24 +12,47 @@ #include "components/ukm/test_ukm_service.h" #include "components/ukm/ukm_entry.h" #include "components/ukm/ukm_source.h" +#include "testing/gmock/include/gmock/gmock.h" + +using testing::AnyNumber; +using testing::Mock; +using testing::Return; namespace { const char kTestUrl1[] = "https://www.google.com/"; const char kTestUrl2[] = "https://www.example.com/"; +class MockNetworkQualityProvider + : public net::NetworkQualityEstimator::NetworkQualityProvider { + public: + MOCK_CONST_METHOD0(GetEffectiveConnectionType, + net::EffectiveConnectionType()); + MOCK_METHOD1( + AddEffectiveConnectionTypeObserver, + void(net::NetworkQualityEstimator::EffectiveConnectionTypeObserver*)); + MOCK_METHOD1( + RemoveEffectiveConnectionTypeObserver, + void(net::NetworkQualityEstimator::EffectiveConnectionTypeObserver*)); +}; + } // namespace class UkmPageLoadMetricsObserverTest : public page_load_metrics::PageLoadMetricsObserverTestHarness { protected: void RegisterObservers(page_load_metrics::PageLoadTracker* tracker) override { - tracker->AddObserver(base::MakeUnique<UkmPageLoadMetricsObserver>()); + tracker->AddObserver(base::MakeUnique<UkmPageLoadMetricsObserver>( + &mock_network_quality_provider_)); } void SetUp() override { page_load_metrics::PageLoadMetricsObserverTestHarness::SetUp(); + EXPECT_CALL(mock_network_quality_provider_, GetEffectiveConnectionType()) + .Times(AnyNumber()) + .WillRepeatedly(Return(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN)); + TestingBrowserProcess::GetGlobal()->SetUkmService( ukm_service_test_harness_.test_ukm_service()); } @@ -42,6 +65,10 @@ return ukm_service_test_harness_.test_ukm_service()->entries_count(); } + MockNetworkQualityProvider& mock_network_quality_provider() { + return mock_network_quality_provider_; + } + const ukm::UkmSource* GetUkmSource(size_t source_index) { return ukm_service_test_harness_.test_ukm_service()->GetSource( source_index); @@ -118,6 +145,7 @@ } private: + MockNetworkQualityProvider mock_network_quality_provider_; ukm::UkmServiceTestingHarness ukm_service_test_harness_; }; @@ -250,3 +278,26 @@ EXPECT_TRUE( HasMetric(internal::kUkmForegroundDurationName, entry2_proto.metrics())); } + +TEST_F(UkmPageLoadMetricsObserverTest, EffectiveConnectionType) { + EXPECT_CALL(mock_network_quality_provider(), GetEffectiveConnectionType()) + .WillRepeatedly(Return(net::EFFECTIVE_CONNECTION_TYPE_3G)); + + NavigateAndCommit(GURL(kTestUrl1)); + + // Simulate closing the tab. + DeleteContents(); + + EXPECT_EQ(1ul, ukm_source_count()); + const ukm::UkmSource* source = GetUkmSource(0); + EXPECT_EQ(GURL(kTestUrl1), source->url()); + + EXPECT_GE(ukm_entry_count(), 1ul); + ukm::Entry entry_proto = GetMergedEntryProtoForSourceID(source->id()); + EXPECT_EQ(entry_proto.source_id(), source->id()); + EXPECT_EQ(entry_proto.event_hash(), + base::HashMetricName(internal::kUkmPageLoadEventName)); + EXPECT_FALSE(entry_proto.metrics().empty()); + ExpectMetric(internal::kUkmEffectiveConnectionType, + net::EFFECTIVE_CONNECTION_TYPE_3G, entry_proto.metrics()); +}
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc b/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc index 3af2ffd..ffca700 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc
@@ -92,7 +92,7 @@ tracker->AddObserver(base::MakeUnique<TabRestorePageLoadMetricsObserver>()); std::unique_ptr<page_load_metrics::PageLoadMetricsObserver> ukm_observer = - UkmPageLoadMetricsObserver::CreateIfNeeded(); + UkmPageLoadMetricsObserver::CreateIfNeeded(web_contents_); if (ukm_observer) tracker->AddObserver(std::move(ukm_observer));
diff --git a/chrome/browser/resources/feedback/js/feedback.js b/chrome/browser/resources/feedback/js/feedback.js index 6d8b39c..cb51b962 100644 --- a/chrome/browser/resources/feedback/js/feedback.js +++ b/chrome/browser/resources/feedback/js/feedback.js
@@ -344,6 +344,9 @@ }); chrome.feedbackPrivate.getUserEmail(function(email) { + // Never add an empty option. + if (!email) + return; var optionElement = document.createElement('option'); optionElement.value = email; optionElement.text = email;
diff --git a/chrome/browser/shell_integration_linux.cc b/chrome/browser/shell_integration_linux.cc index 57072b8..afdcd87c 100644 --- a/chrome/browser/shell_integration_linux.cc +++ b/chrome/browser/shell_integration_linux.cc
@@ -164,27 +164,26 @@ #endif } -// If |protocol| is empty this function checks if Chrome is the default browser, -// otherwise it checks if Chrome is the default handler application for -// |protocol|. -DefaultWebClientState GetIsDefaultWebClient(const std::string& protocol) { -#if defined(OS_CHROMEOS) - return UNKNOWN_DEFAULT; -#else - base::ThreadRestrictions::AssertIOAllowed(); - - std::unique_ptr<base::Environment> env(base::Environment::Create()); - +#if !defined(OS_CHROMEOS) +// If |check| is true, returns the output of "xdg-settings check {property} +// *.desktop", otherwise returns the output of "xdg-settings get {property}", +// where property is "default-web-browser" if |protocol| is empty or +// "default-url-scheme-handler |protocol|" otherwise. Returns "" if +// xdg-settings fails for any reason. +std::string GetXdgSettingsOutput(bool check, + const std::string& protocol, + base::Environment* env) { std::vector<std::string> argv; argv.push_back(kXdgSettings); - argv.push_back("check"); + argv.push_back(check ? "check" : "get"); if (protocol.empty()) { argv.push_back(kXdgSettingsDefaultBrowser); } else { argv.push_back(kXdgSettingsDefaultSchemeHandler); argv.push_back(protocol); } - argv.push_back(shell_integration_linux::GetDesktopName(env.get())); + if (check) + argv.push_back(shell_integration_linux::GetDesktopName(env)); std::string reply; int success_code; @@ -197,15 +196,47 @@ } } - if (!ran_ok || success_code != EXIT_SUCCESS) { - // xdg-settings failed: we can't determine or set the default browser. - return UNKNOWN_DEFAULT; + if (!ran_ok || success_code != EXIT_SUCCESS) + return std::string(); + + return reply; +} +#endif + +// If |protocol| is empty this function checks if Chrome is the default browser, +// otherwise it checks if Chrome is the default handler application for +// |protocol|. +DefaultWebClientState GetDefaultWebClient(const std::string& protocol) { +#if defined(OS_CHROMEOS) + return UNKNOWN_DEFAULT; +#else + base::ThreadRestrictions::AssertIOAllowed(); + + std::unique_ptr<base::Environment> env(base::Environment::Create()); + std::string xdg_is_default = GetXdgSettingsOutput(true, protocol, env.get()); + if (base::StartsWith(xdg_is_default, "yes", base::CompareCase::SENSITIVE)) { + return IS_DEFAULT; + } + if (base::StartsWith(xdg_is_default, "no", base::CompareCase::SENSITIVE)) { + // An output of "no" does not necessarily mean Chrom[e,ium] is not the + // default. According to the xdg-settings man page, this can happen when + // "only some of the underlying settings actually reflect that value". Don't + // return NOT_DEFAULT unless we're sure, or else an annoying "Chrome is not + // your default browser" banner will appear on every launch + // (https://crbug.com/578888). + if (base::StartsWith(GetXdgSettingsOutput(false, protocol, env.get()), + shell_integration_linux::GetDesktopName(env.get()), + base::CompareCase::SENSITIVE)) { + // This is the odd case where 'xdg-settings check' said that Chrome wasn't + // the default, but 'xdg-settings get' returned Chrome as the default. + return UNKNOWN_DEFAULT; + } + // xdg-settings says the default is non-Chrome, and is self-consistent. + return NOT_DEFAULT; } - // Allow any reply that starts with "yes". - return base::StartsWith(reply, "yes", base::CompareCase::SENSITIVE) - ? IS_DEFAULT - : NOT_DEFAULT; + // xdg-settings failed: we can't determine or set the default browser. + return UNKNOWN_DEFAULT; #endif } @@ -243,7 +274,7 @@ } DefaultWebClientState GetDefaultBrowser() { - return GetIsDefaultWebClient(std::string()); + return GetDefaultWebClient(std::string()); } bool IsFirefoxDefaultBrowser() { @@ -259,7 +290,7 @@ } DefaultWebClientState IsDefaultProtocolClient(const std::string& protocol) { - return GetIsDefaultWebClient(protocol); + return GetDefaultWebClient(protocol); } } // namespace shell_integration
diff --git a/chrome/browser/sync/test/integration/profile_sync_service_harness.cc b/chrome/browser/sync/test/integration/profile_sync_service_harness.cc index 97f45645..cd187f3 100644 --- a/chrome/browser/sync/test/integration/profile_sync_service_harness.cc +++ b/chrome/browser/sync/test/integration/profile_sync_service_harness.cc
@@ -19,6 +19,8 @@ #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/webui/signin/login_ui_service.h" +#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" #include "chrome/browser/ui/webui/signin/login_ui_test_utils.h" #include "chrome/common/channel_info.h" #include "chrome/common/chrome_switches.h" @@ -130,19 +132,30 @@ } bool ProfileSyncServiceHarness::SetupSync() { - bool result = SetupSync(syncer::UserSelectableTypes()); - if (result == false) { - std::string status = GetServiceStatus(); - LOG(ERROR) << profile_debug_name_ - << ": SetupSync failed. Syncer status:\n" << status; + bool result = SetupSync(syncer::UserSelectableTypes(), false); + if (!result) { + LOG(ERROR) << profile_debug_name_ << ": SetupSync failed. Syncer status:\n" + << GetServiceStatus(); } else { DVLOG(1) << profile_debug_name_ << ": SetupSync successful."; } return result; } -bool ProfileSyncServiceHarness::SetupSync( - syncer::ModelTypeSet synced_datatypes) { +bool ProfileSyncServiceHarness::SetupSyncForClearingServerData() { + bool result = SetupSync(syncer::UserSelectableTypes(), true); + if (!result) { + LOG(ERROR) << profile_debug_name_ + << ": SetupSyncForClear failed. Syncer status:\n" + << GetServiceStatus(); + } else { + DVLOG(1) << profile_debug_name_ << ": SetupSyncForClear successful."; + } + return result; +} + +bool ProfileSyncServiceHarness::SetupSync(syncer::ModelTypeSet synced_datatypes, + bool skip_passphrase_verification) { DCHECK(!profile_->IsLegacySupervised()) << "SetupSync should not be used for legacy supervised users."; @@ -179,17 +192,20 @@ // Now that auth is completed, request that sync actually start. service()->RequestStart(); - if (!AwaitEngineInitialization()) { + if (!AwaitEngineInitialization(skip_passphrase_verification)) { return false; } - // Choose the datatypes to be synced. If all datatypes are to be synced, // set sync_everything to true; otherwise, set it to false. bool sync_everything = (synced_datatypes == syncer::UserSelectableTypes()); service()->OnUserChoseDatatypes(sync_everything, synced_datatypes); // Notify ProfileSyncService that we are done with configuration. - FinishSyncSetup(); + if (skip_passphrase_verification) { + sync_blocker_.reset(); + } else { + FinishSyncSetup(); + } if ((signin_type_ == SigninType::UI_SIGNIN) && !login_ui_test_utils::DismissSyncConfirmationDialog( @@ -199,6 +215,20 @@ return false; } + // OneClickSigninSyncStarter observer is created with a real user sign in. + // It is deleted on certain conditions which are not satisfied by our tests, + // and this causes the SigninTracker observer to stay hanging at shutdown. + // Calling LoginUIService::SyncConfirmationUIClosed forces the observer to + // be removed. http://crbug.com/484388 + if (signin_type_ == SigninType::UI_SIGNIN) { + LoginUIServiceFactory::GetForProfile(profile_)->SyncConfirmationUIClosed( + LoginUIService::SYNC_WITH_DEFAULT_SETTINGS); + } + + if (skip_passphrase_verification) { + return true; + } + // Set an implicit passphrase for encryption if an explicit one hasn't already // been set. If an explicit passphrase has been set, immediately return false, // since a decryption passphrase is required. @@ -212,7 +242,43 @@ // Wait for initial sync cycle to be completed. if (!AwaitSyncSetupCompletion()) { - LOG(ERROR) << "Initial sync cycle timed out."; + return false; + } + + return true; +} + +bool ProfileSyncServiceHarness::RestartSyncService() { + DVLOG(1) << "Requesting stop for service."; + service()->RequestStop(ProfileSyncService::CLEAR_DATA); + + std::unique_ptr<syncer::SyncSetupInProgressHandle> blocker = + service()->GetSetupInProgressHandle(); + DVLOG(1) << "Requesting start for service"; + service()->RequestStart(); + + if (!AwaitEngineInitialization()) { + LOG(ERROR) << "AwaitEngineInitialization failed."; + return false; + } + DVLOG(1) << "Engine Initialized successfully."; + + // This passphrase should be implicit because ClearServerData should be called + // prior. + if (!service()->IsUsingSecondaryPassphrase()) { + service()->SetEncryptionPassphrase(password_, ProfileSyncService::IMPLICIT); + } else { + LOG(ERROR) << "A passphrase is required for decryption. Sync cannot proceed" + " until SetDecryptionPassphrase is called."; + return false; + } + DVLOG(1) << "Passphrase decryption success."; + + blocker.reset(); + service()->SetFirstSetupComplete(); + + if (!AwaitSyncSetupCompletion()) { + LOG(FATAL) << "AwaitSyncSetupCompletion failed."; return false; } @@ -246,7 +312,8 @@ return QuiesceStatusChangeChecker(services).Wait(); } -bool ProfileSyncServiceHarness::AwaitEngineInitialization() { +bool ProfileSyncServiceHarness::AwaitEngineInitialization( + bool skip_passphrase_verification) { if (!EngineInitializeChecker(service()).Wait()) { LOG(ERROR) << "EngineInitializeChecker timed out."; return false; @@ -258,7 +325,8 @@ } // Make sure that initial sync wasn't blocked by a missing passphrase. - if (service()->passphrase_required_reason() == syncer::REASON_DECRYPTION) { + if (!skip_passphrase_verification && + service()->passphrase_required_reason() == syncer::REASON_DECRYPTION) { LOG(ERROR) << "A passphrase is required for decryption. Sync cannot proceed" " until SetDecryptionPassphrase is called."; return false;
diff --git a/chrome/browser/sync/test/integration/profile_sync_service_harness.h b/chrome/browser/sync/test/integration/profile_sync_service_harness.h index b4b82eb2..42ca6400 100644 --- a/chrome/browser/sync/test/integration/profile_sync_service_harness.h +++ b/chrome/browser/sync/test/integration/profile_sync_service_harness.h
@@ -55,9 +55,21 @@ // changes. bool SetupSync(); + // Setup sync without the authenticating through the passphrase encryption. + // Use this method when you need to setup a client that you're going to call + // RestartSyncService() directly after. + bool SetupSyncForClearingServerData(); + + // Both SetupSync and SetupSyncForClear call into this method. // Same as the above method, but enables sync only for the datatypes contained // in |synced_datatypes|. - bool SetupSync(syncer::ModelTypeSet synced_datatypes); + bool SetupSync(syncer::ModelTypeSet synced_datatypes, + bool skip_passphrase_verification = false); + + // Restart sync service to simulate a sign-in/sign-out. This is useful + // to recover from a lost birthday. Use directly after a clear server data + // command to start from clean slate. + bool RestartSyncService(); // Calling this acts as a barrier and blocks the caller until |this| and // |partner| have both completed a sync cycle. When calling this method, @@ -86,7 +98,7 @@ // (e.g., auth error) is reached. Returns true if and only if the engine // initialized successfully. See ProfileSyncService's IsEngineInitialized() // method for the definition of engine initialization. - bool AwaitEngineInitialization(); + bool AwaitEngineInitialization(bool skip_passphrase_verification = false); // Blocks the caller until sync setup is complete. Returns true if and only // if sync setup completed successfully. See syncer::SyncService's
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc index 5008bee..64cc0210 100644 --- a/chrome/browser/sync/test/integration/sync_test.cc +++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -620,9 +620,21 @@ } } + int clientIndex = 0; + // If we're using external servers, clear server data so the account starts + // with a clean slate. + if (UsingExternalServers()) { + if (!SetupAndClearClient(clientIndex++)) { + LOG(FATAL) << "Setting up and clearing data for client " + << clientIndex - 1 << " failed"; + return false; + } + } + // Sync each of the profiles. - for (int i = 0; i < num_clients_; ++i) { - if (!GetClient(i)->SetupSync()) { + for (; clientIndex < num_clients_; clientIndex++) { + DVLOG(1) << "Setting up " << clientIndex << " client"; + if (!GetClient(clientIndex)->SetupSync()) { LOG(FATAL) << "SetupSync() failed."; return false; } @@ -669,6 +681,23 @@ return true; } +bool SyncTest::SetupAndClearClient(size_t index) { + // Setup the first client so the sync engine is initialized, which is + // required to clear server data. + DVLOG(1) << "Setting up first client for clear."; + if (!GetClient(index)->SetupSyncForClearingServerData()) { + LOG(FATAL) << "SetupSync() failed."; + return false; + } + + DVLOG(1) << "Done setting up first client for clear."; + if (!ClearServerData(GetClient(index++))) { + LOG(FATAL) << "ClearServerData failed."; + return false; + } + return true; +} + void SyncTest::TearDownOnMainThread() { for (size_t i = 0; i < clients_.size(); ++i) { clients_[i]->service()->RequestStop(ProfileSyncService::CLEAR_DATA); @@ -1148,3 +1177,14 @@ const std::string& contents) { preexisting_preferences_file_contents_ = contents; } + +bool SyncTest::ClearServerData(ProfileSyncServiceHarness* harness) { + // At this point our birthday is good. + base::RunLoop run_loop; + harness->service()->ClearServerDataForTest(run_loop.QuitClosure()); + run_loop.Run(); + + // Our birthday is invalidated on the server here so restart sync to get + // the new birthday from the server. + return harness->RestartSyncService(); +}
diff --git a/chrome/browser/sync/test/integration/sync_test.h b/chrome/browser/sync/test/integration/sync_test.h index fb151cf..da2ac60d 100644 --- a/chrome/browser/sync/test/integration/sync_test.h +++ b/chrome/browser/sync/test/integration/sync_test.h
@@ -180,6 +180,9 @@ // Initializes sync clients and profiles if required and syncs each of them. virtual bool SetupSync() WARN_UNUSED_RESULT; + // Initialize, and clear data for given client. + bool SetupAndClearClient(size_t index); + // Sets whether or not the sync clients in this test should respond to // notifications of their own commits. Real sync clients do not do this, but // many test assertions require this behavior. @@ -376,6 +379,9 @@ // value of |server_type_|. void InitializeInvalidations(int index); + // Clear server data, and restart sync. + bool ClearServerData(ProfileSyncServiceHarness* harness); + // Python sync test server, started on demand. syncer::LocalSyncTestServer sync_server_;
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.h b/chrome/browser/ui/cocoa/browser_window_controller.h index 705b592..3fc7c95a 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.h +++ b/chrome/browser/ui/cocoa/browser_window_controller.h
@@ -390,6 +390,9 @@ // Returns the BrowserWindowTouchBar object associated with the window. - (BrowserWindowTouchBar*)browserWindowTouchBar; +// Invalidates the browser's touch bar. +- (void)invalidateTouchBar; + @end // @interface BrowserWindowController
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index 39788f10..5b70340 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -1009,8 +1009,7 @@ [toolbarController_ setStarredState:isStarred]; [touchBar_ setIsStarred:isStarred]; - if ([[self window] respondsToSelector:@selector(setTouchBar:)]) - [[self window] performSelector:@selector(setTouchBar:) withObject:nil]; + [self invalidateTouchBar]; } - (void)setCurrentPageIsTranslated:(BOOL)on { @@ -1149,8 +1148,7 @@ - (void)setIsLoading:(BOOL)isLoading force:(BOOL)force { [toolbarController_ setIsLoading:isLoading force:force]; [touchBar_ setIsPageLoading:isLoading]; - if ([[self window] respondsToSelector:@selector(setTouchBar:)]) - [[self window] performSelector:@selector(setTouchBar:) withObject:nil]; + [self invalidateTouchBar]; } // Make the location bar the first responder, if possible. @@ -1853,13 +1851,19 @@ - (BrowserWindowTouchBar*)browserWindowTouchBar { if (!touchBar_) { - touchBar_.reset( - [[BrowserWindowTouchBar alloc] initWithBrowser:browser_.get()]); + touchBar_.reset([[BrowserWindowTouchBar alloc] + initWithBrowser:browser_.get() + browserWindowController:self]); } return touchBar_.get(); } +- (void)invalidateTouchBar { + if ([[self window] respondsToSelector:@selector(setTouchBar:)]) + [[self window] performSelector:@selector(setTouchBar:) withObject:nil]; +} + @end // @implementation BrowserWindowController @implementation BrowserWindowController(Fullscreen)
diff --git a/chrome/browser/ui/cocoa/browser_window_touch_bar.h b/chrome/browser/ui/cocoa/browser_window_touch_bar.h index 5e670650..5952600 100644 --- a/chrome/browser/ui/cocoa/browser_window_touch_bar.h +++ b/chrome/browser/ui/cocoa/browser_window_touch_bar.h
@@ -10,6 +10,7 @@ #import "ui/base/cocoa/touch_bar_forward_declarations.h" class Browser; +@class BrowserWindowController; // Provides a touch bar for the browser window. This class implements the // NSTouchBarDelegate and handles the items in the touch bar. @@ -22,7 +23,8 @@ @property(nonatomic, assign) BOOL isStarred; // Designated initializer. -- (instancetype)initWithBrowser:(Browser*)browser; +- (instancetype)initWithBrowser:(Browser*)browser + browserWindowController:(BrowserWindowController*)bwc; // Creates and returns a touch bar for the browser window. - (NSTouchBar*)makeTouchBar;
diff --git a/chrome/browser/ui/cocoa/browser_window_touch_bar.mm b/chrome/browser/ui/cocoa/browser_window_touch_bar.mm index 255b62d..274ff4cb 100644 --- a/chrome/browser/ui/cocoa/browser_window_touch_bar.mm +++ b/chrome/browser/ui/cocoa/browser_window_touch_bar.mm
@@ -4,6 +4,8 @@ #import "chrome/browser/ui/cocoa/browser_window_touch_bar.h" +#include <memory> + #include "base/mac/mac_util.h" #import "base/mac/scoped_nsobject.h" #import "base/mac/sdk_forward_declarations.h" @@ -11,12 +13,16 @@ #include "chrome/app/chrome_command_ids.h" #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/command_updater.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_command_controller.h" +#import "chrome/browser/ui/cocoa/browser_window_controller.h" #include "chrome/common/chrome_features.h" +#include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/omnibox/browser/vector_icons.h" +#include "components/prefs/pref_member.h" #include "components/search_engines/util.h" #include "components/toolbar/vector_icons.h" #include "ui/base/l10n/l10n_util.h" @@ -36,6 +42,7 @@ // Touch bar items identifiers. const NSTouchBarItemIdentifier kBackForwardTouchId = @"BackForwardTouchId"; const NSTouchBarItemIdentifier kReloadOrStopTouchId = @"ReloadOrStopTouchId"; +const NSTouchBarItemIdentifier kHomeTouchId = @"HomeTouchId"; const NSTouchBarItemIdentifier kSearchTouchId = @"SearchTouchId"; const NSTouchBarItemIdentifier kStarTouchId = @"StarTouchId"; const NSTouchBarItemIdentifier kNewTabTouchId = @"NewTabTouchId"; @@ -52,7 +59,8 @@ const int kTouchBarIconSize = 16; // The width of the search button in the touch bar. -const int kTouchBarSearchButtonWidth = 280; +const int kSearchBtnWidthWithHomeBtn = 205; +const int kSearchBtnWidthWithoutHomeBtn = 280; // Creates an NSImage from the given VectorIcon. NSImage* CreateNSImageFromIcon(const gfx::VectorIcon& icon, @@ -75,6 +83,23 @@ return button; } +// A class registered for C++ notifications. This is used to detect changes in +// the home button preferences and update the Touch Bar. +class HomePrefNotificationBridge { + public: + explicit HomePrefNotificationBridge(BrowserWindowController* bwc) + : bwc_(bwc) {} + + ~HomePrefNotificationBridge() {} + + void UpdateTouchBar() { [bwc_ invalidateTouchBar]; } + + private: + BrowserWindowController* bwc_; // Weak. + + DISALLOW_COPY_AND_ASSIGN(HomePrefNotificationBridge); +}; + } // namespace @interface BrowserWindowTouchBar () { @@ -83,6 +108,14 @@ // The browser associated with the touch bar. Browser* browser_; // Weak. + + BrowserWindowController* bwc_; // Weak, own us. + + // Used to monitor the optional home button pref. + BooleanPrefMember showHomeButton_; + + // Used to receive and handle notifications for the home button pref. + std::unique_ptr<HomePrefNotificationBridge> notificationBridge_; } // Creates and return the back and forward segmented buttons. @@ -97,11 +130,20 @@ @synthesize isPageLoading = isPageLoading_; @synthesize isStarred = isStarred_; -- (instancetype)initWithBrowser:(Browser*)browser { +- (instancetype)initWithBrowser:(Browser*)browser + browserWindowController:(BrowserWindowController*)bwc { if ((self = [self init])) { DCHECK(browser); commandUpdater_ = browser->command_controller()->command_updater(); browser_ = browser; + bwc_ = bwc; + + notificationBridge_.reset(new HomePrefNotificationBridge(bwc_)); + PrefService* prefs = browser->profile()->GetPrefs(); + showHomeButton_.Init( + prefs::kShowHomeButton, prefs, + base::Bind(&HomePrefNotificationBridge::UpdateTouchBar, + base::Unretained(notificationBridge_.get()))); } return self; @@ -113,10 +155,19 @@ base::scoped_nsobject<NSTouchBar> touchBar( [[NSClassFromString(@"NSTouchBar") alloc] init]); - NSArray* touchBarItemIdentifiers = @[ - kBackForwardTouchId, kReloadOrStopTouchId, kSearchTouchId, kStarTouchId, - kNewTabTouchId - ]; + NSArray* touchBarItemIdentifiers; + if (showHomeButton_.GetValue()) { + touchBarItemIdentifiers = @[ + kBackForwardTouchId, kReloadOrStopTouchId, kHomeTouchId, kSearchTouchId, + kStarTouchId, kNewTabTouchId + ]; + } else { + touchBarItemIdentifiers = @[ + kBackForwardTouchId, kReloadOrStopTouchId, kSearchTouchId, kStarTouchId, + kNewTabTouchId + ]; + } + [touchBar setCustomizationIdentifier:kBrowserWindowTouchBarId]; [touchBar setDefaultItemIdentifiers:touchBarItemIdentifiers]; [touchBar setCustomizationAllowedItemIdentifiers:touchBarItemIdentifiers]; @@ -139,6 +190,9 @@ isPageLoading_ ? kNavigateStopIcon : kNavigateReloadIcon; int command_id = isPageLoading_ ? IDC_STOP : IDC_RELOAD; [touchBarItem setView:CreateTouchBarButton(icon, self, command_id)]; + } else if ([identifier isEqualTo:kHomeTouchId]) { + [touchBarItem + setView:CreateTouchBarButton(kNavigateHomeIcon, self, IDC_HOME)]; } else if ([identifier isEqualTo:kNewTabTouchId]) { [touchBarItem setView:CreateTouchBarButton(kNewTabMacTouchbarIcon, self, IDC_NEW_TAB)]; @@ -206,9 +260,9 @@ action:@selector(executeCommand:)]; searchButton.imageHugsTitle = YES; searchButton.tag = IDC_FOCUS_LOCATION; - [searchButton.widthAnchor - constraintEqualToConstant:kTouchBarSearchButtonWidth] - .active = YES; + int width = showHomeButton_.GetValue() ? kSearchBtnWidthWithHomeBtn + : kSearchBtnWidthWithoutHomeBtn; + [searchButton.widthAnchor constraintEqualToConstant:width].active = YES; return searchButton; }
diff --git a/chrome/browser/ui/cocoa/browser_window_touch_bar_unittest.mm b/chrome/browser/ui/cocoa/browser_window_touch_bar_unittest.mm index 92ac48ee..fa9cdff 100644 --- a/chrome/browser/ui/cocoa/browser_window_touch_bar_unittest.mm +++ b/chrome/browser/ui/cocoa/browser_window_touch_bar_unittest.mm
@@ -9,6 +9,8 @@ #include "chrome/app/chrome_command_ids.h" #import "chrome/browser/ui/cocoa/browser_window_touch_bar.h" #include "chrome/browser/ui/cocoa/test/cocoa_profile_test.h" +#include "chrome/common/pref_names.h" +#include "components/prefs/pref_service.h" #include "testing/gtest/include/gtest/gtest.h" class BrowserWindowTouchBarUnitTest : public CocoaProfileTest { @@ -16,8 +18,9 @@ void SetUp() override { CocoaProfileTest::SetUp(); ASSERT_TRUE(browser()); - browserWindowTouchBar_.reset( - [[BrowserWindowTouchBar alloc] initWithBrowser:browser()]); + browserWindowTouchBar_.reset([[BrowserWindowTouchBar alloc] + initWithBrowser:browser() + browserWindowController:nil]); } void TearDown() override { CocoaProfileTest::TearDown(); } @@ -29,10 +32,24 @@ if (!base::mac::IsAtLeastOS10_12()) return; - NSTouchBar* touchBar = [browserWindowTouchBar_ makeTouchBar]; - NSArray* touchBarItemIds = [touchBar itemIdentifiers]; + PrefService* prefs = profile()->GetPrefs(); + DCHECK(prefs); + prefs->SetBoolean(prefs::kShowHomeButton, true); + + NSArray* touchBarItemIds = + [[browserWindowTouchBar_ makeTouchBar] itemIdentifiers]; EXPECT_TRUE([touchBarItemIds containsObject:@"BackForwardTouchId"]); EXPECT_TRUE([touchBarItemIds containsObject:@"ReloadOrStopTouchId"]); + EXPECT_TRUE([touchBarItemIds containsObject:@"HomeTouchId"]); + EXPECT_TRUE([touchBarItemIds containsObject:@"SearchTouchId"]); + EXPECT_TRUE([touchBarItemIds containsObject:@"NewTabTouchId"]); + EXPECT_TRUE([touchBarItemIds containsObject:@"StarTouchId"]); + + prefs->SetBoolean(prefs::kShowHomeButton, false); + touchBarItemIds = [[browserWindowTouchBar_ makeTouchBar] itemIdentifiers]; + EXPECT_TRUE([touchBarItemIds containsObject:@"BackForwardTouchId"]); + EXPECT_TRUE([touchBarItemIds containsObject:@"ReloadOrStopTouchId"]); + EXPECT_FALSE([touchBarItemIds containsObject:@"HomeTouchId"]); EXPECT_TRUE([touchBarItemIds containsObject:@"SearchTouchId"]); EXPECT_TRUE([touchBarItemIds containsObject:@"NewTabTouchId"]); EXPECT_TRUE([touchBarItemIds containsObject:@"StarTouchId"]);
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.cc b/chrome/browser/ui/views/payments/payment_request_views_util.cc index 6e110bb..62b815b 100644 --- a/chrome/browser/ui/views/payments/payment_request_views_util.cc +++ b/chrome/browser/ui/views/payments/payment_request_views_util.cc
@@ -15,7 +15,9 @@ #include "components/autofill/core/browser/autofill_type.h" #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/field_types.h" +#include "components/strings/grit/components_strings.h" #include "third_party/skia/include/core/SkColor.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" #include "ui/gfx/font_list.h" @@ -246,4 +248,34 @@ return label; } +base::string16 GetShippingAddressSectionString( + payments::mojom::PaymentShippingType shipping_type) { + switch (shipping_type) { + case payments::mojom::PaymentShippingType::DELIVERY: + return l10n_util::GetStringUTF16(IDS_PAYMENTS_DELIVERY_ADDRESS_LABEL); + case payments::mojom::PaymentShippingType::PICKUP: + return l10n_util::GetStringUTF16(IDS_PAYMENTS_PICKUP_ADDRESS_LABEL); + case payments::mojom::PaymentShippingType::SHIPPING: + return l10n_util::GetStringUTF16(IDS_PAYMENTS_SHIPPING_ADDRESS_LABEL); + } + // MSVC doesn't compile with only the above switch statement because it can't + // see that all control paths return a value. + return l10n_util::GetStringUTF16(IDS_PAYMENTS_SHIPPING_ADDRESS_LABEL); +} + +base::string16 GetShippingOptionSectionString( + payments::mojom::PaymentShippingType shipping_type) { + switch (shipping_type) { + case payments::mojom::PaymentShippingType::DELIVERY: + return l10n_util::GetStringUTF16(IDS_PAYMENTS_DELIVERY_OPTION_LABEL); + case payments::mojom::PaymentShippingType::PICKUP: + return l10n_util::GetStringUTF16(IDS_PAYMENTS_PICKUP_OPTION_LABEL); + case payments::mojom::PaymentShippingType::SHIPPING: + return l10n_util::GetStringUTF16(IDS_PAYMENTS_SHIPPING_OPTION_LABEL); + } + // MSVC doesn't compile with only the above switch statement because it can't + // see that all control paths return a value. + return l10n_util::GetStringUTF16(IDS_PAYMENTS_SHIPPING_OPTION_LABEL); +} + } // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.h b/chrome/browser/ui/views/payments/payment_request_views_util.h index a15adda..6a044dd6 100644 --- a/chrome/browser/ui/views/payments/payment_request_views_util.h +++ b/chrome/browser/ui/views/payments/payment_request_views_util.h
@@ -9,6 +9,7 @@ #include <string> #include "base/strings/string16.h" +#include "components/payments/content/payment_request.mojom.h" namespace autofill { class AutofillProfile; @@ -88,6 +89,11 @@ // Creates a label with a bold font. std::unique_ptr<views::Label> CreateBoldLabel(const base::string16& text); +base::string16 GetShippingAddressSectionString( + payments::mojom::PaymentShippingType shipping_type); +base::string16 GetShippingOptionSectionString( + payments::mojom::PaymentShippingType shipping_type); + } // namespace payments #endif // CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_VIEWS_UTIL_H_
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc index e2070ab..a5ae940 100644 --- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -414,7 +414,7 @@ std::unique_ptr<views::Button> PaymentSheetViewController::CreateShippingRow() { std::unique_ptr<views::Button> section = CreatePaymentSheetRow( this, - l10n_util::GetStringUTF16(IDS_PAYMENT_REQUEST_SHIPPING_SECTION_NAME), + GetShippingAddressSectionString(request()->options()->shipping_type), CreateShippingSectionContent(), std::unique_ptr<views::View>(nullptr), widest_name_column_view_width_); section->set_tag( @@ -528,10 +528,8 @@ std::unique_ptr<views::Button> PaymentSheetViewController::CreateShippingOptionRow() { - // TODO(anthonyvd): Use the correct IDS_PAYMENTS_*_OPTION_LABEL string based - // on the data passed by the website. std::unique_ptr<views::Button> section = CreatePaymentSheetRow( - this, l10n_util::GetStringUTF16(IDS_PAYMENTS_SHIPPING_OPTION_LABEL), + this, GetShippingOptionSectionString(request()->options()->shipping_type), CreateShippingOptionContent(), std::unique_ptr<views::View>(nullptr), widest_name_column_view_width_); section->set_tag(static_cast<int>(
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index c03f474..0eb4c9e9 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -427,6 +427,10 @@ IDS_PIN_KEYBOARD_HINT_TEXT_PIN_PASSWORD); builder->Add("pinKeyboardDeleteAccessibleName", IDS_PIN_KEYBOARD_DELETE_ACCESSIBLE_NAME); + builder->Add("fingerprintHint", IDS_FINGERPRINT_HINT_TEXT); + builder->Add("fingerprintIconMessage", IDS_FINGERPRINT_ICON_MESSAGE); + builder->Add("fingerprintSigningin", IDS_FINGERPRINT_LOGIN_TEXT); + builder->Add("fingerprintSigninFailed", IDS_FINGERPRINT_LOGIN_FAILED_TEXT); builder->Add("signingIn", IDS_LOGIN_POD_SIGNING_IN); builder->Add("podMenuButtonAccessibleName", IDS_LOGIN_POD_MENU_BUTTON_ACCESSIBLE_NAME);
diff --git a/chrome/test/base/mojo_test_connector.cc b/chrome/test/base/mojo_test_connector.cc index fcbb998..da87cda 100644 --- a/chrome/test/base/mojo_test_connector.cc +++ b/chrome/test/base/mojo_test_connector.cc
@@ -67,15 +67,11 @@ #else #error "Unsupported" #endif - service_manager::mojom::ServicePtr service = - service_manager::PassServiceRequestOnCommandLine(&process_connection_, - command_line); - background_service_manager_->RegisterService( - service_manager::Identity(content::mojom::kPackagedServicesServiceName, - service_manager::mojom::kRootUserID), - std::move(service), - service_manager::mojom::PIDReceiverRequest(&pid_receiver_)); + // Create the pipe token, as it must be passed to children processes via the + // command line. + service_ = service_manager::PassServiceRequestOnCommandLine( + &process_connection_, command_line); // ChildProcessLaunched may be called on an arbitrary thread, so track the // current TaskRunner and post back to it when we want to send the PID. @@ -91,13 +87,22 @@ handle, mojo::edk::ConnectionParams(platform_channel_->PassServerHandle())); - main_task_runner_->PostTask( - FROM_HERE, - base::Bind(&MojoTestState::SetPID, weak_factory_.GetWeakPtr(), pid)); + main_task_runner_->PostTask(FROM_HERE, + base::Bind(&MojoTestState::SetupService, + weak_factory_.GetWeakPtr(), pid)); } // Called on the main thread only. - void SetPID(base::ProcessId pid) { + // This registers the services needed for the test. This is not done until + // after ChildProcessLaunched as previous test runs will tear down existing + // connections. + void SetupService(base::ProcessId pid) { + background_service_manager_->RegisterService( + service_manager::Identity(content::mojom::kPackagedServicesServiceName, + service_manager::mojom::kRootUserID), + std::move(service_), + service_manager::mojom::PIDReceiverRequest(&pid_receiver_)); + DCHECK(pid_receiver_.is_bound()); pid_receiver_->SetPID(pid); pid_receiver_.reset(); @@ -106,6 +111,11 @@ mojo::edk::PendingProcessConnection process_connection_; service_manager::BackgroundServiceManager* const background_service_manager_; + // The ServicePtr must be created before child process launch so that the pipe + // can be set on the command line. It is held until SetupService is called at + // which point |background_service_manager_| takes over ownership. + service_manager::mojom::ServicePtr service_; + // NOTE: HandlePassingInformation must remain valid through process launch, // hence it lives here instead of within Init()'s stack. mojo::edk::HandlePassingInformation handle_passing_info_;
diff --git a/chrome_elf/chrome_elf.def b/chrome_elf/chrome_elf.def index bc4d1c9..b4c3936 100644 --- a/chrome_elf/chrome_elf.def +++ b/chrome_elf/chrome_elf.def
@@ -11,4 +11,5 @@ GetUserDataDirectoryThunk IsBlacklistInitialized SignalChromeElf + SignalInitializeCrashReporting SuccessfullyBlocked
diff --git a/chrome_elf/chrome_elf_main.cc b/chrome_elf/chrome_elf_main.cc index 23edaaf..926668c 100644 --- a/chrome_elf/chrome_elf_main.cc +++ b/chrome_elf/chrome_elf_main.cc
@@ -14,6 +14,17 @@ #include "chrome_elf/blacklist/blacklist.h" #include "chrome_elf/crash/crash_helper.h" +// This function is a temporary workaround for https://crbug.com/655788. We +// need to come up with a better way to initialize crash reporting that can +// happen inside DllMain(). +void SignalInitializeCrashReporting() { + if (!elf_crash::InitializeCrashReporting()) { +#ifdef _DEBUG + assert(false); +#endif // _DEBUG + } +} + void SignalChromeElf() { blacklist::ResetBeacon(); } @@ -37,10 +48,6 @@ if (reason == DLL_PROCESS_ATTACH) { install_static::InitializeProductDetailsForPrimaryModule(); - if (!elf_crash::InitializeCrashReporting()) { - assert(false); - } - // CRT on initialization installs an exception filter which calls // TerminateProcess. We need to hook CRT's attempt to set an exception. elf_crash::DisableSetUnhandledExceptionFilter();
diff --git a/chrome_elf/chrome_elf_main.h b/chrome_elf/chrome_elf_main.h index 52bf067..432c377 100644 --- a/chrome_elf/chrome_elf_main.h +++ b/chrome_elf/chrome_elf_main.h
@@ -5,6 +5,7 @@ #ifndef CHROME_ELF_CHROME_ELF_MAIN_H_ #define CHROME_ELF_CHROME_ELF_MAIN_H_ +extern "C" void SignalInitializeCrashReporting(); extern "C" void SignalChromeElf(); #endif // CHROME_ELF_CHROME_ELF_MAIN_H_
diff --git a/chromeos/components/tether/proto/tether.proto b/chromeos/components/tether/proto/tether.proto index 3910d190..7526f2e 100644 --- a/chromeos/components/tether/proto/tether.proto +++ b/chromeos/components/tether/proto/tether.proto
@@ -85,6 +85,7 @@ UNKNOWN_ERROR = 0; SUCCESS = 1; PROVISIONING_FAILED = 2; + TETHERING_TIMEOUT = 3; } optional ResponseCode response_code = 1;
diff --git a/chromeos/dbus/cros_disks_client.cc b/chromeos/dbus/cros_disks_client.cc index 47f961d3..42ed90e 100644 --- a/chromeos/dbus/cros_disks_client.cc +++ b/chromeos/dbus/cros_disks_client.cc
@@ -40,10 +40,6 @@ const char kRemountOption[] = "remount"; const char kMountLabelOption[] = "mountlabel"; -const char* kDefaultUnmountOptions[] = { - "force", -}; - const char kLazyUnmountOption[] = "lazy"; // Checks if retrieved media type is in boundaries of DeviceMediaType. @@ -133,9 +129,7 @@ dbus::MessageWriter writer(&method_call); writer.AppendString(device_path); - std::vector<std::string> unmount_options( - kDefaultUnmountOptions, - kDefaultUnmountOptions + arraysize(kDefaultUnmountOptions)); + std::vector<std::string> unmount_options; if (options == UNMOUNT_OPTIONS_LAZY) unmount_options.push_back(kLazyUnmountOption);
diff --git a/components/autofill/core/browser/autofill_profile_unittest.cc b/components/autofill/core/browser/autofill_profile_unittest.cc index c54f2ae..ee55bc0 100644 --- a/components/autofill/core/browser/autofill_profile_unittest.cc +++ b/components/autofill/core/browser/autofill_profile_unittest.cc
@@ -39,39 +39,6 @@ return labels[0]; } -// Holds the autofill profile |first|, |middle| and |last| names. -struct NameParts { - NameParts(const std::string& first, - const std::string& middle, - const std::string& last) - : first(first), middle(middle), last(last) {} - - std::string first; - std::string middle; - std::string last; -}; - -// Test case to be executed to validate OverwriteOrAppendNames. -struct TestCase { - TestCase(const NameParts& starting_name, - const NameParts& additional_name, - const NameParts& expected_result) - : starting_names(std::vector<NameParts>(1, starting_name)), - additional_names(std::vector<NameParts>(1, additional_name)), - expected_result(std::vector<NameParts>(1, expected_result)) {} - - TestCase(const std::vector<NameParts>& starting_names, - const std::vector<NameParts>& additional_names, - const std::vector<NameParts>& expected_result) - : starting_names(starting_names), - additional_names(additional_names), - expected_result(expected_result) {} - - std::vector<NameParts> starting_names; - std::vector<NameParts> additional_names; - std::vector<NameParts> expected_result; -}; - void SetupTestProfile(AutofillProfile& profile) { profile.set_guid(base::GenerateGUID()); profile.set_origin(kSettingsOrigin);
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc index 9e63dfe..ed837f1 100644 --- a/components/browser_sync/profile_sync_service.cc +++ b/components/browser_sync/profile_sync_service.cc
@@ -1197,6 +1197,14 @@ syncer::CLEAR_SERVER_DATA_MAX); } +void ProfileSyncService::ClearServerDataForTest(const base::Closure& callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + // Sync has a restriction that the engine must be in configuration mode + // in order to run clear server data. + engine_->StartConfiguration(); + engine_->ClearServerData(callback); +} + void ProfileSyncService::OnConfigureDone( const DataTypeManager::ConfigureResult& result) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -1384,6 +1392,7 @@ std::unique_ptr<syncer::SyncSetupInProgressHandle> ProfileSyncService::GetSetupInProgressHandle() { DCHECK(thread_checker_.CalledOnValidThread()); + if (++outstanding_setup_in_progress_handles_ == 1) { DCHECK(!startup_controller_->IsSetupInProgress()); startup_controller_->SetSetupInProgress(true); @@ -2434,5 +2443,4 @@ ReconfigureDatatypeManager(); NotifyObservers(); } - } // namespace browser_sync
diff --git a/components/browser_sync/profile_sync_service.h b/components/browser_sync/profile_sync_service.h index e62cc69..b409a3e9 100644 --- a/components/browser_sync/profile_sync_service.h +++ b/components/browser_sync/profile_sync_service.h
@@ -571,6 +571,10 @@ // Triggers sync cycle with request to update specified |types|. void RefreshTypesForTest(syncer::ModelTypeSet types); + // Calls sync engine to send ClearServerDataMessage to server. This is used + // to start accounts with a clean slate when performing end to end testing. + void ClearServerDataForTest(const base::Closure& callback); + protected: // SyncServiceBase implementation. syncer::SyncCredentials GetCredentials() override;
diff --git a/components/crash/content/app/crashpad.cc b/components/crash/content/app/crashpad.cc index a0eabba..76f6734 100644 --- a/components/crash/content/app/crashpad.cc +++ b/components/crash/content/app/crashpad.cc
@@ -335,13 +335,6 @@ RequestSingleCrashUploadImpl(const std::string& local_id) { crash_reporter::RequestSingleCrashUpload(local_id); } - -// This helper is invoked by code in chrome.dll to wait for the handler start to -// complete. -void __declspec(dllexport) BlockUntilHandlerStartedImpl() { - crash_reporter::BlockUntilHandlerStarted(); -} - } // extern "C" #endif // OS_WIN
diff --git a/components/crash/content/app/crashpad.h b/components/crash/content/app/crashpad.h index 7af47f7..eeb65ac 100644 --- a/components/crash/content/app/crashpad.h +++ b/components/crash/content/app/crashpad.h
@@ -53,10 +53,6 @@ // line argument of --type=crashpad-handler. void InitializeCrashpadWithEmbeddedHandler(bool initial_client, const std::string& process_type); - -// Waits until the handler has successfully completed startup or failed, and -// logs an error in that case. -void BlockUntilHandlerStarted(); #endif // OS_WIN // Enables or disables crash report upload, taking the given consent to upload
diff --git a/components/crash/content/app/crashpad_win.cc b/components/crash/content/app/crashpad_win.cc index 3ad5f8d..6d01b28 100644 --- a/components/crash/content/app/crashpad_win.cc +++ b/components/crash/content/app/crashpad_win.cc
@@ -116,15 +116,9 @@ exe_file = exe_dir.Append(FILE_PATH_LITERAL("crashpad_handler.exe")); } - if (!g_crashpad_client.Get().StartHandler( - exe_file, database_path, metrics_path, url, process_annotations, - arguments, false, true)) { - // This means that CreateThread() failed, so this process is very messed - // up. This should be effectively unreachable. It is unlikely that there - // is any utility to ever making this non-fatal, however, if this is done, - // calls to BlockUntilHandlerStarted() will have to be amended. - LOG(FATAL) << "synchronous part of handler startup failed"; - } + g_crashpad_client.Get().StartHandler(exe_file, database_path, metrics_path, + url, process_annotations, arguments, + false, false); // If we're the browser, push the pipe name into the environment so child // processes can connect to it. If we inherited another crashpad_handler's @@ -212,16 +206,6 @@ } // namespace } // namespace internal - -void BlockUntilHandlerStarted() { - // We know that the StartHandler() at least started asynchronous startup if - // we're here, as if it doesn't, we abort. - const unsigned int kTimeoutMS = 5000; - if (!internal::g_crashpad_client.Get().WaitForHandlerStart(kTimeoutMS)) { - LOG(ERROR) << "Crashpad handler failed to start, crash reporting disabled"; - } -} - } // namespace crash_reporter extern "C" {
diff --git a/components/domain_reliability/quic_error_mapping.cc b/components/domain_reliability/quic_error_mapping.cc index 7a37026..56d3c76 100644 --- a/components/domain_reliability/quic_error_mapping.cc +++ b/components/domain_reliability/quic_error_mapping.cc
@@ -12,247 +12,244 @@ net::QuicErrorCode quic_error; const char* beacon_quic_error; } kQuicErrorMap[] = { - // Connection has reached an invalid state. - { net::QUIC_INTERNAL_ERROR, "quic.internal_error" }, - // There were data frames after the a fin or reset. - { net::QUIC_STREAM_DATA_AFTER_TERMINATION, - "quic.stream_data.after_termination" }, - // Control frame is malformed. - { net::QUIC_INVALID_PACKET_HEADER, "quic.invalid.packet_header" }, - // Frame data is malformed. - { net::QUIC_INVALID_FRAME_DATA, "quic.invalid_frame_data" }, - // The packet contained no payload. - { net::QUIC_MISSING_PAYLOAD, "quic.missing.payload" }, - // FEC data is malformed. - { net::QUIC_INVALID_FEC_DATA, "quic.invalid.fec_data" }, - // STREAM frame data is malformed. - { net::QUIC_INVALID_STREAM_DATA, "quic.invalid.stream_data" }, - // STREAM frame data is not encrypted. - { net::QUIC_UNENCRYPTED_STREAM_DATA, "quic.unencrypted.stream_data" }, - // Attempt to send unencrypted STREAM frame. - { net::QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA, - "quic.attempt.to.unencrypted.stream.data" }, - // Received a frame which is likely the result of memory corruption. - { net::QUIC_MAYBE_CORRUPTED_MEMORY, "quic.maybe.corrupted.momery" }, - // FEC frame data is not encrypted. - { net::QUIC_UNENCRYPTED_FEC_DATA, "quic.unencrypted.fec.data" }, - // RST_STREAM frame data is malformed. - { net::QUIC_INVALID_RST_STREAM_DATA, "quic.invalid.rst_stream_data" }, - // CONNECTION_CLOSE frame data is malformed. - { net::QUIC_INVALID_CONNECTION_CLOSE_DATA, - "quic.invalid.connection_close_data" }, - // GOAWAY frame data is malformed. - { net::QUIC_INVALID_GOAWAY_DATA, "quic.invalid.goaway_data" }, - // WINDOW_UPDATE frame data is malformed. - { net::QUIC_INVALID_WINDOW_UPDATE_DATA, "quic.invalid.window_update_data" }, - // BLOCKED frame data is malformed. - { net::QUIC_INVALID_BLOCKED_DATA, "quic.invalid.blocked_data" }, - // STOP_WAITING frame data is malformed. - { net::QUIC_INVALID_STOP_WAITING_DATA, "quic.invalid.stop_waiting_data" }, - // PATH_CLOSE frame data is malformed. - { net::QUIC_INVALID_PATH_CLOSE_DATA, "quic.invalid_path_close_data" }, - // ACK frame data is malformed. - { net::QUIC_INVALID_ACK_DATA, "quic.invalid.ack_data" }, + // Connection has reached an invalid state. + {net::QUIC_INTERNAL_ERROR, "quic.internal_error"}, + // There were data frames after the a fin or reset. + {net::QUIC_STREAM_DATA_AFTER_TERMINATION, + "quic.stream_data.after_termination"}, + // Control frame is malformed. + {net::QUIC_INVALID_PACKET_HEADER, "quic.invalid.packet_header"}, + // Frame data is malformed. + {net::QUIC_INVALID_FRAME_DATA, "quic.invalid_frame_data"}, + // The packet contained no payload. + {net::QUIC_MISSING_PAYLOAD, "quic.missing.payload"}, + // FEC data is malformed. + {net::QUIC_INVALID_FEC_DATA, "quic.invalid.fec_data"}, + // STREAM frame data is malformed. + {net::QUIC_INVALID_STREAM_DATA, "quic.invalid.stream_data"}, + // STREAM frame data is not encrypted. + {net::QUIC_UNENCRYPTED_STREAM_DATA, "quic.unencrypted.stream_data"}, + // Attempt to send unencrypted STREAM frame. + {net::QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA, + "quic.attempt.to.unencrypted.stream.data"}, + // Received a frame which is likely the result of memory corruption. + {net::QUIC_MAYBE_CORRUPTED_MEMORY, "quic.maybe.corrupted.momery"}, + // FEC frame data is not encrypted. + {net::QUIC_UNENCRYPTED_FEC_DATA, "quic.unencrypted.fec.data"}, + // RST_STREAM frame data is malformed. + {net::QUIC_INVALID_RST_STREAM_DATA, "quic.invalid.rst_stream_data"}, + // CONNECTION_CLOSE frame data is malformed. + {net::QUIC_INVALID_CONNECTION_CLOSE_DATA, + "quic.invalid.connection_close_data"}, + // GOAWAY frame data is malformed. + {net::QUIC_INVALID_GOAWAY_DATA, "quic.invalid.goaway_data"}, + // WINDOW_UPDATE frame data is malformed. + {net::QUIC_INVALID_WINDOW_UPDATE_DATA, "quic.invalid.window_update_data"}, + // BLOCKED frame data is malformed. + {net::QUIC_INVALID_BLOCKED_DATA, "quic.invalid.blocked_data"}, + // STOP_WAITING frame data is malformed. + {net::QUIC_INVALID_STOP_WAITING_DATA, "quic.invalid.stop_waiting_data"}, + // PATH_CLOSE frame data is malformed. + {net::QUIC_INVALID_PATH_CLOSE_DATA, "quic.invalid_path_close_data"}, + // ACK frame data is malformed. + {net::QUIC_INVALID_ACK_DATA, "quic.invalid.ack_data"}, - // Version negotiation packet is malformed. - { net::QUIC_INVALID_VERSION_NEGOTIATION_PACKET, - "quic_invalid_version_negotiation_packet" }, - // Public RST packet is malformed. - { net::QUIC_INVALID_PUBLIC_RST_PACKET, "quic.invalid.public_rst_packet" }, + // Version negotiation packet is malformed. + {net::QUIC_INVALID_VERSION_NEGOTIATION_PACKET, + "quic_invalid_version_negotiation_packet"}, + // Public RST packet is malformed. + {net::QUIC_INVALID_PUBLIC_RST_PACKET, "quic.invalid.public_rst_packet"}, - // There was an error decrypting. - { net::QUIC_DECRYPTION_FAILURE, "quic.decryption.failure" }, - // There was an error encrypting. - { net::QUIC_ENCRYPTION_FAILURE, "quic.encryption.failure" }, - // The packet exceeded kMaxPacketSize. - { net::QUIC_PACKET_TOO_LARGE, "quic.packet.too_large" }, - // The peer is going away. May be a client or server. - { net::QUIC_PEER_GOING_AWAY, "quic.peer_going_away" }, - // A stream ID was invalid. - { net::QUIC_INVALID_STREAM_ID, "quic.invalid_stream_id" }, - // A priority was invalid. - { net::QUIC_INVALID_PRIORITY, "quic.invalid_priority" }, - // Too many streams already open. - { net::QUIC_TOO_MANY_OPEN_STREAMS, "quic.too_many_open_streams" }, - // The peer created too many available streams. - { net::QUIC_TOO_MANY_AVAILABLE_STREAMS, "quic.too_many_available_streams" }, - // Received public reset for this connection. - { net::QUIC_PUBLIC_RESET, "quic.public_reset" }, - // Invalid protocol version. - { net::QUIC_INVALID_VERSION, "quic.invalid_version" }, + // There was an error decrypting. + {net::QUIC_DECRYPTION_FAILURE, "quic.decryption.failure"}, + // There was an error encrypting. + {net::QUIC_ENCRYPTION_FAILURE, "quic.encryption.failure"}, + // The packet exceeded kMaxPacketSize. + {net::QUIC_PACKET_TOO_LARGE, "quic.packet.too_large"}, + // The peer is going away. May be a client or server. + {net::QUIC_PEER_GOING_AWAY, "quic.peer_going_away"}, + // A stream ID was invalid. + {net::QUIC_INVALID_STREAM_ID, "quic.invalid_stream_id"}, + // A priority was invalid. + {net::QUIC_INVALID_PRIORITY, "quic.invalid_priority"}, + // Too many streams already open. + {net::QUIC_TOO_MANY_OPEN_STREAMS, "quic.too_many_open_streams"}, + // The peer created too many available streams. + {net::QUIC_TOO_MANY_AVAILABLE_STREAMS, "quic.too_many_available_streams"}, + // Received public reset for this connection. + {net::QUIC_PUBLIC_RESET, "quic.public_reset"}, + // Invalid protocol version. + {net::QUIC_INVALID_VERSION, "quic.invalid_version"}, - // The Header ID for a stream was too far from the previous. - { net::QUIC_INVALID_HEADER_ID, "quic.invalid_header_id" }, - // Negotiable parameter received during handshake had invalid value. - { net::QUIC_INVALID_NEGOTIATED_VALUE, "quic.invalid_negotiated_value" }, - // There was an error decompressing data. - { net::QUIC_DECOMPRESSION_FAILURE, "quic.decompression_failure" }, - // We hit our prenegotiated (or default) timeout - { net::QUIC_NETWORK_IDLE_TIMEOUT, "quic.connection.idle_time_out" }, - // We hit our overall connection timeout - { net::QUIC_HANDSHAKE_TIMEOUT, - "quic.connection.handshake_timed_out" }, - // There was an error encountered migrating addresses. - { net::QUIC_ERROR_MIGRATING_ADDRESS, "quic.error_migrating_address" }, - // There was an error encountered migrating port only. - { net::QUIC_ERROR_MIGRATING_PORT, "quic.error_migrating_port" }, - // There was an error while writing to the socket. - { net::QUIC_PACKET_WRITE_ERROR, "quic.packet.write_error" }, - // There was an error while reading from the socket. - { net::QUIC_PACKET_READ_ERROR, "quic.packet.read_error" }, - // We received a STREAM_FRAME with no data and no fin flag set. - { net::QUIC_EMPTY_STREAM_FRAME_NO_FIN, "quic.empty_stream_frame_no_fin" }, - // We received invalid data on the headers stream. - { net::QUIC_INVALID_HEADERS_STREAM_DATA, "quic.invalid_headers_stream_data" }, - // The peer received too much data, violating flow control. - { net::QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, - "quic.flow_control.received_too_much_data" }, - // The peer sent too much data, violating flow control. - { net::QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA, - "quic.flow_control.sent_too_much_data" }, - // The peer received an invalid flow control window. - { net::QUIC_FLOW_CONTROL_INVALID_WINDOW, "quic.flow_control.invalid_window" }, - // The connection has been IP pooled into an existing connection. - { net::QUIC_CONNECTION_IP_POOLED, "quic.connection.ip_pooled" }, - // The connection has too many outstanding sent packets. - { net::QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS, - "quic.too_many_outstanding_sent_packets" }, - // The connection has too many outstanding received packets. - { net::QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS, - "quic.too_many_outstanding_received_packets" }, - // The quic connection job to load server config is cancelled. - { net::QUIC_CONNECTION_CANCELLED, "quic.connection.cancelled" }, - // Disabled QUIC because of high packet loss rate. - { net::QUIC_BAD_PACKET_LOSS_RATE, "quic.bad_packet_loss_rate" }, - // Disabled QUIC because of too many PUBLIC_RESETs post handshake. - { net::QUIC_PUBLIC_RESETS_POST_HANDSHAKE, - "quic.public_resets_post_handshake" }, - // Disabled QUIC because of too many timeouts with streams open. - { net::QUIC_TIMEOUTS_WITH_OPEN_STREAMS, "quic.timeouts_with_open_streams" }, - // Closed because we failed to serialize a packet. - { net::QUIC_FAILED_TO_SERIALIZE_PACKET, "quic.failed_to_serialize_packet" }, - // QUIC timed out after too many RTOs. - { net::QUIC_TOO_MANY_RTOS, "quic.too_many_rtos" }, - // Crypto errors. + // The Header ID for a stream was too far from the previous. + {net::QUIC_INVALID_HEADER_ID, "quic.invalid_header_id"}, + // Negotiable parameter received during handshake had invalid value. + {net::QUIC_INVALID_NEGOTIATED_VALUE, "quic.invalid_negotiated_value"}, + // There was an error decompressing data. + {net::QUIC_DECOMPRESSION_FAILURE, "quic.decompression_failure"}, + // We hit our prenegotiated (or default) timeout + {net::QUIC_NETWORK_IDLE_TIMEOUT, "quic.connection.idle_time_out"}, + // We hit our overall connection timeout + {net::QUIC_HANDSHAKE_TIMEOUT, "quic.connection.handshake_timed_out"}, + // There was an error encountered migrating addresses. + {net::QUIC_ERROR_MIGRATING_ADDRESS, "quic.error_migrating_address"}, + // There was an error encountered migrating port only. + {net::QUIC_ERROR_MIGRATING_PORT, "quic.error_migrating_port"}, + // There was an error while writing to the socket. + {net::QUIC_PACKET_WRITE_ERROR, "quic.packet.write_error"}, + // There was an error while reading from the socket. + {net::QUIC_PACKET_READ_ERROR, "quic.packet.read_error"}, + // We received a STREAM_FRAME with no data and no fin flag set. + {net::QUIC_EMPTY_STREAM_FRAME_NO_FIN, "quic.empty_stream_frame_no_fin"}, + // We received invalid data on the headers stream. + {net::QUIC_INVALID_HEADERS_STREAM_DATA, "quic.invalid_headers_stream_data"}, + // The peer received too much data, violating flow control. + {net::QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, + "quic.flow_control.received_too_much_data"}, + // The peer sent too much data, violating flow control. + {net::QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA, + "quic.flow_control.sent_too_much_data"}, + // The peer received an invalid flow control window. + {net::QUIC_FLOW_CONTROL_INVALID_WINDOW, "quic.flow_control.invalid_window"}, + // The connection has been IP pooled into an existing connection. + {net::QUIC_CONNECTION_IP_POOLED, "quic.connection.ip_pooled"}, + // The connection has too many outstanding sent packets. + {net::QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS, + "quic.too_many_outstanding_sent_packets"}, + // The connection has too many outstanding received packets. + {net::QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS, + "quic.too_many_outstanding_received_packets"}, + // The quic connection job to load server config is cancelled. + {net::QUIC_CONNECTION_CANCELLED, "quic.connection.cancelled"}, + // Disabled QUIC because of high packet loss rate. + {net::QUIC_BAD_PACKET_LOSS_RATE, "quic.bad_packet_loss_rate"}, + // Disabled QUIC because of too many PUBLIC_RESETs post handshake. + {net::QUIC_PUBLIC_RESETS_POST_HANDSHAKE, + "quic.public_resets_post_handshake"}, + // Disabled QUIC because of too many timeouts with streams open. + {net::QUIC_TIMEOUTS_WITH_OPEN_STREAMS, "quic.timeouts_with_open_streams"}, + // Closed because we failed to serialize a packet. + {net::QUIC_FAILED_TO_SERIALIZE_PACKET, "quic.failed_to_serialize_packet"}, + // QUIC timed out after too many RTOs. + {net::QUIC_TOO_MANY_RTOS, "quic.too_many_rtos"}, + // Crypto errors. - // Hanshake failed. - { net::QUIC_HANDSHAKE_FAILED, "quic.handshake_failed" }, - // Handshake message contained out of order tags. - { net::QUIC_CRYPTO_TAGS_OUT_OF_ORDER, "quic.crypto.tags_out_of_order" }, - // Handshake message contained too many entries. - { net::QUIC_CRYPTO_TOO_MANY_ENTRIES, "quic.crypto.too_many_entries" }, - // Handshake message contained an invalid value length. - { net::QUIC_CRYPTO_INVALID_VALUE_LENGTH, "quic.crypto.invalid_value_length" }, - // A crypto message was received after the handshake was complete. - { net::QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, - "quic.crypto_message_after_handshake_complete" }, - // A crypto message was received with an illegal message tag. - { net::QUIC_INVALID_CRYPTO_MESSAGE_TYPE, "quic.invalid_crypto_message_type" }, - // A crypto message was received with an illegal parameter. - { net::QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, - "quic.invalid_crypto_message_parameter" }, - // An invalid channel id signature was supplied. - { net::QUIC_INVALID_CHANNEL_ID_SIGNATURE, - "quic.invalid_channel_id_signature" }, - // A crypto message was received with a mandatory parameter missing. - { net::QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, - "quic.crypto_message.parameter_not_found" }, - // A crypto message was received with a parameter that has no overlap - // with the local parameter. - { net::QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP, - "quic.crypto_message.parameter_no_overlap" }, - // A crypto message was received that contained a parameter with too few - // values. - { net::QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND, - "quic_crypto_message_index_not_found" }, - // A demand for an unsupport proof type was received. - { net::QUIC_UNSUPPORTED_PROOF_DEMAND, "quic.unsupported_proof_demand" }, - // An internal error occured in crypto processing. - { net::QUIC_CRYPTO_INTERNAL_ERROR, "quic.crypto.internal_error" }, - // A crypto handshake message specified an unsupported version. - { net::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, - "quic.crypto.version_not_supported" }, - // A crypto handshake message resulted in a stateless reject. - { net::QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, - "quic.crypto.handshake_stateless_reject" }, - // There was no intersection between the crypto primitives supported by the - // peer and ourselves. - { net::QUIC_CRYPTO_NO_SUPPORT, "quic.crypto.no_support" }, - // The server rejected our client hello messages too many times. - { net::QUIC_CRYPTO_TOO_MANY_REJECTS, "quic.crypto.too_many_rejects" }, - // The client rejected the server's certificate chain or signature. - { net::QUIC_PROOF_INVALID, "quic.proof_invalid" }, - // A crypto message was received with a duplicate tag. - { net::QUIC_CRYPTO_DUPLICATE_TAG, "quic.crypto.duplicate_tag" }, - // A crypto message was received with the wrong encryption level (i.e. it - // should have been encrypted but was not.) - { net::QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, - "quic.crypto.encryption_level_incorrect" }, - // The server config for a server has expired. - { net::QUIC_CRYPTO_SERVER_CONFIG_EXPIRED, - "quic.crypto.server_config_expired" }, - // We failed to setup the symmetric keys for a connection. - { net::QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED, - "quic.crypto.symmetric_key_setup_failed" }, - // A handshake message arrived, but we are still validating the - // previous handshake message. - { net::QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO, - "quic.crypto_message_while_validating_client_hello" }, - // A server config update arrived before the handshake is complete. - { net::QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE, - "quic.crypto.update_before_handshake_complete" }, - // CHLO cannot fit in one packet. - { net::QUIC_CRYPTO_CHLO_TOO_LARGE, - "quic.crypto.chlo_too_large" }, - // This connection involved a version negotiation which appears to have been - // tampered with. - { net::QUIC_VERSION_NEGOTIATION_MISMATCH, - "quic.version_negotiation_mismatch" }, + // Hanshake failed. + {net::QUIC_HANDSHAKE_FAILED, "quic.handshake_failed"}, + // Handshake message contained out of order tags. + {net::QUIC_CRYPTO_TAGS_OUT_OF_ORDER, "quic.crypto.tags_out_of_order"}, + // Handshake message contained too many entries. + {net::QUIC_CRYPTO_TOO_MANY_ENTRIES, "quic.crypto.too_many_entries"}, + // Handshake message contained an invalid value length. + {net::QUIC_CRYPTO_INVALID_VALUE_LENGTH, "quic.crypto.invalid_value_length"}, + // A crypto message was received after the handshake was complete. + {net::QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, + "quic.crypto_message_after_handshake_complete"}, + // A crypto message was received with an illegal message tag. + {net::QUIC_INVALID_CRYPTO_MESSAGE_TYPE, "quic.invalid_crypto_message_type"}, + // A crypto message was received with an illegal parameter. + {net::QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, + "quic.invalid_crypto_message_parameter"}, + // An invalid channel id signature was supplied. + {net::QUIC_INVALID_CHANNEL_ID_SIGNATURE, + "quic.invalid_channel_id_signature"}, + // A crypto message was received with a mandatory parameter missing. + {net::QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, + "quic.crypto_message.parameter_not_found"}, + // A crypto message was received with a parameter that has no overlap + // with the local parameter. + {net::QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP, + "quic.crypto_message.parameter_no_overlap"}, + // A crypto message was received that contained a parameter with too few + // values. + {net::QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND, + "quic_crypto_message_index_not_found"}, + // A demand for an unsupport proof type was received. + {net::QUIC_UNSUPPORTED_PROOF_DEMAND, "quic.unsupported_proof_demand"}, + // An internal error occured in crypto processing. + {net::QUIC_CRYPTO_INTERNAL_ERROR, "quic.crypto.internal_error"}, + // A crypto handshake message specified an unsupported version. + {net::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, + "quic.crypto.version_not_supported"}, + // A crypto handshake message resulted in a stateless reject. + {net::QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, + "quic.crypto.handshake_stateless_reject"}, + // There was no intersection between the crypto primitives supported by the + // peer and ourselves. + {net::QUIC_CRYPTO_NO_SUPPORT, "quic.crypto.no_support"}, + // The server rejected our client hello messages too many times. + {net::QUIC_CRYPTO_TOO_MANY_REJECTS, "quic.crypto.too_many_rejects"}, + // The client rejected the server's certificate chain or signature. + {net::QUIC_PROOF_INVALID, "quic.proof_invalid"}, + // A crypto message was received with a duplicate tag. + {net::QUIC_CRYPTO_DUPLICATE_TAG, "quic.crypto.duplicate_tag"}, + // A crypto message was received with the wrong encryption level (i.e. it + // should have been encrypted but was not.) + {net::QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, + "quic.crypto.encryption_level_incorrect"}, + // The server config for a server has expired. + {net::QUIC_CRYPTO_SERVER_CONFIG_EXPIRED, + "quic.crypto.server_config_expired"}, + // We failed to setup the symmetric keys for a connection. + {net::QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED, + "quic.crypto.symmetric_key_setup_failed"}, + // A handshake message arrived, but we are still validating the + // previous handshake message. + {net::QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO, + "quic.crypto_message_while_validating_client_hello"}, + // A server config update arrived before the handshake is complete. + {net::QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE, + "quic.crypto.update_before_handshake_complete"}, + // CHLO cannot fit in one packet. + {net::QUIC_CRYPTO_CHLO_TOO_LARGE, "quic.crypto.chlo_too_large"}, + // This connection involved a version negotiation which appears to have been + // tampered with. + {net::QUIC_VERSION_NEGOTIATION_MISMATCH, + "quic.version_negotiation_mismatch"}, - // Multipath is not enabled, but a packet with multipath flag on is received. - { net::QUIC_BAD_MULTIPATH_FLAG, "quic.bad_multipath_flag" }, - // A path is supposed to exist but does not. - { net::QUIC_MULTIPATH_PATH_DOES_NOT_EXIST, - "quic.quic_multipath_path_does_not_exist" }, - // A path is supposed to be active but is not. - { net::QUIC_MULTIPATH_PATH_NOT_ACTIVE, - "quic.quic_multipath_path_not_active" }, + // Multipath is not enabled, but a packet with multipath flag on is + // received. + {net::QUIC_BAD_MULTIPATH_FLAG, "quic.bad_multipath_flag"}, + // A path is supposed to exist but does not. + {net::QUIC_MULTIPATH_PATH_DOES_NOT_EXIST, + "quic.quic_multipath_path_does_not_exist"}, + // A path is supposed to be active but is not. + {net::QUIC_MULTIPATH_PATH_NOT_ACTIVE, + "quic.quic_multipath_path_not_active"}, - // Network change and connection migration errors. + // Network change and connection migration errors. - // IP address changed causing connection close. - { net::QUIC_IP_ADDRESS_CHANGED, "quic.ip_address_changed" }, - // Network changed, but connection had no migratable streams. - { net::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS, - "quic.connection_migration_no_migratable_streams" }, - // Connection changed networks too many times. - { net::QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES, - "quic.connection_migration_too_many_changes" }, - // Connection migration was attempted, but there was no new network to - // migrate to. - { net::QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK, - "quic.connection_migration_no_new_network" }, - // Network changed, but connection had one or more non-migratable streams. - { net::QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM, - "quic.connection_migration_non_migratable_stream" }, - // Stream frame overlaps with buffered data. - { net::QUIC_OVERLAPPING_STREAM_DATA, - "quic.overlapping_stream_data" }, - // Stream frames arrived too discontiguously so that stream sequencer buffer - // has too many gaps. - { net::QUIC_TOO_MANY_FRAME_GAPS, - "quic.too_many_frame_gaps" }, - // Sequencer buffer get into weird state where continuing read/write - // will lead to crash. - { net::QUIC_STREAM_SEQUENCER_INVALID_STATE, - "quic.stream_sequencer_invalid_state" }, - // Connection closed because of server hits max number of sessions allowed. - { net::QUIC_TOO_MANY_SESSIONS_ON_SERVER, - "quic.too_many_sessions_on_server" }, + // IP address changed causing connection close. + {net::QUIC_IP_ADDRESS_CHANGED, "quic.ip_address_changed"}, + // Network changed, but connection had no migratable streams. + {net::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS, + "quic.connection_migration_no_migratable_streams"}, + // Connection changed networks too many times. + {net::QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES, + "quic.connection_migration_too_many_changes"}, + // Connection migration was attempted, but there was no new network to + // migrate to. + {net::QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK, + "quic.connection_migration_no_new_network"}, + // Network changed, but connection had one or more non-migratable streams. + {net::QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM, + "quic.connection_migration_non_migratable_stream"}, + // Stream frame overlaps with buffered data. + {net::QUIC_OVERLAPPING_STREAM_DATA, "quic.overlapping_stream_data"}, + // Stream frames arrived too discontiguously so that stream sequencer buffer + // has too many gaps. + {net::QUIC_TOO_MANY_FRAME_GAPS, "quic.too_many_frame_gaps"}, + // Sequencer buffer get into weird state where continuing read/write + // will lead to crash. + {net::QUIC_STREAM_SEQUENCER_INVALID_STATE, + "quic.stream_sequencer_invalid_state"}, + // Connection closed because of server hits max number of sessions allowed. + {net::QUIC_TOO_MANY_SESSIONS_ON_SERVER, "quic.too_many_sessions_on_server"}, + // There was an error decompressing data. + {net::QUIC_DECOMPRESSION_FAILURE, "quic.decompression_failure"}, - // No error. Used as bound while iterating. - { net::QUIC_LAST_ERROR, "quic.last_error"} -}; + // No error. Used as bound while iterating. + {net::QUIC_LAST_ERROR, "quic.last_error"}}; // Must be updated any time a net::QuicErrorCode is deprecated in // net/quic/core/quic_packets.h.
diff --git a/components/ntp_snippets/content_suggestion.cc b/components/ntp_snippets/content_suggestion.cc index 3b007a4f..e5cac618 100644 --- a/components/ntp_snippets/content_suggestion.cc +++ b/components/ntp_snippets/content_suggestion.cc
@@ -10,6 +10,9 @@ DownloadSuggestionExtra::DownloadSuggestionExtra() = default; +DownloadSuggestionExtra::DownloadSuggestionExtra( + const DownloadSuggestionExtra& other) = default; + DownloadSuggestionExtra::~DownloadSuggestionExtra() = default; bool ContentSuggestion::ID::operator==(const ID& rhs) const {
diff --git a/components/ntp_snippets/content_suggestion.h b/components/ntp_snippets/content_suggestion.h index ea17274c..b2403f6 100644 --- a/components/ntp_snippets/content_suggestion.h +++ b/components/ntp_snippets/content_suggestion.h
@@ -21,8 +21,11 @@ // download suggestions. struct DownloadSuggestionExtra { DownloadSuggestionExtra(); + DownloadSuggestionExtra(const DownloadSuggestionExtra&); ~DownloadSuggestionExtra(); + // The GUID for the downloaded file. + std::string download_guid; // The file path of the downloaded file once download completes. base::FilePath target_file_path; // The effective MIME type of downloaded content.
diff --git a/components/payments/content/payment_request.h b/components/payments/content/payment_request.h index 8ae228f..4a6507d 100644 --- a/components/payments/content/payment_request.h +++ b/components/payments/content/payment_request.h
@@ -145,6 +145,7 @@ } payments::mojom::PaymentDetails* details() { return details_.get(); } + payments::mojom::PaymentOptions* options() { return options_.get(); } const std::vector<std::string>& supported_card_networks() { return supported_card_networks_; }
diff --git a/components/safe_browsing_db/v4_local_database_manager.cc b/components/safe_browsing_db/v4_local_database_manager.cc index 65c40b2..53c5d8c 100644 --- a/components/safe_browsing_db/v4_local_database_manager.cc +++ b/components/safe_browsing_db/v4_local_database_manager.cc
@@ -111,12 +111,14 @@ const std::vector<GURL>& urls) : client(client), client_callback_type(client_callback_type), - result_threat_type(SB_THREAT_TYPE_SAFE), + most_severe_threat_type(SB_THREAT_TYPE_SAFE), stores_to_check(stores_to_check), urls(urls) { for (const auto& url : urls) { V4ProtocolManagerUtil::UrlToFullHashes(url, &full_hashes); } + DCHECK(full_hashes.size()); + full_hash_threat_types.assign(full_hashes.size(), SB_THREAT_TYPE_SAFE); } V4LocalDatabaseManager::PendingCheck::PendingCheck( @@ -126,9 +128,11 @@ const std::set<FullHash>& full_hashes_set) : client(client), client_callback_type(client_callback_type), - result_threat_type(SB_THREAT_TYPE_SAFE), + most_severe_threat_type(SB_THREAT_TYPE_SAFE), stores_to_check(stores_to_check) { full_hashes.assign(full_hashes_set.begin(), full_hashes_set.end()); + DCHECK(full_hashes.size()); + full_hash_threat_types.assign(full_hashes.size(), SB_THREAT_TYPE_SAFE); } V4LocalDatabaseManager::PendingCheck::~PendingCheck() {} @@ -503,20 +507,25 @@ } void V4LocalDatabaseManager::GetSeverestThreatTypeAndMetadata( - SBThreatType* result_threat_type, + const std::vector<FullHashInfo>& full_hash_infos, + const std::vector<FullHash>& full_hashes, + std::vector<SBThreatType>* full_hash_threat_types, + SBThreatType* most_severe_threat_type, ThreatMetadata* metadata, - FullHash* matching_full_hash, - const std::vector<FullHashInfo>& full_hash_infos) { - DCHECK(result_threat_type); - DCHECK(metadata); - DCHECK(matching_full_hash); - + FullHash* matching_full_hash) { ThreatSeverity most_severe_yet = kLeastSeverity; for (const FullHashInfo& fhi : full_hash_infos) { ThreatSeverity severity = GetThreatSeverity(fhi.list_id); + SBThreatType threat_type = GetSBThreatTypeForList(fhi.list_id); + + const auto& it = + std::find(full_hashes.begin(), full_hashes.end(), fhi.full_hash); + DCHECK(it != full_hashes.end()); + (*full_hash_threat_types)[it - full_hashes.begin()] = threat_type; + if (severity < most_severe_yet) { most_severe_yet = severity; - *result_threat_type = GetSBThreatTypeForList(fhi.list_id); + *most_severe_threat_type = threat_type; *metadata = fhi.metadata; *matching_full_hash = fhi.full_hash; } @@ -612,9 +621,10 @@ } // Find out the most severe threat, if any, to report to the client. - GetSeverestThreatTypeAndMetadata(&check->result_threat_type, - &check->url_metadata, - &check->matching_full_hash, full_hash_infos); + GetSeverestThreatTypeAndMetadata( + full_hash_infos, check->full_hashes, &check->full_hash_threat_types, + &check->most_severe_threat_type, &check->url_metadata, + &check->matching_full_hash); pending_checks_.erase(it); RespondToClient(std::move(check)); } @@ -673,24 +683,31 @@ case ClientCallbackType::CHECK_URL_FOR_SUBRESOURCE_FILTER: DCHECK_EQ(1u, check->urls.size()); check->client->OnCheckBrowseUrlResult( - check->urls[0], check->result_threat_type, check->url_metadata); + check->urls[0], check->most_severe_threat_type, check->url_metadata); break; case ClientCallbackType::CHECK_DOWNLOAD_URLS: check->client->OnCheckDownloadUrlResult(check->urls, - check->result_threat_type); + check->most_severe_threat_type); break; case ClientCallbackType::CHECK_RESOURCE_URL: DCHECK_EQ(1u, check->urls.size()); - check->client->OnCheckResourceUrlResult( - check->urls[0], check->result_threat_type, check->matching_full_hash); + check->client->OnCheckResourceUrlResult(check->urls[0], + check->most_severe_threat_type, + check->matching_full_hash); break; case ClientCallbackType::CHECK_EXTENSION_IDS: { - const std::set<FullHash> extension_ids(check->full_hashes.begin(), - check->full_hashes.end()); - check->client->OnCheckExtensionsResult(extension_ids); + DCHECK_EQ(check->full_hash_threat_types.size(), + check->full_hashes.size()); + std::set<FullHash> unsafe_extension_ids; + for (size_t i = 0; i < check->full_hash_threat_types.size(); i++) { + if (check->full_hash_threat_types[i] == SB_THREAT_TYPE_EXTENSION) { + unsafe_extension_ids.insert(check->full_hashes[i]); + } + } + check->client->OnCheckExtensionsResult(unsafe_extension_ids); break; } case ClientCallbackType::CHECK_OTHER:
diff --git a/components/safe_browsing_db/v4_local_database_manager.h b/components/safe_browsing_db/v4_local_database_manager.h index 4cf8160..e010dee 100644 --- a/components/safe_browsing_db/v4_local_database_manager.h +++ b/components/safe_browsing_db/v4_local_database_manager.h
@@ -134,8 +134,8 @@ // know whether the URL in |url| is safe or unsafe. const ClientCallbackType client_callback_type; - // The threat verdict for the URL being checked. - SBThreatType result_threat_type; + // The most severe threat verdict for the URLs/hashes being checked. + SBThreatType most_severe_threat_type; // When the check was sent to the SafeBrowsing service. Used to record the // time it takes to get the uncached full hashes from the service (or a @@ -149,10 +149,13 @@ // one of |full_hashes| and |urls| should be greater than 0. const std::vector<GURL> urls; - // The full hashes that are being checked for being safe. The size of - // exactly one of |full_hashes| and |urls| should be greater than 0. + // The full hashes that are being checked for being safe. std::vector<FullHash> full_hashes; + // The most severe SBThreatType for each full hash in |full_hashes|. The + // length of |full_hash_threat_type| must always match |full_hashes|. + std::vector<SBThreatType> full_hash_threat_types; + // The metadata associated with the full hash of the severest match found // for that URL. ThreatMetadata url_metadata; @@ -196,13 +199,18 @@ const std::unique_ptr<PendingCheck>& check, FullHashToStoreAndHashPrefixesMap* full_hash_to_store_and_hash_prefixes); - // Finds the most severe |SBThreatType| and the corresponding |metadata|, and - // |matching_full_hash| from |full_hash_infos|. + // Goes over the |full_hash_infos| and stores the most severe SBThreatType in + // |most_severe_threat_type|, the corresponding metadata in |metadata|, and + // the matching full hash in |matching_full_hash|. Also, updates in + // |full_hash_threat_types|, the threat type for each full hash in + // |full_hashes|. void GetSeverestThreatTypeAndMetadata( - SBThreatType* result_threat_type, + const std::vector<FullHashInfo>& full_hash_infos, + const std::vector<FullHash>& full_hashes, + std::vector<SBThreatType>* full_hash_threat_types, + SBThreatType* most_severe_threat_type, ThreatMetadata* metadata, - FullHash* matching_full_hash, - const std::vector<FullHashInfo>& full_hash_infos); + FullHash* matching_full_hash); // Returns the SBThreatType for a given ListIdentifier. SBThreatType GetSBThreatTypeForList(const ListIdentifier& list_id);
diff --git a/components/safe_browsing_db/v4_local_database_manager_unittest.cc b/components/safe_browsing_db/v4_local_database_manager_unittest.cc index e005c18..be6a792 100644 --- a/components/safe_browsing_db/v4_local_database_manager_unittest.cc +++ b/components/safe_browsing_db/v4_local_database_manager_unittest.cc
@@ -191,6 +191,21 @@ V4LocalDatabaseManager* manager_to_cancel_; }; +class TestExtensionClient : public SafeBrowsingDatabaseManager::Client { + public: + TestExtensionClient(const std::set<FullHash>& expected_bad_crxs) + : expected_bad_crxs(expected_bad_crxs), + on_check_extensions_result_called_(false) {} + + void OnCheckExtensionsResult(const std::set<FullHash>& bad_crxs) override { + EXPECT_EQ(expected_bad_crxs, bad_crxs); + on_check_extensions_result_called_ = true; + } + + const std::set<FullHash> expected_bad_crxs; + bool on_check_extensions_result_called_; +}; + class FakeV4LocalDatabaseManager : public V4LocalDatabaseManager { public: void PerformFullHashCheck(std::unique_ptr<PendingCheck> check, @@ -404,32 +419,48 @@ TEST_F(V4LocalDatabaseManagerTest, TestGetSeverestThreatTypeAndMetadata) { WaitForTasksOnTaskRunner(); - FullHash full_hash("Malware"); - FullHashInfo fhi_malware(full_hash, GetUrlMalwareId(), base::Time::Now()); + FullHash fh_malware("Malware"); + FullHashInfo fhi_malware(fh_malware, GetUrlMalwareId(), base::Time::Now()); fhi_malware.metadata.population_id = "malware_popid"; - FullHashInfo fhi_api(FullHash("api"), GetChromeUrlApiId(), base::Time::Now()); + FullHash fh_api("api"); + FullHashInfo fhi_api(fh_api, GetChromeUrlApiId(), base::Time::Now()); fhi_api.metadata.population_id = "api_popid"; + FullHash fh_example("example"); std::vector<FullHashInfo> fhis({fhi_malware, fhi_api}); + std::vector<FullHash> full_hashes({fh_malware, fh_example, fh_api}); + std::vector<SBThreatType> full_hash_threat_types(full_hashes.size(), + SB_THREAT_TYPE_SAFE); SBThreatType result_threat_type; ThreatMetadata metadata; FullHash matching_full_hash; + const std::vector<SBThreatType> expected_full_hash_threat_types( + {SB_THREAT_TYPE_URL_MALWARE, SB_THREAT_TYPE_SAFE, + SB_THREAT_TYPE_API_ABUSE}); + v4_local_database_manager_->GetSeverestThreatTypeAndMetadata( - &result_threat_type, &metadata, &matching_full_hash, fhis); + fhis, full_hashes, &full_hash_threat_types, &result_threat_type, + &metadata, &matching_full_hash); + EXPECT_EQ(expected_full_hash_threat_types, full_hash_threat_types); + EXPECT_EQ(SB_THREAT_TYPE_URL_MALWARE, result_threat_type); EXPECT_EQ("malware_popid", metadata.population_id); - EXPECT_EQ(full_hash, matching_full_hash); + EXPECT_EQ(fh_malware, matching_full_hash); // Reversing the list has no effect. std::reverse(std::begin(fhis), std::end(fhis)); + full_hash_threat_types.assign(full_hashes.size(), SB_THREAT_TYPE_SAFE); + v4_local_database_manager_->GetSeverestThreatTypeAndMetadata( - &result_threat_type, &metadata, &matching_full_hash, fhis); + fhis, full_hashes, &full_hash_threat_types, &result_threat_type, + &metadata, &matching_full_hash); + EXPECT_EQ(expected_full_hash_threat_types, full_hash_threat_types); EXPECT_EQ(SB_THREAT_TYPE_URL_MALWARE, result_threat_type); EXPECT_EQ("malware_popid", metadata.population_id); - EXPECT_EQ(full_hash, matching_full_hash); + EXPECT_EQ(fh_malware, matching_full_hash); } TEST_F(V4LocalDatabaseManagerTest, TestChecksAreQueued) { @@ -801,8 +832,64 @@ EXPECT_TRUE(client.on_check_resource_url_result_called_); } -// TODO(nparker): Add tests for +TEST_F(V4LocalDatabaseManagerTest, TestCheckExtensionIDsNothingBlacklisted) { + // Setup to receive full-hash misses. + ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({})); + + // Reset the database manager so it picks up the replacement protocol manager. + ResetLocalDatabaseManager(); + WaitForTasksOnTaskRunner(); + + // bad_extension_id is in the local DB but the full hash won't match. + const FullHash bad_extension_id("aaaabbbbccccdddd"), + good_extension_id("ddddccccbbbbaaaa"); + + // Put a match in the db that will cause a protocol-manager request. + StoreAndHashPrefixes store_and_hash_prefixes; + store_and_hash_prefixes.emplace_back(GetChromeExtMalwareId(), + bad_extension_id); + ReplaceV4Database(store_and_hash_prefixes, true /* stores_available */); + + const std::set<FullHash> expected_bad_crxs({}); + const std::set<FullHash> extension_ids({good_extension_id, bad_extension_id}); + TestExtensionClient client(expected_bad_crxs); + EXPECT_FALSE( + v4_local_database_manager_->CheckExtensionIDs(extension_ids, &client)); + EXPECT_FALSE(client.on_check_extensions_result_called_); + WaitForTasksOnTaskRunner(); + EXPECT_TRUE(client.on_check_extensions_result_called_); +} + +TEST_F(V4LocalDatabaseManagerTest, TestCheckExtensionIDsOneIsBlacklisted) { + // bad_extension_id is in the local DB and the full hash will match. + const FullHash bad_extension_id("aaaabbbbccccdddd"), + good_extension_id("ddddccccbbbbaaaa"); + FullHashInfo fhi(bad_extension_id, GetChromeExtMalwareId(), base::Time()); + + // Setup to receive full-hash hit. + ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({fhi})); + + // Reset the database manager so it picks up the replacement protocol manager. + ResetLocalDatabaseManager(); + WaitForTasksOnTaskRunner(); + + // Put a match in the db that will cause a protocol-manager request. + StoreAndHashPrefixes store_and_hash_prefixes; + store_and_hash_prefixes.emplace_back(GetChromeExtMalwareId(), + bad_extension_id); + ReplaceV4Database(store_and_hash_prefixes, true /* stores_available */); + + const std::set<FullHash> expected_bad_crxs({bad_extension_id}); + const std::set<FullHash> extension_ids({good_extension_id, bad_extension_id}); + TestExtensionClient client(expected_bad_crxs); + EXPECT_FALSE( + v4_local_database_manager_->CheckExtensionIDs(extension_ids, &client)); + EXPECT_FALSE(client.on_check_extensions_result_called_); + WaitForTasksOnTaskRunner(); + EXPECT_TRUE(client.on_check_extensions_result_called_); +} + +// TODO(vakh): By 03/15/2017: Add tests for // CheckDownloadUrl() -// CheckExtensionIDs() } // namespace safe_browsing
diff --git a/components/signin/OWNERS b/components/signin/OWNERS index b3c8286..11e357e 100644 --- a/components/signin/OWNERS +++ b/components/signin/OWNERS
@@ -1,2 +1,4 @@ msarda@chromium.org rogerta@chromium.org + +# COMPONENT: Services>SignIn
diff --git a/components/sync_bookmarks/bookmark_model_associator.cc b/components/sync_bookmarks/bookmark_model_associator.cc index 2305bb1..8376ee04 100644 --- a/components/sync_bookmarks/bookmark_model_associator.cc +++ b/components/sync_bookmarks/bookmark_model_associator.cc
@@ -94,7 +94,7 @@ // Maps bookmark node titles to instances, duplicates allowed. // Titles are converted to the sync internal format before // being used as keys for the map. - using BookmarkNodeMap = base::hash_multimap<std::string, const BookmarkNode*>; + using BookmarkNodeMap = std::multimap<std::string, const BookmarkNode*>; using BookmarkNodeRange = std::pair<BookmarkNodeMap::iterator, BookmarkNodeMap::iterator>;
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index d1982fd4..6a325553 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -718,6 +718,8 @@ "host_zoom_map_impl.h", "host_zoom_map_observer.cc", "host_zoom_map_observer.h", + "image_capture/image_capture_impl.cc", + "image_capture/image_capture_impl.h", "indexed_db/cursor_impl.cc", "indexed_db/cursor_impl.h", "indexed_db/database_impl.cc", @@ -892,8 +894,6 @@ "media/capture/audio_mirroring_manager.h", "media/capture/desktop_capture_device_uma_types.cc", "media/capture/desktop_capture_device_uma_types.h", - "media/capture/image_capture_impl.cc", - "media/capture/image_capture_impl.h", "media/capture/web_contents_audio_input_stream.cc", "media/capture/web_contents_audio_input_stream.h", "media/capture/web_contents_audio_muter.cc",
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 191cc57..1762d79 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -277,6 +277,8 @@ LOG(ERROR) << message; } else if (strstr(message, "Could not obtain desktop path or name")) { LOG(ERROR) << message; + } else if (strstr(message, "Theme parsing error")) { + LOG(ERROR) << message; } else { LOG(DFATAL) << log_domain << ": " << message; }
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc index 014e75e..bf41fac 100644 --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -6048,13 +6048,13 @@ static_cast<WebContentsImpl*>(shell()->web_contents()); FrameTreeNode* root = web_contents->GetFrameTree()->root(); - // Navigate to a simple page and then perform an in-page navigation. + // Navigate to a simple page and then perform a fragment change navigation. GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html")); EXPECT_TRUE(NavigateToURL(shell(), start_url)); - GURL same_page_url( + GURL fragment_change_url( embedded_test_server()->GetURL("a.com", "/title1.html#foo")); - EXPECT_TRUE(NavigateToURL(shell(), same_page_url)); + EXPECT_TRUE(NavigateToURL(shell(), fragment_change_url)); EXPECT_EQ(2, web_contents->GetController().GetEntryCount()); // Replace the URL of the current NavigationEntry with one that will cause @@ -6082,8 +6082,8 @@ // classified as SAME_PAGE) was leaving the FrameNavigationEntry with the // same document sequence number as the previous entry but updates the URL. // Doing a back session history navigation now will cause the browser to - // consider it as in-page because of this matching document sequence number - // and lead to a mismatch of origin and URL in the renderer process. + // consider it as same document because of this matching document sequence + // number and lead to a mismatch of origin and URL in the renderer process. { TestNavigationObserver observer(web_contents); web_contents->GetController().GoBack(); @@ -6151,26 +6151,27 @@ }; // Test which simulates a race condition between a cross-origin, same-process -// navigation and a same page session history navigation. When such a race +// navigation and a same document session history navigation. When such a race // occurs, the renderer will commit the cross-origin navigation, updating its // version of the current document sequence number, and will send an IPC to the // browser process. The session history navigation comes after the commit for // the cross-origin navigation and updates the URL, but not the origin of the // document. This results in mismatch between the two and causes the renderer // process to be killed. See https://crbug.com/630103. -IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, - RaceCrossOriginNavigationAndSamePageHistoryNavigation) { +IN_PROC_BROWSER_TEST_F( + NavigationControllerBrowserTest, + RaceCrossOriginNavigationAndSameDocumentHistoryNavigation) { WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(shell()->web_contents()); FrameTreeNode* root = web_contents->GetFrameTree()->root(); - // Navigate to a simple page and then perform an in-page navigation. + // Navigate to a simple page and then perform a same document navigation. GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html")); EXPECT_TRUE(NavigateToURL(shell(), start_url)); - GURL same_page_url( + GURL same_document_url( embedded_test_server()->GetURL("a.com", "/title1.html#foo")); - EXPECT_TRUE(NavigateToURL(shell(), same_page_url)); + EXPECT_TRUE(NavigateToURL(shell(), same_document_url)); EXPECT_EQ(2, web_contents->GetController().GetEntryCount()); // Create a GoBackAndCommitFilter, which will delay the commit IPC for a @@ -6214,7 +6215,7 @@ EXPECT_TRUE(ExecuteScriptAndExtractString( web_contents, "domAutomationController.send(document.origin)", &origin)); - EXPECT_EQ(same_page_url.GetOrigin().spec(), origin + "/"); + EXPECT_EQ(same_document_url.GetOrigin().spec(), origin + "/"); } else { // Wait for the back navigation to commit as well. history_commit_observer.Wait(); @@ -6676,10 +6677,10 @@ bool was_renderer_initiated_; }; -// Test that a same-page navigation does not lead to the deletion of the -// NavigationHandle for an ongoing different page navigation. +// Test that a same document navigation does not lead to the deletion of the +// NavigationHandle for an ongoing different document navigation. IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, - SamePageNavigationDoesntDeleteNavigationHandle) { + SameDocumentNavigationDoesntDeleteNavigationHandle) { const GURL kURL1 = embedded_test_server()->GetURL("/title1.html"); const GURL kPushStateURL = embedded_test_server()->GetURL("/title1.html#fragment"); @@ -6749,10 +6750,10 @@ } -// Tests that a same-page browser-initiated navigation is properly reported by -// the NavigationHandle. +// Tests that a same document browser-initiated navigation is properly reported +// by the NavigationHandle. IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, - SamePageBrowserInitiated) { + SameDocumentBrowserInitiated) { const GURL kURL = embedded_test_server()->GetURL("/title1.html"); const GURL kFragmentURL = embedded_test_server()->GetURL("/title1.html#fragment");
diff --git a/content/browser/image_capture/OWNERS b/content/browser/image_capture/OWNERS new file mode 100644 index 0000000..d9e863e --- /dev/null +++ b/content/browser/image_capture/OWNERS
@@ -0,0 +1,4 @@ +mcasas@chromium.org +miu@chromium.org + +# COMPONENT: Blink>ImageCapture
diff --git a/content/browser/media/capture/image_capture_impl.cc b/content/browser/image_capture/image_capture_impl.cc similarity index 98% rename from content/browser/media/capture/image_capture_impl.cc rename to content/browser/image_capture/image_capture_impl.cc index 5c1c7e1..3ce15a8 100644 --- a/content/browser/media/capture/image_capture_impl.cc +++ b/content/browser/image_capture/image_capture_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/media/capture/image_capture_impl.h" +#include "content/browser/image_capture/image_capture_impl.h" #include <utility>
diff --git a/content/browser/media/capture/image_capture_impl.h b/content/browser/image_capture/image_capture_impl.h similarity index 83% rename from content/browser/media/capture/image_capture_impl.h rename to content/browser/image_capture/image_capture_impl.h index a4b3cf4..7ea8c320 100644 --- a/content/browser/media/capture/image_capture_impl.h +++ b/content/browser/image_capture/image_capture_impl.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_IMAGE_CAPTURE_IMPL_H_ -#define CONTENT_BROWSER_MEDIA_CAPTURE_IMAGE_CAPTURE_IMPL_H_ +#ifndef CONTENT_BROWSER_IMAGE_CAPTURE_IMAGE_CAPTURE_IMPL_H_ +#define CONTENT_BROWSER_IMAGE_CAPTURE_IMAGE_CAPTURE_IMPL_H_ #include "media/capture/mojo/image_capture.mojom.h" @@ -32,4 +32,4 @@ } // namespace content -#endif // CONTENT_BROWSER_MEDIA_CAPTURE_IMAGE_CAPTURE_IMPL_H_ +#endif // CONTENT_BROWSER_IMAGE_CAPTURE_IMAGE_CAPTURE_IMPL_H_
diff --git a/content/browser/media/session/media_session_service_impl_browsertest.cc b/content/browser/media/session/media_session_service_impl_browsertest.cc index cfbdef1..90d4375 100644 --- a/content/browser/media/session/media_session_service_impl_browsertest.cc +++ b/content/browser/media/session/media_session_service_impl_browsertest.cc
@@ -175,17 +175,17 @@ } IN_PROC_BROWSER_TEST_F(MediaSessionServiceImplBrowserTest, - DontResetServiceForSamePageNavigation) { + DontResetServiceForSameDocumentNavigation) { NavigateToURL(shell(), GetTestUrl(".", "title1.html")); EnsurePlayer(); EXPECT_TRUE(ExecuteScriptToSetUpMediaSessionSync()); - // Start a same-page navigation and check the playback state, metadata, + // Start a fragment navigation and check the playback state, metadata, // actions are not reset. - GURL same_page_url = GetTestUrl(".", "title1.html"); - same_page_url = GURL(same_page_url.spec() + "#some-anchor"); - NavigateToURLAndWaitForFinish(shell(), same_page_url); + GURL fragment_change_url = GetTestUrl(".", "title1.html"); + fragment_change_url = GURL(fragment_change_url.spec() + "#some-anchor"); + NavigateToURLAndWaitForFinish(shell(), fragment_change_url); EXPECT_EQ(blink::mojom::MediaSessionPlaybackState::PLAYING, GetService()->playback_state());
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc index bec9b52..085fd44 100644 --- a/content/browser/renderer_host/delegated_frame_host.cc +++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -68,7 +68,7 @@ void DelegatedFrameHost::WasShown(const ui::LatencyInfo& latency_info) { delegated_frame_evictor_->SetVisible(true); - if (!local_surface_id_.is_valid() && !released_front_lock_.get()) { + if (!has_frame_ && !released_front_lock_.get()) { if (compositor_) released_front_lock_ = compositor_->GetCompositorLock(); } @@ -225,7 +225,7 @@ const gfx::Point& point, RenderWidgetHostViewBase* target_view, gfx::Point* transformed_point) { - if (!local_surface_id_.is_valid()) + if (!has_frame_) return false; return target_view->TransformPointToLocalCoordSpace( @@ -261,7 +261,7 @@ } void DelegatedFrameHost::UpdateGutters() { - if (!local_surface_id_.is_valid()) { + if (!has_frame_) { right_gutter_.reset(); bottom_gutter_.reset(); return; @@ -366,8 +366,7 @@ // To avoid unnecessary browser composites, try to go directly to the Surface // rather than through the Layer (which goes through the browser compositor). - if (local_surface_id_.is_valid() && - request_copy_of_output_callback_for_testing_.is_null()) { + if (has_frame_ && request_copy_of_output_callback_for_testing_.is_null()) { support_->RequestCopyOfSurface(std::move(request)); } else { RequestCopyOfOutput(std::move(request)); @@ -426,7 +425,7 @@ // resources from the old one with resources from the new one which would // have the same id. Changing the layer to showing painted content destroys // the DelegatedRendererLayer. - EvictDelegatedFrame(); + local_surface_id_ = cc::LocalSurfaceId(); ResetCompositorFrameSinkSupport(); CreateCompositorFrameSinkSupport(); last_compositor_frame_sink_id_ = compositor_frame_sink_id; @@ -455,7 +454,7 @@ support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)); - if (allocated_new_local_surface_id) { + if (allocated_new_local_surface_id || !has_frame_) { // manager must outlive compositors using it. cc::SurfaceId surface_id(frame_sink_id_, local_surface_id_); cc::SurfaceInfo surface_info(surface_id, frame_device_scale_factor, @@ -465,6 +464,8 @@ current_surface_size_ = frame_size; current_scale_factor_ = frame_device_scale_factor; } + + has_frame_ = true; } released_front_lock_ = NULL; current_frame_size_in_dip_ = frame_size_in_dip; @@ -480,7 +481,7 @@ if (compositor_) can_lock_compositor_ = NO_PENDING_COMMIT; - if (local_surface_id_.is_valid()) { + if (has_frame_) { delegated_frame_evictor_->SwappedFrame( client_->DelegatedFrameHostIsVisible()); } @@ -488,8 +489,7 @@ } void DelegatedFrameHost::ClearDelegatedFrame() { - if (local_surface_id_.is_valid()) - EvictDelegatedFrame(); + EvictDelegatedFrame(); } void DelegatedFrameHost::DidReceiveCompositorFrameAck() { @@ -520,11 +520,11 @@ } void DelegatedFrameHost::EvictDelegatedFrame() { + if (!has_frame_) + return; client_->DelegatedFrameHostGetLayer()->SetShowSolidColorContent(); - if (local_surface_id_.is_valid()) { - support_->EvictFrame(); - local_surface_id_ = cc::LocalSurfaceId(); - } + support_->EvictFrame(); + has_frame_ = false; delegated_frame_evictor_->DiscardedFrame(); UpdateGutters(); } @@ -747,8 +747,7 @@ // DelegatedFrameHost, ImageTransportFactoryObserver implementation: void DelegatedFrameHost::OnLostResources() { - if (local_surface_id_.is_valid()) - EvictDelegatedFrame(); + EvictDelegatedFrame(); idle_frame_subscriber_textures_.clear(); yuv_readback_pipeline_.reset(); }
diff --git a/content/browser/renderer_host/delegated_frame_host.h b/content/browser/renderer_host/delegated_frame_host.h index 01f4f65..0cba4c4 100644 --- a/content/browser/renderer_host/delegated_frame_host.h +++ b/content/browser/renderer_host/delegated_frame_host.h
@@ -178,9 +178,7 @@ return cc::SurfaceId(frame_sink_id_, local_surface_id_); } - const cc::LocalSurfaceId& LocalSurfaceIdForTesting() const { - return local_surface_id_; - } + bool HasFrameForTesting() const { return has_frame_; } void OnCompositingDidCommitForTesting(ui::Compositor* compositor) { OnCompositingDidCommit(compositor); @@ -339,6 +337,8 @@ bool needs_begin_frame_ = false; + bool has_frame_ = false; + std::unique_ptr<DelegatedFrameEvictor> delegated_frame_evictor_; };
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index b1a238d..b5e0205c 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -78,13 +78,13 @@ #include "content/browser/gpu/gpu_process_host.h" #include "content/browser/gpu/shader_cache_factory.h" #include "content/browser/histogram_message_filter.h" +#include "content/browser/image_capture/image_capture_impl.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/browser/indexed_db/indexed_db_dispatcher_host.h" #include "content/browser/loader/resource_message_filter.h" #include "content/browser/loader/resource_scheduler_filter.h" #include "content/browser/loader/url_loader_factory_impl.h" #include "content/browser/media/capture/audio_mirroring_manager.h" -#include "content/browser/media/capture/image_capture_impl.h" #include "content/browser/media/media_internals.h" #include "content/browser/media/midi_host.h" #include "content/browser/memory/memory_coordinator_impl.h"
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index 8b36a472..60cb689 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -421,12 +421,10 @@ return GetDelegatedFrameHost()->SurfaceIdForTesting(); } - const cc::LocalSurfaceId& GetLocalSurfaceId() const { - return GetDelegatedFrameHost()->LocalSurfaceIdForTesting(); + bool HasFrameData() const { + return GetDelegatedFrameHost()->HasFrameForTesting(); } - bool HasFrameData() const { return GetLocalSurfaceId().is_valid(); } - bool released_front_lock_active() const { return GetDelegatedFrameHost()->ReleasedFrontLockActiveForTesting(); }
diff --git a/content/browser/zygote_host/zygote_host_impl_linux.cc b/content/browser/zygote_host/zygote_host_impl_linux.cc index e333809..73ad92f 100644 --- a/content/browser/zygote_host/zygote_host_impl_linux.cc +++ b/content/browser/zygote_host/zygote_host_impl_linux.cc
@@ -244,38 +244,40 @@ base::FileEnumerator en(kSelinuxPath, false, base::FileEnumerator::FILES); bool has_selinux_files = !en.Next().empty(); - selinux = access(kSelinuxPath.value().c_str(), X_OK) == 0 && - has_selinux_files; + selinux = + has_selinux_files && access(kSelinuxPath.value().c_str(), X_OK) == 0; selinux_valid = true; } - if (use_suid_sandbox_for_adj_oom_score_ && !selinux) { - // If heap profiling is running, these processes are not exiting, at least - // on ChromeOS. The easiest thing to do is not launch them when profiling. - // TODO(stevenjb): Investigate further and fix. - if (base::allocator::IsHeapProfilerRunning()) - return; - - std::vector<std::string> adj_oom_score_cmdline; - adj_oom_score_cmdline.push_back(sandbox_binary_); - adj_oom_score_cmdline.push_back(sandbox::kAdjustOOMScoreSwitch); - adj_oom_score_cmdline.push_back(base::Int64ToString(pid)); - adj_oom_score_cmdline.push_back(base::IntToString(score)); - - base::Process sandbox_helper_process; - base::LaunchOptions options; - - // sandbox_helper_process is a setuid binary. - options.allow_new_privs = true; - - sandbox_helper_process = - base::LaunchProcess(adj_oom_score_cmdline, options); - if (sandbox_helper_process.IsValid()) - base::EnsureProcessGetsReaped(sandbox_helper_process.Pid()); - } else if (!use_suid_sandbox_for_adj_oom_score_) { + if (!use_suid_sandbox_for_adj_oom_score_) { if (!base::AdjustOOMScore(pid, score)) PLOG(ERROR) << "Failed to adjust OOM score of renderer with pid " << pid; + return; } + + if (selinux) + return; + + // If heap profiling is running, these processes are not exiting, at least + // on ChromeOS. The easiest thing to do is not launch them when profiling. + // TODO(stevenjb): Investigate further and fix. + if (base::allocator::IsHeapProfilerRunning()) + return; + + std::vector<std::string> adj_oom_score_cmdline; + adj_oom_score_cmdline.push_back(sandbox_binary_); + adj_oom_score_cmdline.push_back(sandbox::kAdjustOOMScoreSwitch); + adj_oom_score_cmdline.push_back(base::Int64ToString(pid)); + adj_oom_score_cmdline.push_back(base::IntToString(score)); + + // sandbox_helper_process is a setuid binary. + base::LaunchOptions options; + options.allow_new_privs = true; + + base::Process sandbox_helper_process = + base::LaunchProcess(adj_oom_score_cmdline, options); + if (sandbox_helper_process.IsValid()) + base::EnsureProcessGetsReaped(sandbox_helper_process.Pid()); } #endif
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/BrowserStartupControllerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/BrowserStartupControllerTest.java index c1276c8c3..43ef2d67d 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/BrowserStartupControllerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/BrowserStartupControllerTest.java
@@ -4,19 +4,25 @@ package org.chromium.content.browser; +import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; -import android.test.InstrumentationTestCase; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; import org.chromium.base.ThreadUtils; import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.LoaderErrors; import org.chromium.base.library_loader.ProcessInitException; +import org.chromium.base.test.BaseJUnit4ClassRunner; /** * Test of BrowserStartupController */ -public class BrowserStartupControllerTest extends InstrumentationTestCase { - +@RunWith(BaseJUnit4ClassRunner.class) +public class BrowserStartupControllerTest { private TestBrowserStartupController mController; private static class TestBrowserStartupController extends BrowserStartupController { @@ -84,9 +90,8 @@ } } - @Override - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { mController = new TestBrowserStartupController(); // Setting the static singleton instance field enables more correct testing, since it is // is possible to call {@link BrowserStartupController#browserStartupComplete(int)} instead @@ -94,6 +99,7 @@ BrowserStartupController.overrideInstanceForTest(mController); } + @Test @SmallTest public void testSingleAsynchronousStartupRequest() { mController.mStartupResult = BrowserStartupController.STARTUP_SUCCESS; @@ -107,25 +113,27 @@ try { mController.startBrowserProcessesAsync(true, callback); } catch (Exception e) { - fail("Browser should have started successfully"); + Assert.fail("Browser should have started successfully"); } } }); - assertTrue("Asynchronous mode should have been set.", + Assert.assertTrue("Asynchronous mode should have been set.", BrowserStartupController.browserMayStartAsynchonously()); - assertEquals("The browser process should have been initialized one time.", 1, + Assert.assertEquals("The browser process should have been initialized one time.", 1, mController.initializedCounter()); // Wait for callbacks to complete. - getInstrumentation().waitForIdleSync(); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - assertTrue("Callback should have been executed.", callback.mHasStartupResult); - assertTrue("Callback should have been a success.", callback.mWasSuccess); - assertFalse("Callback should be told that the browser process was not already started.", + Assert.assertTrue("Callback should have been executed.", callback.mHasStartupResult); + Assert.assertTrue("Callback should have been a success.", callback.mWasSuccess); + Assert.assertFalse( + "Callback should be told that the browser process was not already started.", callback.mAlreadyStarted); } + @Test @SmallTest public void testMultipleAsynchronousStartupRequests() { mController.mStartupResult = BrowserStartupController.STARTUP_SUCCESS; @@ -141,7 +149,7 @@ try { mController.startBrowserProcessesAsync(true, callback1); } catch (Exception e) { - fail("Browser should have started successfully"); + Assert.fail("Browser should have started successfully"); } } }); @@ -151,7 +159,7 @@ try { mController.startBrowserProcessesAsync(true, callback2); } catch (Exception e) { - fail("Browser should have started successfully"); + Assert.fail("Browser should have started successfully"); } } }); @@ -162,26 +170,28 @@ } }); - assertTrue("Asynchronous mode should have been set.", + Assert.assertTrue("Asynchronous mode should have been set.", BrowserStartupController.browserMayStartAsynchonously()); - assertEquals("The browser process should have been initialized one time.", 1, + Assert.assertEquals("The browser process should have been initialized one time.", 1, mController.initializedCounter()); // Wait for callbacks to complete. - getInstrumentation().waitForIdleSync(); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - assertTrue("Callback 1 should have been executed.", callback1.mHasStartupResult); - assertTrue("Callback 1 should have been a success.", callback1.mWasSuccess); - assertTrue("Callback 2 should have been executed.", callback2.mHasStartupResult); - assertTrue("Callback 2 should have been a success.", callback2.mWasSuccess); - assertTrue("Callback 3 should have been executed.", callback3.mHasStartupResult); - assertTrue("Callback 3 should have been a success.", callback3.mWasSuccess); + Assert.assertTrue("Callback 1 should have been executed.", callback1.mHasStartupResult); + Assert.assertTrue("Callback 1 should have been a success.", callback1.mWasSuccess); + Assert.assertTrue("Callback 2 should have been executed.", callback2.mHasStartupResult); + Assert.assertTrue("Callback 2 should have been a success.", callback2.mWasSuccess); + Assert.assertTrue("Callback 3 should have been executed.", callback3.mHasStartupResult); + Assert.assertTrue("Callback 3 should have been a success.", callback3.mWasSuccess); // Some startup tasks might have been enqueued after the browser process was started, but // not the first one which kicked of the startup. - assertFalse("Callback 1 should be told that the browser process was not already started.", + Assert.assertFalse( + "Callback 1 should be told that the browser process was not already started.", callback1.mAlreadyStarted); } + @Test @SmallTest public void testConsecutiveAsynchronousStartupRequests() { mController.mStartupResult = BrowserStartupController.STARTUP_SUCCESS; @@ -196,7 +206,7 @@ try { mController.startBrowserProcessesAsync(true, callback1); } catch (Exception e) { - fail("Browser should have started successfully"); + Assert.fail("Browser should have started successfully"); } } }); @@ -207,18 +217,18 @@ } }); - assertTrue("Asynchronous mode should have been set.", + Assert.assertTrue("Asynchronous mode should have been set.", BrowserStartupController.browserMayStartAsynchonously()); - assertEquals("The browser process should have been initialized one time.", 1, + Assert.assertEquals("The browser process should have been initialized one time.", 1, mController.initializedCounter()); // Wait for callbacks to complete. - getInstrumentation().waitForIdleSync(); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - assertTrue("Callback 1 should have been executed.", callback1.mHasStartupResult); - assertTrue("Callback 1 should have been a success.", callback1.mWasSuccess); - assertTrue("Callback 2 should have been executed.", callback2.mHasStartupResult); - assertTrue("Callback 2 should have been a success.", callback2.mWasSuccess); + Assert.assertTrue("Callback 1 should have been executed.", callback1.mHasStartupResult); + Assert.assertTrue("Callback 1 should have been a success.", callback1.mWasSuccess); + Assert.assertTrue("Callback 2 should have been executed.", callback2.mHasStartupResult); + Assert.assertTrue("Callback 2 should have been a success.", callback2.mWasSuccess); final TestStartupCallback callback3 = new TestStartupCallback(); final TestStartupCallback callback4 = new TestStartupCallback(); @@ -230,7 +240,7 @@ try { mController.startBrowserProcessesAsync(true, callback3); } catch (Exception e) { - fail("Browser should have started successfully"); + Assert.fail("Browser should have started successfully"); } } }); @@ -242,18 +252,19 @@ }); // Wait for callbacks to complete. - getInstrumentation().waitForIdleSync(); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - assertTrue("Callback 3 should have been executed.", callback3.mHasStartupResult); - assertTrue("Callback 3 should have been a success.", callback3.mWasSuccess); - assertTrue("Callback 3 should be told that the browser process was already started.", + Assert.assertTrue("Callback 3 should have been executed.", callback3.mHasStartupResult); + Assert.assertTrue("Callback 3 should have been a success.", callback3.mWasSuccess); + Assert.assertTrue("Callback 3 should be told that the browser process was already started.", callback3.mAlreadyStarted); - assertTrue("Callback 4 should have been executed.", callback4.mHasStartupResult); - assertTrue("Callback 4 should have been a success.", callback4.mWasSuccess); - assertTrue("Callback 4 should be told that the browser process was already started.", + Assert.assertTrue("Callback 4 should have been executed.", callback4.mHasStartupResult); + Assert.assertTrue("Callback 4 should have been a success.", callback4.mWasSuccess); + Assert.assertTrue("Callback 4 should be told that the browser process was already started.", callback4.mAlreadyStarted); } + @Test @SmallTest public void testSingleFailedAsynchronousStartupRequest() { mController.mStartupResult = BrowserStartupController.STARTUP_FAILURE; @@ -267,23 +278,24 @@ try { mController.startBrowserProcessesAsync(true, callback); } catch (Exception e) { - fail("Browser should have started successfully"); + Assert.fail("Browser should have started successfully"); } } }); - assertTrue("Asynchronous mode should have been set.", + Assert.assertTrue("Asynchronous mode should have been set.", BrowserStartupController.browserMayStartAsynchonously()); - assertEquals("The browser process should have been initialized one time.", 1, + Assert.assertEquals("The browser process should have been initialized one time.", 1, mController.initializedCounter()); // Wait for callbacks to complete. - getInstrumentation().waitForIdleSync(); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - assertTrue("Callback should have been executed.", callback.mHasStartupResult); - assertTrue("Callback should have been a failure.", callback.mWasFailure); + Assert.assertTrue("Callback should have been executed.", callback.mHasStartupResult); + Assert.assertTrue("Callback should have been a failure.", callback.mWasFailure); } + @Test @SmallTest public void testConsecutiveFailedAsynchronousStartupRequests() { mController.mStartupResult = BrowserStartupController.STARTUP_FAILURE; @@ -298,7 +310,7 @@ try { mController.startBrowserProcessesAsync(true, callback1); } catch (Exception e) { - fail("Browser should have started successfully"); + Assert.fail("Browser should have started successfully"); } } }); @@ -309,18 +321,18 @@ } }); - assertTrue("Asynchronous mode should have been set.", + Assert.assertTrue("Asynchronous mode should have been set.", BrowserStartupController.browserMayStartAsynchonously()); - assertEquals("The browser process should have been initialized one time.", 1, + Assert.assertEquals("The browser process should have been initialized one time.", 1, mController.initializedCounter()); // Wait for callbacks to complete. - getInstrumentation().waitForIdleSync(); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - assertTrue("Callback 1 should have been executed.", callback1.mHasStartupResult); - assertTrue("Callback 1 should have been a failure.", callback1.mWasFailure); - assertTrue("Callback 2 should have been executed.", callback2.mHasStartupResult); - assertTrue("Callback 2 should have been a failure.", callback2.mWasFailure); + Assert.assertTrue("Callback 1 should have been executed.", callback1.mHasStartupResult); + Assert.assertTrue("Callback 1 should have been a failure.", callback1.mWasFailure); + Assert.assertTrue("Callback 2 should have been executed.", callback2.mHasStartupResult); + Assert.assertTrue("Callback 2 should have been a failure.", callback2.mWasFailure); final TestStartupCallback callback3 = new TestStartupCallback(); final TestStartupCallback callback4 = new TestStartupCallback(); @@ -332,7 +344,7 @@ try { mController.startBrowserProcessesAsync(true, callback3); } catch (Exception e) { - fail("Browser should have started successfully"); + Assert.fail("Browser should have started successfully"); } } }); @@ -344,14 +356,15 @@ }); // Wait for callbacks to complete. - getInstrumentation().waitForIdleSync(); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - assertTrue("Callback 3 should have been executed.", callback3.mHasStartupResult); - assertTrue("Callback 3 should have been a failure.", callback3.mWasFailure); - assertTrue("Callback 4 should have been executed.", callback4.mHasStartupResult); - assertTrue("Callback 4 should have been a failure.", callback4.mWasFailure); + Assert.assertTrue("Callback 3 should have been executed.", callback3.mHasStartupResult); + Assert.assertTrue("Callback 3 should have been a failure.", callback3.mWasFailure); + Assert.assertTrue("Callback 4 should have been executed.", callback4.mHasStartupResult); + Assert.assertTrue("Callback 4 should have been a failure.", callback4.mWasFailure); } + @Test @SmallTest public void testSingleSynchronousRequest() { mController.mStartupResult = BrowserStartupController.STARTUP_SUCCESS; @@ -363,17 +376,18 @@ try { mController.startBrowserProcessesSync(false); } catch (Exception e) { - fail("Browser should have started successfully"); + Assert.fail("Browser should have started successfully"); } } }); - assertFalse("Synchronous mode should have been set", + Assert.assertFalse("Synchronous mode should have been set", BrowserStartupController.browserMayStartAsynchonously()); - assertEquals("The browser process should have been initialized one time.", 1, + Assert.assertEquals("The browser process should have been initialized one time.", 1, mController.initializedCounter()); } + @Test @SmallTest public void testAsyncThenSyncRequests() { mController.mStartupResult = BrowserStartupController.STARTUP_SUCCESS; @@ -387,7 +401,7 @@ try { mController.startBrowserProcessesAsync(true, callback); } catch (Exception e) { - fail("Browser should have started successfully"); + Assert.fail("Browser should have started successfully"); } // To ensure that the async startup doesn't complete too soon we have // to do both these in a since Runnable instance. This avoids the @@ -395,22 +409,24 @@ try { mController.startBrowserProcessesSync(false); } catch (Exception e) { - fail("Browser should have started successfully"); + Assert.fail("Browser should have started successfully"); } } }); - assertFalse("Synchronous mode should have been set", + Assert.assertFalse("Synchronous mode should have been set", BrowserStartupController.browserMayStartAsynchonously()); - assertEquals("The browser process should have been initialized twice.", 2, + Assert.assertEquals("The browser process should have been initialized twice.", 2, mController.initializedCounter()); - assertTrue("Callback should have been executed.", callback.mHasStartupResult); - assertTrue("Callback should have been a success.", callback.mWasSuccess); - assertFalse("Callback should be told that the browser process was not already started.", + Assert.assertTrue("Callback should have been executed.", callback.mHasStartupResult); + Assert.assertTrue("Callback should have been a success.", callback.mWasSuccess); + Assert.assertFalse( + "Callback should be told that the browser process was not already started.", callback.mAlreadyStarted); } + @Test @SmallTest public void testSyncThenAsyncRequests() { mController.mStartupResult = BrowserStartupController.STARTUP_SUCCESS; @@ -424,15 +440,15 @@ try { mController.startBrowserProcessesSync(false); } catch (Exception e) { - fail("Browser should have started successfully"); + Assert.fail("Browser should have started successfully"); } } }); - assertEquals("The browser process should have been initialized once.", 1, + Assert.assertEquals("The browser process should have been initialized once.", 1, mController.initializedCounter()); - assertFalse("Synchronous mode should have been set", + Assert.assertFalse("Synchronous mode should have been set", BrowserStartupController.browserMayStartAsynchonously()); // Kick off the asynchronous startup request. This should just queue the callback. @@ -442,23 +458,24 @@ try { mController.startBrowserProcessesAsync(true, callback); } catch (Exception e) { - fail("Browser should have started successfully"); + Assert.fail("Browser should have started successfully"); } } }); - assertEquals("The browser process should not have been initialized a second time.", 1, - mController.initializedCounter()); + Assert.assertEquals("The browser process should not have been initialized a second time.", + 1, mController.initializedCounter()); // Wait for callbacks to complete. - getInstrumentation().waitForIdleSync(); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - assertTrue("Callback should have been executed.", callback.mHasStartupResult); - assertTrue("Callback should have been a success.", callback.mWasSuccess); - assertTrue("Callback should be told that the browser process was already started.", + Assert.assertTrue("Callback should have been executed.", callback.mHasStartupResult); + Assert.assertTrue("Callback should have been a success.", callback.mWasSuccess); + Assert.assertTrue("Callback should be told that the browser process was already started.", callback.mAlreadyStarted); } + @Test @SmallTest public void testLibraryLoadFails() { mController.mLibraryLoadSucceeds = false; @@ -470,18 +487,18 @@ public void run() { try { mController.startBrowserProcessesAsync(true, callback); - fail("Browser should not have started successfully"); + Assert.fail("Browser should not have started successfully"); } catch (Exception e) { // Exception expected, ignore. } } }); - assertEquals("The browser process should not have been initialized.", 0, + Assert.assertEquals("The browser process should not have been initialized.", 0, mController.initializedCounter()); // Wait for callbacks to complete. - getInstrumentation().waitForIdleSync(); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentCommandLineTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentCommandLineTest.java index a6575931..6b2aae8 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentCommandLineTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentCommandLineTest.java
@@ -6,16 +6,27 @@ import android.support.test.filters.MediumTest; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.chromium.base.CommandLine; import org.chromium.base.annotations.SuppressFBWarnings; +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; -import org.chromium.content.browser.test.NativeLibraryTestBase; +import org.chromium.content.browser.test.NativeLibraryTestRule; import org.chromium.content_shell_apk.ContentShellApplication; /** * Test class for command lines. */ -public class ContentCommandLineTest extends NativeLibraryTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class ContentCommandLineTest { + @Rule + public NativeLibraryTestRule mActivityTestRule = new NativeLibraryTestRule(); + // A reference command line. Note that switch2 is [brea\d], switch3 is [and "butter"], // and switch4 is [a "quoted" 'food'!] static final String INIT_SWITCHES[] = { "init_command", "--switch", "Arg", @@ -33,65 +44,65 @@ static final String CL_ADDED_SWITCH_2 = "username"; static final String CL_ADDED_VALUE_2 = "bozo"; - @Override + @Before public void setUp() throws Exception { - super.setUp(); CommandLine.reset(); } void loadJni() { - assertFalse(CommandLine.getInstance().isNativeImplementation()); - loadNativeLibraryNoBrowserProcess(); - assertTrue(CommandLine.getInstance().isNativeImplementation()); + Assert.assertFalse(CommandLine.getInstance().isNativeImplementation()); + mActivityTestRule.loadNativeLibraryNoBrowserProcess(); + Assert.assertTrue(CommandLine.getInstance().isNativeImplementation()); } void checkInitSwitches() { CommandLine cl = CommandLine.getInstance(); - assertFalse(cl.hasSwitch("init_command")); - assertTrue(cl.hasSwitch("switch")); - assertFalse(cl.hasSwitch("--switch")); - assertFalse(cl.hasSwitch("arg")); - assertFalse(cl.hasSwitch("actually_an_arg")); - assertEquals("brea\\d", cl.getSwitchValue("switch2")); - assertEquals("and \"butter\"", cl.getSwitchValue("switch3")); - assertEquals("a \"quoted\" 'food'!", cl.getSwitchValue("switch4")); - assertNull(cl.getSwitchValue("switch")); - assertNull(cl.getSwitchValue("non-existant")); + Assert.assertFalse(cl.hasSwitch("init_command")); + Assert.assertTrue(cl.hasSwitch("switch")); + Assert.assertFalse(cl.hasSwitch("--switch")); + Assert.assertFalse(cl.hasSwitch("arg")); + Assert.assertFalse(cl.hasSwitch("actually_an_arg")); + Assert.assertEquals("brea\\d", cl.getSwitchValue("switch2")); + Assert.assertEquals("and \"butter\"", cl.getSwitchValue("switch3")); + Assert.assertEquals("a \"quoted\" 'food'!", cl.getSwitchValue("switch4")); + Assert.assertNull(cl.getSwitchValue("switch")); + Assert.assertNull(cl.getSwitchValue("non-existant")); } void checkSettingThenGetting() { CommandLine cl = CommandLine.getInstance(); // Add a plain switch. - assertFalse(cl.hasSwitch(CL_ADDED_SWITCH)); + Assert.assertFalse(cl.hasSwitch(CL_ADDED_SWITCH)); cl.appendSwitch(CL_ADDED_SWITCH); - assertTrue(cl.hasSwitch(CL_ADDED_SWITCH)); + Assert.assertTrue(cl.hasSwitch(CL_ADDED_SWITCH)); // Add a switch paired with a value. - assertFalse(cl.hasSwitch(CL_ADDED_SWITCH_2)); - assertNull(cl.getSwitchValue(CL_ADDED_SWITCH_2)); + Assert.assertFalse(cl.hasSwitch(CL_ADDED_SWITCH_2)); + Assert.assertNull(cl.getSwitchValue(CL_ADDED_SWITCH_2)); cl.appendSwitchWithValue(CL_ADDED_SWITCH_2, CL_ADDED_VALUE_2); - assertTrue(CL_ADDED_VALUE_2.equals(cl.getSwitchValue(CL_ADDED_SWITCH_2))); + Assert.assertTrue(CL_ADDED_VALUE_2.equals(cl.getSwitchValue(CL_ADDED_SWITCH_2))); // Append a few new things. final String switchesAndArgs[] = { "dummy", "--superfast", "--speed=turbo" }; - assertFalse(cl.hasSwitch("dummy")); - assertFalse(cl.hasSwitch("superfast")); - assertNull(cl.getSwitchValue("speed")); + Assert.assertFalse(cl.hasSwitch("dummy")); + Assert.assertFalse(cl.hasSwitch("superfast")); + Assert.assertNull(cl.getSwitchValue("speed")); cl.appendSwitchesAndArguments(switchesAndArgs); - assertFalse(cl.hasSwitch("dummy")); - assertFalse(cl.hasSwitch("command")); - assertTrue(cl.hasSwitch("superfast")); - assertTrue("turbo".equals(cl.getSwitchValue("speed"))); + Assert.assertFalse(cl.hasSwitch("dummy")); + Assert.assertFalse(cl.hasSwitch("command")); + Assert.assertTrue(cl.hasSwitch("superfast")); + Assert.assertTrue("turbo".equals(cl.getSwitchValue("speed"))); } void checkAppendedSwitchesPassedThrough() { CommandLine cl = CommandLine.getInstance(); - assertTrue(cl.hasSwitch(CL_ADDED_SWITCH)); - assertTrue(cl.hasSwitch(CL_ADDED_SWITCH_2)); - assertTrue(CL_ADDED_VALUE_2.equals(cl.getSwitchValue(CL_ADDED_SWITCH_2))); + Assert.assertTrue(cl.hasSwitch(CL_ADDED_SWITCH)); + Assert.assertTrue(cl.hasSwitch(CL_ADDED_SWITCH_2)); + Assert.assertTrue(CL_ADDED_VALUE_2.equals(cl.getSwitchValue(CL_ADDED_SWITCH_2))); } + @Test @MediumTest @Feature({"Android-AppBase"}) public void testJavaNativeTransition() { @@ -102,6 +113,7 @@ checkSettingThenGetting(); } + @Test @MediumTest @Feature({"Android-AppBase"}) public void testJavaNativeTransitionAfterAppends() { @@ -113,6 +125,7 @@ checkAppendedSwitchesPassedThrough(); } + @Test @MediumTest @Feature({"Android-AppBase"}) public void testNativeInitialization() { @@ -126,6 +139,7 @@ checkSettingThenGetting(); } + @Test @SuppressFBWarnings("DMI_HARDCODED_ABSOLUTE_FILENAME") @MediumTest @Feature({"Android-AppBase"})
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewLocationTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewLocationTest.java index 319e77df..172c989 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewLocationTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewLocationTest.java
@@ -4,15 +4,24 @@ package org.chromium.content.browser; +import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; import org.chromium.content.browser.test.util.TestCallbackHelperContainer; import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper; import org.chromium.content_public.browser.LoadUrlParams; -import org.chromium.content_shell_apk.ContentShellTestBase; +import org.chromium.content_shell_apk.ContentShellActivityTestRule; import org.chromium.device.geolocation.LocationProviderFactory; import org.chromium.device.geolocation.MockLocationProvider; @@ -23,44 +32,48 @@ * with ContentView APIs - e.g. that it's started and stopped as the * ContentView is hidden or shown. */ -public class ContentViewLocationTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class ContentViewLocationTest { + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); private TestCallbackHelperContainer mTestCallbackHelperContainer; private TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper mJavascriptHelper; private MockLocationProvider mMockLocationProvider; private void hideContentViewOnUiThread() { - getInstrumentation().runOnMainSync(new Runnable() { - @Override - public void run() { - getContentViewCore().onHide(); - } + InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { + @Override + public void run() { + mActivityTestRule.getContentViewCore().onHide(); + } }); } private void showContentViewOnUiThread() { - getInstrumentation().runOnMainSync(new Runnable() { - @Override - public void run() { - getContentViewCore().onShow(); - } + InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { + @Override + public void run() { + mActivityTestRule.getContentViewCore().onShow(); + } }); } private void pollForPositionCallback() throws Throwable { - mJavascriptHelper.evaluateJavaScriptForTests(getWebContents(), - "positionCount = 0"); + mJavascriptHelper.evaluateJavaScriptForTests( + mActivityTestRule.getWebContents(), "positionCount = 0"); mJavascriptHelper.waitUntilHasValue(); - assertEquals(0, Integer.parseInt(mJavascriptHelper.getJsonResultAndClear())); + Assert.assertEquals(0, Integer.parseInt(mJavascriptHelper.getJsonResultAndClear())); CriteriaHelper.pollInstrumentationThread(new Criteria() { @Override public boolean isSatisfied() { - mJavascriptHelper.evaluateJavaScriptForTests(getWebContents(), "positionCount"); + mJavascriptHelper.evaluateJavaScriptForTests( + mActivityTestRule.getWebContents(), "positionCount"); try { mJavascriptHelper.waitUntilHasValue(); } catch (Exception e) { - fail(); + Assert.fail(); } return Integer.parseInt(mJavascriptHelper.getJsonResultAndClear()) > 0; } @@ -68,8 +81,8 @@ } private void startGeolocationWatchPosition() throws Throwable { - mJavascriptHelper.evaluateJavaScriptForTests(getWebContents(), - "initiate_watchPosition();"); + mJavascriptHelper.evaluateJavaScriptForTests( + mActivityTestRule.getWebContents(), "initiate_watchPosition();"); mJavascriptHelper.waitUntilHasValue(); } @@ -82,35 +95,34 @@ })); } - @Override - protected void setUp() throws Exception { - super.setUp(); - + @Before + public void setUp() throws Exception { mMockLocationProvider = new MockLocationProvider(); LocationProviderFactory.setLocationProviderImpl(mMockLocationProvider); try { - startActivityWithTestUrl("content/test/data/android/geolocation.html"); + mActivityTestRule.launchContentShellWithUrlSync( + "content/test/data/android/geolocation.html"); } catch (Throwable t) { - fail(); + Assert.fail(); } - mTestCallbackHelperContainer = new TestCallbackHelperContainer(getContentViewCore()); + mTestCallbackHelperContainer = + new TestCallbackHelperContainer(mActivityTestRule.getContentViewCore()); mJavascriptHelper = new OnEvaluateJavaScriptResultHelper(); ensureGeolocationRunning(false); } - @Override - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { mMockLocationProvider.stopUpdates(); - super.tearDown(); } + @Test @MediumTest @Feature({"Location"}) public void testWatchHideShowStop() throws Throwable { - startGeolocationWatchPosition(); pollForPositionCallback(); ensureGeolocationRunning(true); @@ -119,8 +131,8 @@ hideContentViewOnUiThread(); ensureGeolocationRunning(false); - mJavascriptHelper.evaluateJavaScriptForTests(getWebContents(), - "positionCount = 0"); + mJavascriptHelper.evaluateJavaScriptForTests( + mActivityTestRule.getWebContents(), "positionCount = 0"); mJavascriptHelper.waitUntilHasValue(); // Show the ContentView again and ensure that geolocation starts again. @@ -129,11 +141,13 @@ ensureGeolocationRunning(true); // Navigate away and ensure that geolocation stops. - loadUrl(getContentViewCore().getWebContents().getNavigationController(), + mActivityTestRule.loadUrl( + mActivityTestRule.getContentViewCore().getWebContents().getNavigationController(), mTestCallbackHelperContainer, new LoadUrlParams("about:blank")); ensureGeolocationRunning(false); } + @Test @MediumTest @Feature({"Location"}) public void testHideWatchResume() throws Throwable { @@ -146,6 +160,7 @@ ensureGeolocationRunning(true); } + @Test @MediumTest @Feature({"Location"}) public void testWatchHideNewWatchShow() throws Throwable { @@ -165,6 +180,7 @@ ensureGeolocationRunning(true); } + @Test @MediumTest @Feature({"Location"}) public void testHideWatchStopShow() throws Throwable { @@ -172,7 +188,8 @@ startGeolocationWatchPosition(); ensureGeolocationRunning(false); - loadUrl(getContentViewCore().getWebContents().getNavigationController(), + mActivityTestRule.loadUrl( + mActivityTestRule.getContentViewCore().getWebContents().getNavigationController(), mTestCallbackHelperContainer, new LoadUrlParams("about:blank")); showContentViewOnUiThread(); ensureGeolocationRunning(false);
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewPopupZoomerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewPopupZoomerTest.java index a2ad3824..a2cef5c 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewPopupZoomerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewPopupZoomerTest.java
@@ -4,26 +4,36 @@ package org.chromium.content.browser; +import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.base.test.util.UrlUtils; import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; import org.chromium.content.browser.test.util.DOMUtils; -import org.chromium.content_shell_apk.ContentShellTestBase; +import org.chromium.content_shell_apk.ContentShellActivityTestRule; import java.util.concurrent.TimeoutException; /** * Class which provides test coverage for Popup Zoomer. */ +@RunWith(BaseJUnit4ClassRunner.class) @RetryOnFailure -public class ContentViewPopupZoomerTest extends ContentShellTestBase { +public class ContentViewPopupZoomerTest { + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); + private static PopupZoomer findPopupZoomer(ViewGroup view) { assert view != null; for (int i = 0; i < view.getChildCount(); i++) { @@ -85,13 +95,14 @@ /** * Tests that shows a zoomer popup and makes sure it has valid dimensions. */ + @Test @MediumTest @Feature({"Browser"}) public void testPopupZoomerShowsUp() throws InterruptedException, TimeoutException { - launchContentShellWithUrl(generateTestUrl(100, 15, "clickme")); - waitForActiveShellToBeDoneLoading(); + mActivityTestRule.launchContentShellWithUrl(generateTestUrl(100, 15, "clickme")); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); - final ContentViewCore viewCore = getContentViewCore(); + final ContentViewCore viewCore = mActivityTestRule.getContentViewCore(); final ViewGroup view = viewCore.getContainerView(); // The popup should be hidden before the click. @@ -108,20 +119,21 @@ /** * Tests Popup zoomer hides when device back key is pressed. */ + @Test @MediumTest @Feature({"Browser"}) @RetryOnFailure public void testBackKeyDismissesPopupZoomer() throws InterruptedException, TimeoutException { - launchContentShellWithUrl(generateTestUrl(100, 15, "clickme")); - waitForActiveShellToBeDoneLoading(); + mActivityTestRule.launchContentShellWithUrl(generateTestUrl(100, 15, "clickme")); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); - final ContentViewCore viewCore = getContentViewCore(); + final ContentViewCore viewCore = mActivityTestRule.getContentViewCore(); final ViewGroup view = viewCore.getContainerView(); CriteriaHelper.pollInstrumentationThread(new PopupShowingCriteria(view, false)); DOMUtils.clickNode(viewCore, "clickme"); CriteriaHelper.pollInstrumentationThread(new PopupShowingCriteria(view, true)); - sendKeys(KeyEvent.KEYCODE_BACK); + InstrumentationRegistry.getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK); // When device key is pressed, popup zoomer should hide if already showing. CriteriaHelper.pollInstrumentationThread(new PopupShowingCriteria(view, false)); }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewZoomingTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewZoomingTest.java index 0b54c26..d6a824d 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewZoomingTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewZoomingTest.java
@@ -9,16 +9,26 @@ import android.view.InputDevice; import android.view.MotionEvent; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.UrlUtils; import org.chromium.content.browser.input.AnimationIntervalProvider; import org.chromium.content.browser.input.JoystickZoomProvider; -import org.chromium.content_shell_apk.ContentShellTestBase; +import org.chromium.content_shell_apk.ContentShellActivityTestRule; /** * Tests that ContentView running inside ContentShell can be zoomed using gamepad joystick. */ -public class ContentViewZoomingTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class ContentViewZoomingTest { + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); + private static final String LARGE_PAGE = UrlUtils.encodeHtmlDataUri("<html><head>" + "<meta name=\"viewport\" content=\"width=device-width, " + "initial-scale=2.0, minimum-scale=2.0, maximum-scale=5.0\" />" @@ -48,7 +58,7 @@ public void animateZoomTest(final MotionEvent joystickZoomEvent, final long animationTicks) throws Throwable { - runTestOnUiThread(new Runnable() { + mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { onMotion(joystickZoomEvent); @@ -77,67 +87,68 @@ return joystickMotionEvent; } - @Override - protected void setUp() throws Exception { - super.setUp(); - launchContentShellWithUrl(LARGE_PAGE); - waitForActiveShellToBeDoneLoading(); - assertWaitForPageScaleFactorMatch(2.0f); + @Before + public void setUp() throws Exception { + mActivityTestRule.launchContentShellWithUrl(LARGE_PAGE); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); + mActivityTestRule.assertWaitForPageScaleFactorMatch(2.0f); } + @Test @SmallTest @Feature({"JoystickZoom"}) public void testJoystickZoomIn() throws Throwable { MotionEvent rTriggerEvent; AnimationIntervalProvider intervalProvider = new TestAnimationIntervalProvider(); - TestJoystickZoomProvider rtJoystickZoomProvider = - new TestJoystickZoomProvider(getContentViewCore(), intervalProvider); + TestJoystickZoomProvider rtJoystickZoomProvider = new TestJoystickZoomProvider( + mActivityTestRule.getContentViewCore(), intervalProvider); // Verify page does not zoom-in if trigger motion falls in deadzone. rTriggerEvent = simulateJoystickEvent(0.1f, true); rtJoystickZoomProvider.animateZoomTest(rTriggerEvent, 20); - assertWaitForPageScaleFactorMatch(2.0f); + mActivityTestRule.assertWaitForPageScaleFactorMatch(2.0f); rTriggerEvent = simulateJoystickEvent(0.3f, true); rtJoystickZoomProvider.animateZoomTest(rTriggerEvent, 20); - assertWaitForPageScaleFactorMatch(2.2018466f); + mActivityTestRule.assertWaitForPageScaleFactorMatch(2.2018466f); rTriggerEvent = simulateJoystickEvent(0.5f, true); rtJoystickZoomProvider.animateZoomTest(rTriggerEvent, 40); - assertWaitForPageScaleFactorMatch(3.033731f); + mActivityTestRule.assertWaitForPageScaleFactorMatch(3.033731f); rTriggerEvent = simulateJoystickEvent(0.75f, true); rtJoystickZoomProvider.animateZoomTest(rTriggerEvent, 50); - assertWaitForPageScaleFactorMatch(5.0f); + mActivityTestRule.assertWaitForPageScaleFactorMatch(5.0f); } + @Test @SmallTest @Feature({"JoystickZoom"}) public void testJoystickZoomOut() throws Throwable { MotionEvent lTriggerEvent; AnimationIntervalProvider intervalProvider = new TestAnimationIntervalProvider(); - TestJoystickZoomProvider ltJoystickZoomProvider = - new TestJoystickZoomProvider(getContentViewCore(), intervalProvider); + TestJoystickZoomProvider ltJoystickZoomProvider = new TestJoystickZoomProvider( + mActivityTestRule.getContentViewCore(), intervalProvider); // Zoom page to max size. lTriggerEvent = simulateJoystickEvent(1.0f, true); ltJoystickZoomProvider.animateZoomTest(lTriggerEvent, 60); - assertWaitForPageScaleFactorMatch(5.0f); + mActivityTestRule.assertWaitForPageScaleFactorMatch(5.0f); // Verify page does not zoom-out if trigger motion falls in deadzone. lTriggerEvent = simulateJoystickEvent(0.1f, false); ltJoystickZoomProvider.animateZoomTest(lTriggerEvent, 20); - assertWaitForPageScaleFactorMatch(5.0f); + mActivityTestRule.assertWaitForPageScaleFactorMatch(5.0f); lTriggerEvent = simulateJoystickEvent(0.3f, false); ltJoystickZoomProvider.animateZoomTest(lTriggerEvent, 40); - assertWaitForPageScaleFactorMatch(4.125306f); + mActivityTestRule.assertWaitForPageScaleFactorMatch(4.125306f); lTriggerEvent = simulateJoystickEvent(0.5f, false); ltJoystickZoomProvider.animateZoomTest(lTriggerEvent, 50); - assertWaitForPageScaleFactorMatch(2.7635581f); + mActivityTestRule.assertWaitForPageScaleFactorMatch(2.7635581f); lTriggerEvent = simulateJoystickEvent(0.75f, false); ltJoystickZoomProvider.animateZoomTest(lTriggerEvent, 60); - assertWaitForPageScaleFactorMatch(2.0f); + mActivityTestRule.assertWaitForPageScaleFactorMatch(2.0f); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/EncodeHtmlDataUriTest.java b/content/public/android/javatests/src/org/chromium/content/browser/EncodeHtmlDataUriTest.java index 42805f7..a07a8e1 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/EncodeHtmlDataUriTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/EncodeHtmlDataUriTest.java
@@ -5,19 +5,24 @@ package org.chromium.content.browser; import android.support.test.filters.SmallTest; -import android.test.InstrumentationTestCase; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.UrlUtils; import java.net.URI; import java.net.URLDecoder; -public class EncodeHtmlDataUriTest extends InstrumentationTestCase { +@RunWith(BaseJUnit4ClassRunner.class) +public class EncodeHtmlDataUriTest { private static final String DATA_URI_PREFIX = "data:text/html;utf-8,"; private String getData(String dataUri) { - assertNotNull("Data URI is null", dataUri); - assertTrue("Incorrect HTML Data URI prefix", dataUri.startsWith(DATA_URI_PREFIX)); + Assert.assertNotNull("Data URI is null", dataUri); + Assert.assertTrue("Incorrect HTML Data URI prefix", dataUri.startsWith(DATA_URI_PREFIX)); return dataUri.substring(DATA_URI_PREFIX.length()); } @@ -26,30 +31,35 @@ return URLDecoder.decode(data, "UTF-8"); } + @Test @SmallTest public void testDelimitersEncoding() throws java.io.UnsupportedEncodingException { String testString = "><#%\"'"; String encodedUri = UrlUtils.encodeHtmlDataUri(testString); String decodedUri = decode(encodedUri); - assertEquals("Delimiters are not properly encoded", decodedUri, testString); + Assert.assertEquals("Delimiters are not properly encoded", decodedUri, testString); } + @Test @SmallTest public void testUnwiseCharactersEncoding() throws java.io.UnsupportedEncodingException { String testString = "{}|\\^[]`"; String encodedUri = UrlUtils.encodeHtmlDataUri(testString); String decodedUri = decode(encodedUri); - assertEquals("Unwise characters are not properly encoded", decodedUri, testString); + Assert.assertEquals("Unwise characters are not properly encoded", decodedUri, testString); } + @Test @SmallTest public void testWhitespaceEncoding() throws java.io.UnsupportedEncodingException { String testString = " \n\t"; String encodedUri = UrlUtils.encodeHtmlDataUri(testString); String decodedUri = decode(encodedUri); - assertEquals("Whitespace characters are not properly encoded", decodedUri, testString); + Assert.assertEquals( + "Whitespace characters are not properly encoded", decodedUri, testString); } + @Test @SmallTest public void testReturnsValidUri() throws java.net.URISyntaxException, java.io.UnsupportedEncodingException { @@ -59,6 +69,6 @@ // Verify that the encoded URI is valid. new URI(encodedUri); // Verify that something sensible was encoded. - assertEquals("Simple HTML is not properly encoded", decodedUri, testString); + Assert.assertEquals("Simple HTML is not properly encoded", decodedUri, testString); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorResetTest.java b/content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorResetTest.java index 497299d..31c50fc3 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorResetTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorResetTest.java
@@ -6,10 +6,16 @@ import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; +import android.support.test.InstrumentationRegistry; import android.support.test.filters.LargeTest; import junit.framework.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.base.test.util.UrlUtils; @@ -19,7 +25,7 @@ import org.chromium.content.browser.test.util.TestCallbackHelperContainer; import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnPageFinishedHelper; import org.chromium.content_public.browser.LoadUrlParams; -import org.chromium.content_shell_apk.ContentShellTestBase; +import org.chromium.content_shell_apk.ContentShellActivityTestRule; import java.util.concurrent.TimeUnit; @@ -27,7 +33,11 @@ * Provides test environment for Gesture Detector Reset for Content Shell. * This is a helper class for Content Shell tests. */ -public class GestureDetectorResetTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class GestureDetectorResetTest { + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); + private static final long WAIT_TIMEOUT_SECONDS = scaleTimeout(2); private static final String CLICK_TEST_URL = UrlUtils.encodeHtmlDataUri("<html><body>" + "<button id=\"button\" " @@ -90,16 +100,17 @@ * Tests that showing a select popup and having the page reload while the popup is showing does * not assert. */ + @Test @LargeTest @Feature({"Browser"}) @RetryOnFailure public void testSeparateClicksAreRegisteredOnReload() throws InterruptedException, Exception, Throwable { // Load the test page. - launchContentShellWithUrl(CLICK_TEST_URL); - waitForActiveShellToBeDoneLoading(); + mActivityTestRule.launchContentShellWithUrl(CLICK_TEST_URL); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); - final ContentViewCore viewCore = getContentViewCore(); + final ContentViewCore viewCore = mActivityTestRule.getContentViewCore(); final TestCallbackHelperContainer viewClient = new TestCallbackHelperContainer(viewCore); final OnPageFinishedHelper onPageFinishedHelper = @@ -110,10 +121,10 @@ // Reload the test page. int currentCallCount = onPageFinishedHelper.getCallCount(); - getInstrumentation().runOnMainSync(new Runnable() { + InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() { - getActivity().getActiveShell().loadUrl(CLICK_TEST_URL); + mActivityTestRule.getActivity().getActiveShell().loadUrl(CLICK_TEST_URL); } }); onPageFinishedHelper.waitForCallback(currentCallCount, 1, @@ -124,12 +135,15 @@ // Directly navigate to the test page. currentCallCount = onPageFinishedHelper.getCallCount(); - getInstrumentation().runOnMainSync(new Runnable() { + InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() { - getActivity().getActiveShell().getContentViewCore().getWebContents() - .getNavigationController().loadUrl( - new LoadUrlParams(CLICK_TEST_URL)); + mActivityTestRule.getActivity() + .getActiveShell() + .getContentViewCore() + .getWebContents() + .getNavigationController() + .loadUrl(new LoadUrlParams(CLICK_TEST_URL)); } }); onPageFinishedHelper.waitForCallback(currentCallCount, 1,
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ImportantFileWriterAndroidTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ImportantFileWriterAndroidTest.java index 5efe0c7e7..2398c37 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ImportantFileWriterAndroidTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ImportantFileWriterAndroidTest.java
@@ -4,11 +4,19 @@ package org.chromium.content.browser; +import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.chromium.base.ImportantFileWriterAndroid; +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; -import org.chromium.content.browser.test.NativeLibraryTestBase; +import org.chromium.content.browser.test.NativeLibraryTestRule; import java.io.DataInputStream; import java.io.File; @@ -23,62 +31,62 @@ * work, so is not attempting to test that writes are atomic. Instead it is just * testing that the Java code is calling the native code correctly. */ -public class ImportantFileWriterAndroidTest extends NativeLibraryTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class ImportantFileWriterAndroidTest { + @Rule + public NativeLibraryTestRule mActivityTestRule = new NativeLibraryTestRule(); private void checkFile(File testFile, byte[] data) { - assertTrue(testFile.exists()); + Assert.assertTrue(testFile.exists()); try { byte[] fileData = new byte[(int) testFile.length()]; DataInputStream dis = new DataInputStream(new FileInputStream(testFile)); dis.readFully(fileData); dis.close(); - assertEquals("Data length wrong", data.length, fileData.length); + Assert.assertEquals("Data length wrong", data.length, fileData.length); for (int i = 0; i < data.length; i++) { - assertEquals("Data byte wrong", data[i], fileData[i]); + Assert.assertEquals("Data byte wrong", data[i], fileData[i]); } } catch (IOException e) { - fail("Failed to read file"); + Assert.fail("Failed to read file"); } } + @Test @SmallTest @Feature({"Android-AppBase"}) public void testAtomicWrite() { // Try writing a file that can't be created. byte[] data1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - assertFalse("Writing bad file succeded", - ImportantFileWriterAndroid.writeFileAtomically( - "/junk/junk", data1)); - File dir = getInstrumentation().getTargetContext().getFilesDir(); + Assert.assertFalse("Writing bad file succeded", + ImportantFileWriterAndroid.writeFileAtomically("/junk/junk", data1)); + File dir = InstrumentationRegistry.getInstrumentation().getTargetContext().getFilesDir(); File testFile = new File(dir, "ImportantFileTest"); // Make sure the file doesn't already exist if (testFile.exists()) { - assertTrue(testFile.delete()); + Assert.assertTrue(testFile.delete()); } // Write a new file - assertTrue("Writing new file failed", - ImportantFileWriterAndroid.writeFileAtomically( - testFile.getAbsolutePath(), data1)); + Assert.assertTrue("Writing new file failed", + ImportantFileWriterAndroid.writeFileAtomically(testFile.getAbsolutePath(), data1)); checkFile(testFile, data1); byte[] data2 = {10, 20, 30, 40, 50, 60, 70, 80}; // Overwrite an existing file - assertTrue("Writing exiting file failed", - ImportantFileWriterAndroid.writeFileAtomically( - testFile.getAbsolutePath(), data2)); + Assert.assertTrue("Writing exiting file failed", + ImportantFileWriterAndroid.writeFileAtomically(testFile.getAbsolutePath(), data2)); checkFile(testFile, data2); // Done, tidy up - assertTrue(testFile.delete()); + Assert.assertTrue(testFile.delete()); } - @Override + @Before public void setUp() throws Exception { - super.setUp(); - loadNativeLibraryNoBrowserProcess(); + mActivityTestRule.loadNativeLibraryNoBrowserProcess(); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/InterstitialPageTest.java b/content/public/android/javatests/src/org/chromium/content/browser/InterstitialPageTest.java index 1bdba7b1..64a9c359 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/InterstitialPageTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/InterstitialPageTest.java
@@ -6,7 +6,14 @@ import android.support.test.filters.LargeTest; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.chromium.base.ThreadUtils; +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.base.test.util.UrlUtils; @@ -16,7 +23,7 @@ import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsObserver; import org.chromium.content_shell_apk.ContentShellActivity; -import org.chromium.content_shell_apk.ContentShellTestBase; +import org.chromium.content_shell_apk.ContentShellActivityTestRule; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; @@ -24,7 +31,10 @@ /** * Tests for interstitial pages. */ -public class InterstitialPageTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class InterstitialPageTest { + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); private static final String URL = UrlUtils.encodeHtmlDataUri( "<html><head></head><body>test</body></html>"); @@ -56,12 +66,11 @@ } } - @Override - protected void setUp() throws Exception { - super.setUp(); - ContentShellActivity activity = launchContentShellWithUrl(URL); - assertNotNull(activity); - waitForActiveShellToBeDoneLoading(); + @Before + public void setUp() throws Exception { + ContentShellActivity activity = mActivityTestRule.launchContentShellWithUrl(URL); + Assert.assertNotNull(activity); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); } private void waitForInterstitial(final boolean shouldBeShown) { @@ -69,7 +78,7 @@ Criteria.equals(shouldBeShown, new Callable<Boolean>() { @Override public Boolean call() { - return getWebContents().isShowingInterstitialPage(); + return mActivityTestRule.getWebContents().isShowingInterstitialPage(); } })); } @@ -77,6 +86,7 @@ /** * Tests that showing and hiding an interstitial works. */ + @Test @LargeTest @Feature({"Navigation"}) @RetryOnFailure @@ -100,7 +110,7 @@ new InterstitialPageDelegateAndroid(htmlContent) { @Override protected void commandReceived(String command) { - assertEquals(command, proceedCommand); + Assert.assertEquals(command, proceedCommand); proceed(); } }; @@ -108,17 +118,19 @@ new Callable<TestWebContentsObserver>() { @Override public TestWebContentsObserver call() throws Exception { - getWebContents().showInterstitialPage(URL, delegate.getNative()); - return new TestWebContentsObserver(getWebContents()); + mActivityTestRule.getWebContents().showInterstitialPage( + URL, delegate.getNative()); + return new TestWebContentsObserver(mActivityTestRule.getWebContents()); } }); waitForInterstitial(true); - assertTrue("WebContentsObserver not notified of interstitial showing", + Assert.assertTrue("WebContentsObserver not notified of interstitial showing", observer.isInterstitialShowing()); - TouchCommon.singleClickView(getContentViewCore().getContainerView(), 10, 10); + TouchCommon.singleClickView( + mActivityTestRule.getContentViewCore().getContainerView(), 10, 10); waitForInterstitial(false); - assertTrue("WebContentsObserver not notified of interstitial hiding", + Assert.assertTrue("WebContentsObserver not notified of interstitial hiding", !observer.isInterstitialShowing()); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayCoercionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayCoercionTest.java index fdf3b1d..387c35f 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayCoercionTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayCoercionTest.java
@@ -6,7 +6,14 @@ import android.support.test.filters.SmallTest; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.chromium.base.annotations.SuppressFBWarnings; +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.content.browser.JavaBridgeTestCommon.Controller; @@ -21,7 +28,13 @@ * FIXME: Consider making our implementation more compliant, if it will not * break backwards-compatibility. See b/4408210. */ -public class JavaBridgeArrayCoercionTest extends JavaBridgeTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class JavaBridgeArrayCoercionTest { + private static final double ASSERTION_DELTA = 0; + + @Rule + public JavaBridgeActivityTestRule mActivityTestRule = new JavaBridgeActivityTestRule(); + @SuppressFBWarnings("CHROMIUM_SYNCHRONIZED_METHOD") private static class TestObject extends Controller { private final Object mObjectInstance; @@ -148,11 +161,10 @@ private TestObject mTestObject; - @Override - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { mTestObject = new TestObject(); - injectObjectAndReload(mTestObject, "testObject"); + mActivityTestRule.injectObjectAndReload(mTestObject, "testObject"); } // Note that all tests use a single element array for simplicity. We test @@ -160,809 +172,841 @@ // Test passing an array of JavaScript numbers in the int32 range to a // method which takes a Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassNumberInt32() throws Throwable { - executeJavaScript("testObject.setBooleanArray([0]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray([0]);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); // LIVECONNECT_COMPLIANCE: Should convert to boolean. - executeJavaScript("testObject.setBooleanArray([42]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray([42]);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); - executeJavaScript("testObject.setByteArray([42]);"); - assertEquals(42, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray([42]);"); + Assert.assertEquals(42, mTestObject.waitForByteArray()[0]); - executeJavaScript("testObject.setCharArray([42]);"); - assertEquals(42, mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray([42]);"); + Assert.assertEquals(42, mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setShortArray([42]);"); - assertEquals(42, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray([42]);"); + Assert.assertEquals(42, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setIntArray([42]);"); - assertEquals(42, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray([42]);"); + Assert.assertEquals(42, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setLongArray([42]);"); - assertEquals(42L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray([42]);"); + Assert.assertEquals(42L, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setFloatArray([42]);"); - assertEquals(42.0f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray([42]);"); + Assert.assertEquals(42.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleArray([42]);"); - assertEquals(42.0, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray([42]);"); + Assert.assertEquals(42.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. - executeJavaScript("testObject.setObjectArray([42]);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray([42]);"); + Assert.assertNull(mTestObject.waitForObjectArray()); // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String. - executeJavaScript("testObject.setStringArray([42]);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray([42]);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeArray([42]);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray([42]);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing an array of JavaScript numbers in the double range to a // method which takes a Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassNumberDouble() throws Throwable { // LIVECONNECT_COMPLIANCE: Should convert to boolean. - executeJavaScript("testObject.setBooleanArray([42.1]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray([42.1]);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); - executeJavaScript("testObject.setByteArray([42.1]);"); - assertEquals(42, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray([42.1]);"); + Assert.assertEquals(42, mTestObject.waitForByteArray()[0]); // LIVECONNECT_COMPLIANCE: Should convert to numeric char value. - executeJavaScript("testObject.setCharArray([42.1]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray([42.1]);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setShortArray([42.1]);"); - assertEquals(42, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray([42.1]);"); + Assert.assertEquals(42, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setIntArray([42.1]);"); - assertEquals(42, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray([42.1]);"); + Assert.assertEquals(42, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setLongArray([42.1]);"); - assertEquals(42L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray([42.1]);"); + Assert.assertEquals(42L, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setFloatArray([42.1]);"); - assertEquals(42.1f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray([42.1]);"); + Assert.assertEquals(42.1f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleArray([42.1]);"); - assertEquals(42.1, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray([42.1]);"); + Assert.assertEquals(42.1, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. - executeJavaScript("testObject.setObjectArray([42.1]);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray([42.1]);"); + Assert.assertNull(mTestObject.waitForObjectArray()); // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String. - executeJavaScript("testObject.setStringArray([42.1]);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray([42.1]);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeArray([42.1]);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray([42.1]);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing an array of JavaScript NaN values to a method which takes a // Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassNumberNaN() throws Throwable { - executeJavaScript("testObject.setBooleanArray([Number.NaN]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray([Number.NaN]);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); - executeJavaScript("testObject.setByteArray([Number.NaN]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray([Number.NaN]);"); + Assert.assertEquals(0, mTestObject.waitForByteArray()[0]); - executeJavaScript("testObject.setCharArray([Number.NaN]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray([Number.NaN]);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setShortArray([Number.NaN]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray([Number.NaN]);"); + Assert.assertEquals(0, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setIntArray([Number.NaN]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray([Number.NaN]);"); + Assert.assertEquals(0, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setLongArray([Number.NaN]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray([Number.NaN]);"); + Assert.assertEquals(0L, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setFloatArray([Number.NaN]);"); - assertEquals(Float.NaN, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray([Number.NaN]);"); + Assert.assertEquals(Float.NaN, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleArray([Number.NaN]);"); - assertEquals(Double.NaN, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray([Number.NaN]);"); + Assert.assertEquals(Double.NaN, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. - executeJavaScript("testObject.setObjectArray([Number.NaN]);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray([Number.NaN]);"); + Assert.assertNull(mTestObject.waitForObjectArray()); // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String. - executeJavaScript("testObject.setStringArray([Number.NaN]);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray([Number.NaN]);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeArray([Number.NaN]);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray([Number.NaN]);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing an array of JavaScript infinity values to a method which // takes a Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassNumberInfinity() throws Throwable { - executeJavaScript("testObject.setBooleanArray([Infinity]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray([Infinity]);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); - executeJavaScript("testObject.setByteArray([Infinity]);"); - assertEquals(-1, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray([Infinity]);"); + Assert.assertEquals(-1, mTestObject.waitForByteArray()[0]); // LIVECONNECT_COMPLIANCE: Should convert to maximum numeric char value. - executeJavaScript("testObject.setCharArray([Infinity]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray([Infinity]);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setShortArray([Infinity]);"); - assertEquals(-1, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray([Infinity]);"); + Assert.assertEquals(-1, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setIntArray([Infinity]);"); - assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray([Infinity]);"); + Assert.assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setLongArray([Infinity]);"); - assertEquals(Long.MAX_VALUE, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray([Infinity]);"); + Assert.assertEquals(Long.MAX_VALUE, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setFloatArray([Infinity]);"); - assertEquals(Float.POSITIVE_INFINITY, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray([Infinity]);"); + Assert.assertEquals( + Float.POSITIVE_INFINITY, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleArray([Infinity]);"); - assertEquals(Double.POSITIVE_INFINITY, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray([Infinity]);"); + Assert.assertEquals( + Double.POSITIVE_INFINITY, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. - executeJavaScript("testObject.setObjectArray([Infinity]);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray([Infinity]);"); + Assert.assertNull(mTestObject.waitForObjectArray()); // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String. - executeJavaScript("testObject.setStringArray([Infinity]);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray([Infinity]);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeArray([Infinity]);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray([Infinity]);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing an array of JavaScript boolean values to a method which // takes a Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassBoolean() throws Throwable { - executeJavaScript("testObject.setBooleanArray([true]);"); - assertTrue(mTestObject.waitForBooleanArray()[0]); - executeJavaScript("testObject.setBooleanArray([false]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray([true]);"); + Assert.assertTrue(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray([false]);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setByteArray([true]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); - executeJavaScript("testObject.setByteArray([false]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray([true]);"); + Assert.assertEquals(0, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray([false]);"); + Assert.assertEquals(0, mTestObject.waitForByteArray()[0]); // LIVECONNECT_COMPLIANCE: Should convert to numeric char value 1. - executeJavaScript("testObject.setCharArray([true]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setCharArray([false]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray([true]);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray([false]);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharArray()[0]); // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setShortArray([true]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setShortArray([false]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray([true]);"); + Assert.assertEquals(0, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray([false]);"); + Assert.assertEquals(0, mTestObject.waitForShortArray()[0]); // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setIntArray([true]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setIntArray([false]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray([true]);"); + Assert.assertEquals(0, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray([false]);"); + Assert.assertEquals(0, mTestObject.waitForIntArray()[0]); // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setLongArray([true]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setLongArray([false]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray([true]);"); + Assert.assertEquals(0L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray([false]);"); + Assert.assertEquals(0L, mTestObject.waitForLongArray()[0]); // LIVECONNECT_COMPLIANCE: Should be 1.0. - executeJavaScript("testObject.setFloatArray([true]);"); - assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); - executeJavaScript("testObject.setFloatArray([false]);"); - assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray([true]);"); + Assert.assertEquals(0.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); + mActivityTestRule.executeJavaScript("testObject.setFloatArray([false]);"); + Assert.assertEquals(0.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should be 1.0. - executeJavaScript("testObject.setDoubleArray([true]);"); - assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); - executeJavaScript("testObject.setDoubleArray([false]);"); - assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray([true]);"); + Assert.assertEquals(0.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray([false]);"); + Assert.assertEquals(0.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. - executeJavaScript("testObject.setObjectArray([true]);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray([true]);"); + Assert.assertNull(mTestObject.waitForObjectArray()); // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String. - executeJavaScript("testObject.setStringArray([true]);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray([true]);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeArray([true]);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray([true]);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing an array of JavaScript strings to a method which takes a // Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassString() throws Throwable { // LIVECONNECT_COMPLIANCE: Non-empty string should convert to true. - executeJavaScript("testObject.setBooleanArray([\"+042.10\"]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray([\"+042.10\"]);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setByteArray([\"+042.10\"]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray([\"+042.10\"]);"); + Assert.assertEquals(0, mTestObject.waitForByteArray()[0]); // LIVECONNECT_COMPLIANCE: Should decode and convert to numeric char value. - executeJavaScript("testObject.setCharArray([\"+042.10\"]);"); - assertEquals(0, mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray([\"+042.10\"]);"); + Assert.assertEquals(0, mTestObject.waitForCharArray()[0]); // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setShortArray([\"+042.10\"]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray([\"+042.10\"]);"); + Assert.assertEquals(0, mTestObject.waitForShortArray()[0]); // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setIntArray([\"+042.10\"]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray([\"+042.10\"]);"); + Assert.assertEquals(0, mTestObject.waitForIntArray()[0]); // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setLongArray([\"+042.10\"]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray([\"+042.10\"]);"); + Assert.assertEquals(0L, mTestObject.waitForLongArray()[0]); // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setFloatArray([\"+042.10\"]);"); - assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray([\"+042.10\"]);"); + Assert.assertEquals(0.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setDoubleArray([\"+042.10\"]);"); - assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray([\"+042.10\"]);"); + Assert.assertEquals(0.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. - executeJavaScript("testObject.setObjectArray([\"+042.10\"]);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray([\"+042.10\"]);"); + Assert.assertNull(mTestObject.waitForObjectArray()); - executeJavaScript("testObject.setStringArray([\"+042.10\"]);"); - assertEquals("+042.10", mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray([\"+042.10\"]);"); + Assert.assertEquals("+042.10", mTestObject.waitForStringArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeArray([\"+042.10\"]);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray([\"+042.10\"]);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing an array of JavaScript objects to a method which takes a // Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassJavaScriptObject() throws Throwable { // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setBooleanArray([{foo: 42}]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray([{foo: 42}]);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setByteArray([{foo: 42}]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray([{foo: 42}]);"); + Assert.assertEquals(0, mTestObject.waitForByteArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCharArray([{foo: 42}]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray([{foo: 42}]);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setShortArray([{foo: 42}]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray([{foo: 42}]);"); + Assert.assertEquals(0, mTestObject.waitForShortArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setIntArray([{foo: 42}]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray([{foo: 42}]);"); + Assert.assertEquals(0, mTestObject.waitForIntArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setLongArray([{foo: 42}]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray([{foo: 42}]);"); + Assert.assertEquals(0L, mTestObject.waitForLongArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setFloatArray([{foo: 42}]);"); - assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray([{foo: 42}]);"); + Assert.assertEquals(0.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setDoubleArray([{foo: 42}]);"); - assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray([{foo: 42}]);"); + Assert.assertEquals(0.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setObjectArray([{foo: 42}]);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray([{foo: 42}]);"); + Assert.assertNull(mTestObject.waitForObjectArray()); // LIVECONNECT_COMPLIANCE: Should call toString() on object. - executeJavaScript("testObject.setStringArray([{foo: 42}]);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray([{foo: 42}]);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeArray([{foo: 42}]);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray([{foo: 42}]);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing an array of Java objects to a method which takes a Java // array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassJavaObject() throws Throwable { // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setBooleanArray([testObject.getObjectInstance()]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript( + "testObject.setBooleanArray([testObject.getObjectInstance()]);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setByteArray([testObject.getObjectInstance()]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript( + "testObject.setByteArray([testObject.getObjectInstance()]);"); + Assert.assertEquals(0, mTestObject.waitForByteArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCharArray([testObject.getObjectInstance()]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript( + "testObject.setCharArray([testObject.getObjectInstance()]);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setShortArray([testObject.getObjectInstance()]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript( + "testObject.setShortArray([testObject.getObjectInstance()]);"); + Assert.assertEquals(0, mTestObject.waitForShortArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setIntArray([testObject.getObjectInstance()]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript( + "testObject.setIntArray([testObject.getObjectInstance()]);"); + Assert.assertEquals(0, mTestObject.waitForIntArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setLongArray([testObject.getObjectInstance()]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript( + "testObject.setLongArray([testObject.getObjectInstance()]);"); + Assert.assertEquals(0L, mTestObject.waitForLongArray()[0]); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setFloatArray([testObject.getObjectInstance()]);"); - assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript( + "testObject.setFloatArray([testObject.getObjectInstance()]);"); + Assert.assertEquals(0.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setDoubleArray([testObject.getObjectInstance()]);"); - assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript( + "testObject.setDoubleArray([testObject.getObjectInstance()]);"); + Assert.assertEquals(0.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should create an array and pass Java object. - executeJavaScript("testObject.setObjectArray([testObject.getObjectInstance()]);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript( + "testObject.setObjectArray([testObject.getObjectInstance()]);"); + Assert.assertNull(mTestObject.waitForObjectArray()); // LIVECONNECT_COMPLIANCE: Should call toString() on object. - executeJavaScript("testObject.setStringArray([testObject.getObjectInstance()]);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript( + "testObject.setStringArray([testObject.getObjectInstance()]);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); // LIVECONNECT_COMPLIANCE: Should create array and pass Java object. - executeJavaScript("testObject.setCustomTypeArray([testObject.getObjectInstance()]);"); - assertNull(mTestObject.waitForCustomTypeArray()); - executeJavaScript("testObject.setCustomTypeArray([testObject.getCustomTypeInstance()]);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript( + "testObject.setCustomTypeArray([testObject.getObjectInstance()]);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript( + "testObject.setCustomTypeArray([testObject.getCustomTypeInstance()]);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing an array of JavaScript null values to a method which takes // a Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassNull() throws Throwable { - executeJavaScript("testObject.setByteArray([null]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray([null]);"); + Assert.assertEquals(0, mTestObject.waitForByteArray()[0]); - executeJavaScript("testObject.setCharArray([null]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray([null]);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setShortArray([null]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray([null]);"); + Assert.assertEquals(0, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setIntArray([null]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray([null]);"); + Assert.assertEquals(0, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setLongArray([null]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray([null]);"); + Assert.assertEquals(0L, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setFloatArray([null]);"); - assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray([null]);"); + Assert.assertEquals(0.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleArray([null]);"); - assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray([null]);"); + Assert.assertEquals(0.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setBooleanArray([null]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray([null]);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); // LIVECONNECT_COMPLIANCE: Should create array and pass null. - executeJavaScript("testObject.setObjectArray([null]);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray([null]);"); + Assert.assertNull(mTestObject.waitForObjectArray()); - executeJavaScript("testObject.setStringArray([null]);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray([null]);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); // LIVECONNECT_COMPLIANCE: Should create array and pass null. - executeJavaScript("testObject.setCustomTypeArray([null]);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray([null]);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing an array of JavaScript undefined values to a method which // takes a Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassUndefined() throws Throwable { - executeJavaScript("testObject.setByteArray([undefined]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray([undefined]);"); + Assert.assertEquals(0, mTestObject.waitForByteArray()[0]); - executeJavaScript("testObject.setCharArray([undefined]);"); - assertEquals(0, mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray([undefined]);"); + Assert.assertEquals(0, mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setShortArray([undefined]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray([undefined]);"); + Assert.assertEquals(0, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setIntArray([undefined]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray([undefined]);"); + Assert.assertEquals(0, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setLongArray([undefined]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray([undefined]);"); + Assert.assertEquals(0L, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setFloatArray([undefined]);"); - assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray([undefined]);"); + Assert.assertEquals(0.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleArray([undefined]);"); - assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray([undefined]);"); + Assert.assertEquals(0.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setBooleanArray([undefined]);"); - assertEquals(false, mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray([undefined]);"); + Assert.assertEquals(false, mTestObject.waitForBooleanArray()[0]); // LIVECONNECT_COMPLIANCE: Should create array and pass null. - executeJavaScript("testObject.setObjectArray([undefined]);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray([undefined]);"); + Assert.assertNull(mTestObject.waitForObjectArray()); - executeJavaScript("testObject.setStringArray([undefined]);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray([undefined]);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); // LIVECONNECT_COMPLIANCE: Should create array and pass null. - executeJavaScript("testObject.setCustomTypeArray([undefined]);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray([undefined]);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing a typed Int8Array to a method which takes a Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassInt8Array() throws Throwable { - executeJavaScript("buffer = new ArrayBuffer(1);"); - executeJavaScript("int8_array = new Int8Array(buffer);"); - executeJavaScript("int8_array[0] = 42;"); + mActivityTestRule.executeJavaScript("buffer = new ArrayBuffer(1);"); + mActivityTestRule.executeJavaScript("int8_array = new Int8Array(buffer);"); + mActivityTestRule.executeJavaScript("int8_array[0] = 42;"); - executeJavaScript("testObject.setBooleanArray(int8_array);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray(int8_array);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); - executeJavaScript("testObject.setByteArray(int8_array);"); - assertEquals(42, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray(int8_array);"); + Assert.assertEquals(42, mTestObject.waitForByteArray()[0]); - executeJavaScript("testObject.setCharArray(int8_array);"); - assertEquals(42, mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray(int8_array);"); + Assert.assertEquals(42, mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setShortArray(int8_array);"); - assertEquals(42, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray(int8_array);"); + Assert.assertEquals(42, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setIntArray(int8_array);"); - assertEquals(42, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray(int8_array);"); + Assert.assertEquals(42, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setLongArray(int8_array);"); - assertEquals(42L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray(int8_array);"); + Assert.assertEquals(42L, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setFloatArray(int8_array);"); - assertEquals(42.0f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray(int8_array);"); + Assert.assertEquals(42.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleArray(int8_array);"); - assertEquals(42.0, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray(int8_array);"); + Assert.assertEquals(42.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setObjectArray(int8_array);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray(int8_array);"); + Assert.assertNull(mTestObject.waitForObjectArray()); - executeJavaScript("testObject.setStringArray(int8_array);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray(int8_array);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); - executeJavaScript("testObject.setCustomTypeArray(int8_array);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray(int8_array);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing a typed Uint8Array to a method which takes a Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassUint8Array() throws Throwable { - executeJavaScript("buffer = new ArrayBuffer(1);"); - executeJavaScript("uint8_array = new Uint8Array(buffer);"); - executeJavaScript("uint8_array[0] = 42;"); + mActivityTestRule.executeJavaScript("buffer = new ArrayBuffer(1);"); + mActivityTestRule.executeJavaScript("uint8_array = new Uint8Array(buffer);"); + mActivityTestRule.executeJavaScript("uint8_array[0] = 42;"); - executeJavaScript("testObject.setBooleanArray(uint8_array);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray(uint8_array);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); - executeJavaScript("testObject.setByteArray(uint8_array);"); - assertEquals(42, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray(uint8_array);"); + Assert.assertEquals(42, mTestObject.waitForByteArray()[0]); - executeJavaScript("testObject.setCharArray(uint8_array);"); - assertEquals(42, mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray(uint8_array);"); + Assert.assertEquals(42, mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setShortArray(uint8_array);"); - assertEquals(42, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray(uint8_array);"); + Assert.assertEquals(42, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setIntArray(uint8_array);"); - assertEquals(42, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray(uint8_array);"); + Assert.assertEquals(42, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setLongArray(uint8_array);"); - assertEquals(42L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray(uint8_array);"); + Assert.assertEquals(42L, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setFloatArray(uint8_array);"); - assertEquals(42.0f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray(uint8_array);"); + Assert.assertEquals(42.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleArray(uint8_array);"); - assertEquals(42.0, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray(uint8_array);"); + Assert.assertEquals(42.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setObjectArray(uint8_array);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray(uint8_array);"); + Assert.assertNull(mTestObject.waitForObjectArray()); - executeJavaScript("testObject.setStringArray(uint8_array);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray(uint8_array);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); - executeJavaScript("testObject.setCustomTypeArray(uint8_array);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray(uint8_array);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing a typed Int16Array to a method which takes a Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassInt16Array() throws Throwable { - executeJavaScript("buffer = new ArrayBuffer(2);"); - executeJavaScript("int16_array = new Int16Array(buffer);"); - executeJavaScript("int16_array[0] = 42;"); + mActivityTestRule.executeJavaScript("buffer = new ArrayBuffer(2);"); + mActivityTestRule.executeJavaScript("int16_array = new Int16Array(buffer);"); + mActivityTestRule.executeJavaScript("int16_array[0] = 42;"); - executeJavaScript("testObject.setBooleanArray(int16_array);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray(int16_array);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); - executeJavaScript("testObject.setByteArray(int16_array);"); - assertEquals(42, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray(int16_array);"); + Assert.assertEquals(42, mTestObject.waitForByteArray()[0]); - executeJavaScript("testObject.setCharArray(int16_array);"); - assertEquals(42, mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray(int16_array);"); + Assert.assertEquals(42, mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setShortArray(int16_array);"); - assertEquals(42, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray(int16_array);"); + Assert.assertEquals(42, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setIntArray(int16_array);"); - assertEquals(42, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray(int16_array);"); + Assert.assertEquals(42, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setLongArray(int16_array);"); - assertEquals(42L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray(int16_array);"); + Assert.assertEquals(42L, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setFloatArray(int16_array);"); - assertEquals(42.0f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray(int16_array);"); + Assert.assertEquals(42.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleArray(int16_array);"); - assertEquals(42.0, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray(int16_array);"); + Assert.assertEquals(42.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setObjectArray(int16_array);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray(int16_array);"); + Assert.assertNull(mTestObject.waitForObjectArray()); - executeJavaScript("testObject.setStringArray(int16_array);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray(int16_array);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); - executeJavaScript("testObject.setCustomTypeArray(int16_array);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray(int16_array);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing a typed Uint16Array to a method which takes a Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassUint16Array() throws Throwable { - executeJavaScript("buffer = new ArrayBuffer(2);"); - executeJavaScript("uint16_array = new Uint16Array(buffer);"); - executeJavaScript("uint16_array[0] = 42;"); + mActivityTestRule.executeJavaScript("buffer = new ArrayBuffer(2);"); + mActivityTestRule.executeJavaScript("uint16_array = new Uint16Array(buffer);"); + mActivityTestRule.executeJavaScript("uint16_array[0] = 42;"); - executeJavaScript("testObject.setBooleanArray(uint16_array);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray(uint16_array);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); - executeJavaScript("testObject.setByteArray(uint16_array);"); - assertEquals(42, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray(uint16_array);"); + Assert.assertEquals(42, mTestObject.waitForByteArray()[0]); - executeJavaScript("testObject.setCharArray(uint16_array);"); - assertEquals(42, mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray(uint16_array);"); + Assert.assertEquals(42, mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setShortArray(uint16_array);"); - assertEquals(42, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray(uint16_array);"); + Assert.assertEquals(42, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setIntArray(uint16_array);"); - assertEquals(42, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray(uint16_array);"); + Assert.assertEquals(42, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setLongArray(uint16_array);"); - assertEquals(42L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray(uint16_array);"); + Assert.assertEquals(42L, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setFloatArray(uint16_array);"); - assertEquals(42.0f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray(uint16_array);"); + Assert.assertEquals(42.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleArray(uint16_array);"); - assertEquals(42.0, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray(uint16_array);"); + Assert.assertEquals(42.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setObjectArray(uint16_array);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray(uint16_array);"); + Assert.assertNull(mTestObject.waitForObjectArray()); - executeJavaScript("testObject.setStringArray(uint16_array);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray(uint16_array);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); - executeJavaScript("testObject.setCustomTypeArray(uint16_array);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray(uint16_array);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing a typed Int32Array to a method which takes a Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassInt32Array() throws Throwable { - executeJavaScript("buffer = new ArrayBuffer(4);"); - executeJavaScript("int32_array = new Int32Array(buffer);"); - executeJavaScript("int32_array[0] = 42;"); + mActivityTestRule.executeJavaScript("buffer = new ArrayBuffer(4);"); + mActivityTestRule.executeJavaScript("int32_array = new Int32Array(buffer);"); + mActivityTestRule.executeJavaScript("int32_array[0] = 42;"); - executeJavaScript("testObject.setBooleanArray(int32_array);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray(int32_array);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); - executeJavaScript("testObject.setByteArray(int32_array);"); - assertEquals(42, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray(int32_array);"); + Assert.assertEquals(42, mTestObject.waitForByteArray()[0]); - executeJavaScript("testObject.setCharArray(int32_array);"); - assertEquals(42, mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray(int32_array);"); + Assert.assertEquals(42, mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setShortArray(int32_array);"); - assertEquals(42, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray(int32_array);"); + Assert.assertEquals(42, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setIntArray(int32_array);"); - assertEquals(42, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray(int32_array);"); + Assert.assertEquals(42, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setLongArray(int32_array);"); - assertEquals(42L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray(int32_array);"); + Assert.assertEquals(42L, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setFloatArray(int32_array);"); - assertEquals(42.0f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray(int32_array);"); + Assert.assertEquals(42.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleArray(int32_array);"); - assertEquals(42.0, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray(int32_array);"); + Assert.assertEquals(42.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setObjectArray(int32_array);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray(int32_array);"); + Assert.assertNull(mTestObject.waitForObjectArray()); - executeJavaScript("testObject.setStringArray(int32_array);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray(int32_array);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); - executeJavaScript("testObject.setCustomTypeArray(int32_array);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray(int32_array);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing a typed Uint32Array to a method which takes a Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassUint32Array() throws Throwable { - executeJavaScript("buffer = new ArrayBuffer(4);"); - executeJavaScript("uint32_array = new Uint32Array(buffer);"); - executeJavaScript("uint32_array[0] = 42;"); + mActivityTestRule.executeJavaScript("buffer = new ArrayBuffer(4);"); + mActivityTestRule.executeJavaScript("uint32_array = new Uint32Array(buffer);"); + mActivityTestRule.executeJavaScript("uint32_array[0] = 42;"); - executeJavaScript("testObject.setBooleanArray(uint32_array);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray(uint32_array);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); - executeJavaScript("testObject.setByteArray(uint32_array);"); - assertEquals(42, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray(uint32_array);"); + Assert.assertEquals(42, mTestObject.waitForByteArray()[0]); - executeJavaScript("testObject.setCharArray(uint32_array);"); - assertEquals(42, mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray(uint32_array);"); + Assert.assertEquals(42, mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setShortArray(uint32_array);"); - assertEquals(42, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray(uint32_array);"); + Assert.assertEquals(42, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setIntArray(uint32_array);"); - assertEquals(42, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray(uint32_array);"); + Assert.assertEquals(42, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setLongArray(uint32_array);"); - assertEquals(42L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray(uint32_array);"); + Assert.assertEquals(42L, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setFloatArray(uint32_array);"); - assertEquals(42.0f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray(uint32_array);"); + Assert.assertEquals(42.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleArray(uint32_array);"); - assertEquals(42.0, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray(uint32_array);"); + Assert.assertEquals(42.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setObjectArray(uint32_array);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray(uint32_array);"); + Assert.assertNull(mTestObject.waitForObjectArray()); - executeJavaScript("testObject.setStringArray(uint32_array);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray(uint32_array);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); - executeJavaScript("testObject.setCustomTypeArray(uint32_array);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray(uint32_array);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing a typed Float32Array to a method which takes a Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassFloat32Array() throws Throwable { - executeJavaScript("buffer = new ArrayBuffer(4);"); - executeJavaScript("float32_array = new Float32Array(buffer);"); - executeJavaScript("float32_array[0] = 42.0;"); + mActivityTestRule.executeJavaScript("buffer = new ArrayBuffer(4);"); + mActivityTestRule.executeJavaScript("float32_array = new Float32Array(buffer);"); + mActivityTestRule.executeJavaScript("float32_array[0] = 42.0;"); - executeJavaScript("testObject.setBooleanArray(float32_array);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray(float32_array);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); - executeJavaScript("testObject.setByteArray(float32_array);"); - assertEquals(42, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray(float32_array);"); + Assert.assertEquals(42, mTestObject.waitForByteArray()[0]); - executeJavaScript("testObject.setCharArray(float32_array);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray(float32_array);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setShortArray(float32_array);"); - assertEquals(42, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray(float32_array);"); + Assert.assertEquals(42, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setIntArray(float32_array);"); - assertEquals(42, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray(float32_array);"); + Assert.assertEquals(42, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setLongArray(float32_array);"); - assertEquals(42L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray(float32_array);"); + Assert.assertEquals(42L, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setFloatArray(float32_array);"); - assertEquals(42.0f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray(float32_array);"); + Assert.assertEquals(42.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleArray(float32_array);"); - assertEquals(42.0, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray(float32_array);"); + Assert.assertEquals(42.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setObjectArray(float32_array);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray(float32_array);"); + Assert.assertNull(mTestObject.waitForObjectArray()); - executeJavaScript("testObject.setStringArray(float32_array);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray(float32_array);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); - executeJavaScript("testObject.setCustomTypeArray(float32_array);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray(float32_array);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } // Test passing a typed Float64Array to a method which takes a Java array. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassFloat64Array() throws Throwable { - executeJavaScript("buffer = new ArrayBuffer(8);"); - executeJavaScript("float64_array = new Float64Array(buffer);"); - executeJavaScript("float64_array[0] = 42.0;"); + mActivityTestRule.executeJavaScript("buffer = new ArrayBuffer(8);"); + mActivityTestRule.executeJavaScript("float64_array = new Float64Array(buffer);"); + mActivityTestRule.executeJavaScript("float64_array[0] = 42.0;"); - executeJavaScript("testObject.setBooleanArray(float64_array);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setBooleanArray(float64_array);"); + Assert.assertFalse(mTestObject.waitForBooleanArray()[0]); - executeJavaScript("testObject.setByteArray(float64_array);"); - assertEquals(42, mTestObject.waitForByteArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setByteArray(float64_array);"); + Assert.assertEquals(42, mTestObject.waitForByteArray()[0]); - executeJavaScript("testObject.setCharArray(float64_array);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setCharArray(float64_array);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setShortArray(float64_array);"); - assertEquals(42, mTestObject.waitForShortArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setShortArray(float64_array);"); + Assert.assertEquals(42, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setIntArray(float64_array);"); - assertEquals(42, mTestObject.waitForIntArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setIntArray(float64_array);"); + Assert.assertEquals(42, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setLongArray(float64_array);"); - assertEquals(42L, mTestObject.waitForLongArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setLongArray(float64_array);"); + Assert.assertEquals(42L, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setFloatArray(float64_array);"); - assertEquals(42.0f, mTestObject.waitForFloatArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setFloatArray(float64_array);"); + Assert.assertEquals(42.0f, mTestObject.waitForFloatArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleArray(float64_array);"); - assertEquals(42.0, mTestObject.waitForDoubleArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setDoubleArray(float64_array);"); + Assert.assertEquals(42.0, mTestObject.waitForDoubleArray()[0], ASSERTION_DELTA); - executeJavaScript("testObject.setObjectArray(float64_array);"); - assertNull(mTestObject.waitForObjectArray()); + mActivityTestRule.executeJavaScript("testObject.setObjectArray(float64_array);"); + Assert.assertNull(mTestObject.waitForObjectArray()); - executeJavaScript("testObject.setStringArray(float64_array);"); - assertNull(mTestObject.waitForStringArray()[0]); + mActivityTestRule.executeJavaScript("testObject.setStringArray(float64_array);"); + Assert.assertNull(mTestObject.waitForStringArray()[0]); - executeJavaScript("testObject.setCustomTypeArray(float64_array);"); - assertNull(mTestObject.waitForCustomTypeArray()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeArray(float64_array);"); + Assert.assertNull(mTestObject.waitForCustomTypeArray()); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayTest.java b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayTest.java index 2be60b5..f4001b8 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeArrayTest.java
@@ -6,7 +6,14 @@ import android.support.test.filters.SmallTest; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.chromium.base.annotations.SuppressFBWarnings; +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.content.browser.JavaBridgeTestCommon.Controller; @@ -20,7 +27,11 @@ * FIXME: Consider making our implementation more compliant, if it will not * break backwards-compatibility. See b/4408210. */ -public class JavaBridgeArrayTest extends JavaBridgeTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class JavaBridgeArrayTest { + @Rule + public JavaBridgeActivityTestRule mActivityTestRule = new JavaBridgeActivityTestRule(); + @SuppressFBWarnings("CHROMIUM_SYNCHRONIZED_METHOD") private static class TestObject extends Controller { private boolean mBooleanValue; @@ -88,128 +99,140 @@ private TestObject mTestObject; - @Override - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { mTestObject = new TestObject(); - injectObjectAndReload(mTestObject, "testObject"); + mActivityTestRule.injectObjectAndReload(mTestObject, "testObject"); } + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testArrayLength() throws Throwable { - executeJavaScript("testObject.setIntArray([42, 43, 44]);"); + mActivityTestRule.executeJavaScript("testObject.setIntArray([42, 43, 44]);"); int[] result = mTestObject.waitForIntArray(); - assertEquals(3, result.length); - assertEquals(42, result[0]); - assertEquals(43, result[1]); - assertEquals(44, result[2]); + Assert.assertEquals(3, result.length); + Assert.assertEquals(42, result[0]); + Assert.assertEquals(43, result[1]); + Assert.assertEquals(44, result[2]); } + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassNull() throws Throwable { - executeJavaScript("testObject.setIntArray(null);"); - assertNull(mTestObject.waitForIntArray()); + mActivityTestRule.executeJavaScript("testObject.setIntArray(null);"); + Assert.assertNull(mTestObject.waitForIntArray()); } + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassUndefined() throws Throwable { - executeJavaScript("testObject.setIntArray(undefined);"); - assertNull(mTestObject.waitForIntArray()); + mActivityTestRule.executeJavaScript("testObject.setIntArray(undefined);"); + Assert.assertNull(mTestObject.waitForIntArray()); } + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassEmptyArray() throws Throwable { - executeJavaScript("testObject.setIntArray([]);"); - assertEquals(0, mTestObject.waitForIntArray().length); + mActivityTestRule.executeJavaScript("testObject.setIntArray([]);"); + Assert.assertEquals(0, mTestObject.waitForIntArray().length); } // Note that this requires being able to pass a string from JavaScript to // Java. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassArrayToStringMethod() throws Throwable { // LIVECONNECT_COMPLIANCE: Should call toString() on array. - executeJavaScript("testObject.setStringValue([42, 42, 42]);"); - assertEquals("undefined", mTestObject.waitForStringValue()); + mActivityTestRule.executeJavaScript("testObject.setStringValue([42, 42, 42]);"); + Assert.assertEquals("undefined", mTestObject.waitForStringValue()); } // Note that this requires being able to pass an integer from JavaScript to // Java. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassArrayToNonStringNonArrayMethod() throws Throwable { // LIVECONNECT_COMPLIANCE: Should raise JavaScript exception. - executeJavaScript("testObject.setIntValue([42, 42, 42]);"); - assertEquals(0, mTestObject.waitForIntValue()); + mActivityTestRule.executeJavaScript("testObject.setIntValue([42, 42, 42]);"); + Assert.assertEquals(0, mTestObject.waitForIntValue()); } + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassNonArrayToArrayMethod() throws Throwable { // LIVECONNECT_COMPLIANCE: Should raise JavaScript exception. - executeJavaScript("testObject.setIntArray(42);"); - assertNull(mTestObject.waitForIntArray()); + mActivityTestRule.executeJavaScript("testObject.setIntArray(42);"); + Assert.assertNull(mTestObject.waitForIntArray()); } + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testObjectWithLengthProperty() throws Throwable { - executeJavaScript("testObject.setIntArray({length: 3, 1: 42});"); + mActivityTestRule.executeJavaScript("testObject.setIntArray({length: 3, 1: 42});"); int[] result = mTestObject.waitForIntArray(); - assertEquals(3, result.length); - assertEquals(0, result[0]); - assertEquals(42, result[1]); - assertEquals(0, result[2]); + Assert.assertEquals(3, result.length); + Assert.assertEquals(0, result[0]); + Assert.assertEquals(42, result[1]); + Assert.assertEquals(0, result[2]); } + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testNonNumericLengthProperty() throws Throwable { // LIVECONNECT_COMPLIANCE: This should not count as an array, so we // should raise a JavaScript exception. - executeJavaScript("testObject.setIntArray({length: \"foo\"});"); - assertNull(mTestObject.waitForIntArray()); + mActivityTestRule.executeJavaScript("testObject.setIntArray({length: \"foo\"});"); + Assert.assertNull(mTestObject.waitForIntArray()); } + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testLengthOutOfBounds() throws Throwable { // LIVECONNECT_COMPLIANCE: This should not count as an array, so we // should raise a JavaScript exception. - executeJavaScript("testObject.setIntArray({length: -1});"); - assertNull(mTestObject.waitForIntArray()); + mActivityTestRule.executeJavaScript("testObject.setIntArray({length: -1});"); + Assert.assertNull(mTestObject.waitForIntArray()); // LIVECONNECT_COMPLIANCE: This should not count as an array, so we // should raise a JavaScript exception. long length = Integer.MAX_VALUE + 1L; - executeJavaScript("testObject.setIntArray({length: " + length + "});"); - assertNull(mTestObject.waitForIntArray()); + mActivityTestRule.executeJavaScript("testObject.setIntArray({length: " + length + "});"); + Assert.assertNull(mTestObject.waitForIntArray()); // LIVECONNECT_COMPLIANCE: This should not count as an array, so we // should raise a JavaScript exception. length = Integer.MAX_VALUE + 1L - Integer.MIN_VALUE + 1L; - executeJavaScript("testObject.setIntArray({length: " + length + "});"); - assertNull(mTestObject.waitForIntArray()); + mActivityTestRule.executeJavaScript("testObject.setIntArray({length: " + length + "});"); + Assert.assertNull(mTestObject.waitForIntArray()); } + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testSparseArray() throws Throwable { - executeJavaScript("var x = [42, 43]; x[3] = 45; testObject.setIntArray(x);"); + mActivityTestRule.executeJavaScript( + "var x = [42, 43]; x[3] = 45; testObject.setIntArray(x);"); int[] result = mTestObject.waitForIntArray(); - assertEquals(4, result.length); - assertEquals(42, result[0]); - assertEquals(43, result[1]); - assertEquals(0, result[2]); - assertEquals(45, result[3]); + Assert.assertEquals(4, result.length); + Assert.assertEquals(42, result[0]); + Assert.assertEquals(43, result[1]); + Assert.assertEquals(0, result[2]); + Assert.assertEquals(45, result[3]); } // Note that this requires being able to pass a boolean from JavaScript to // Java. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testMethodReturningArrayNotCalled() throws Throwable { @@ -217,39 +240,43 @@ // exception is raised. // LIVECONNECT_COMPLIANCE: Should call method and convert result to // JavaScript array. - executeJavaScript("testObject.setBooleanValue(undefined === testObject.arrayMethod())"); - assertTrue(mTestObject.waitForBooleanValue()); - assertFalse(mTestObject.wasArrayMethodCalled()); + mActivityTestRule.executeJavaScript( + "testObject.setBooleanValue(undefined === testObject.arrayMethod())"); + Assert.assertTrue(mTestObject.waitForBooleanValue()); + Assert.assertFalse(mTestObject.wasArrayMethodCalled()); } + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testMultiDimensionalArrayMethod() throws Throwable { // LIVECONNECT_COMPLIANCE: Should handle multi-dimensional arrays. - executeJavaScript("testObject.setIntIntArray([ [42, 43], [44, 45] ]);"); - assertNull(mTestObject.waitForIntIntArray()); + mActivityTestRule.executeJavaScript("testObject.setIntIntArray([ [42, 43], [44, 45] ]);"); + Assert.assertNull(mTestObject.waitForIntIntArray()); } + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassMultiDimensionalArray() throws Throwable { // LIVECONNECT_COMPLIANCE: Should handle multi-dimensional arrays. - executeJavaScript("testObject.setIntArray([ [42, 43], [44, 45] ]);"); + mActivityTestRule.executeJavaScript("testObject.setIntArray([ [42, 43], [44, 45] ]);"); int[] result = mTestObject.waitForIntArray(); - assertEquals(2, result.length); - assertEquals(0, result[0]); - assertEquals(0, result[1]); + Assert.assertEquals(2, result.length); + Assert.assertEquals(0, result[0]); + Assert.assertEquals(0, result[1]); } // Verify that ArrayBuffers are not converted into arrays when passed to Java. // The LiveConnect spec doesn't mention ArrayBuffers, so it doesn't seem to // be a compliance issue. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassArrayBuffer() throws Throwable { - executeJavaScript("buffer = new ArrayBuffer(16);"); - executeJavaScript("testObject.setIntArray(buffer);"); - assertNull(mTestObject.waitForIntArray()); + mActivityTestRule.executeJavaScript("buffer = new ArrayBuffer(16);"); + mActivityTestRule.executeJavaScript("testObject.setIntArray(buffer);"); + Assert.assertNull(mTestObject.waitForIntArray()); } // Verify that ArrayBufferViews are not converted into arrays when passed to Java. @@ -258,11 +285,12 @@ // Here, a DataView is used as an ArrayBufferView instance (since the latter is // an interface and can't be instantiated directly). See also JavaBridgeArrayCoercionTest // for typed arrays (that also subclass ArrayBufferView) tests. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassDataView() throws Throwable { - executeJavaScript("buffer = new ArrayBuffer(16);"); - executeJavaScript("testObject.setIntArray(new DataView(buffer));"); - assertNull(mTestObject.waitForIntArray()); + mActivityTestRule.executeJavaScript("buffer = new ArrayBuffer(16);"); + mActivityTestRule.executeJavaScript("testObject.setIntArray(new DataView(buffer));"); + Assert.assertNull(mTestObject.waitForIntArray()); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBareboneTest.java b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBareboneTest.java index 0261302..ae2349e 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBareboneTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBareboneTest.java
@@ -6,33 +6,44 @@ import android.support.test.filters.SmallTest; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.UrlUtils; import org.chromium.content.browser.test.util.TestCallbackHelperContainer; import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper; import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnPageFinishedHelper; -import org.chromium.content_shell_apk.ContentShellTestBase; +import org.chromium.content_shell_apk.ContentShellActivityTestRule; /** * Common functionality for testing the Java Bridge. */ -public class JavaBridgeBareboneTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class JavaBridgeBareboneTest { + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); + private TestCallbackHelperContainer mTestCallbackHelperContainer; - @Override - protected void setUp() throws Exception { - super.setUp(); - launchContentShellWithUrl( + @Before + public void setUp() throws Exception { + mActivityTestRule.launchContentShellWithUrl( UrlUtils.encodeHtmlDataUri("<html><head></head><body>test</body></html>")); - waitForActiveShellToBeDoneLoading(); - mTestCallbackHelperContainer = new TestCallbackHelperContainer(getContentViewCore()); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); + mTestCallbackHelperContainer = + new TestCallbackHelperContainer(mActivityTestRule.getContentViewCore()); } private void injectDummyObject(final String name) throws Throwable { - runTestOnUiThread(new Runnable() { + mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { - getContentViewCore().addPossiblyUnsafeJavascriptInterface( + mActivityTestRule.getContentViewCore().addPossiblyUnsafeJavascriptInterface( new Object(), name, null); } }); @@ -40,7 +51,7 @@ private String evaluateJsSync(String jsCode) throws Exception { OnEvaluateJavaScriptResultHelper javascriptHelper = new OnEvaluateJavaScriptResultHelper(); - javascriptHelper.evaluateJavaScriptForTests(getWebContents(), jsCode); + javascriptHelper.evaluateJavaScriptForTests(mActivityTestRule.getWebContents(), jsCode); javascriptHelper.waitUntilHasValue(); return javascriptHelper.getJsonResultAndClear(); } @@ -49,10 +60,10 @@ OnPageFinishedHelper pageFinishedHelper = mTestCallbackHelperContainer.getOnPageFinishedHelper(); int currentCallCount = pageFinishedHelper.getCallCount(); - runTestOnUiThread(new Runnable() { + mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { - getWebContents().getNavigationController().reload(true); + mActivityTestRule.getWebContents().getNavigationController().reload(true); } }); pageFinishedHelper.waitForCallback(currentCallCount); @@ -69,36 +80,40 @@ // webView.addJavascriptInterface(new Foo(), "foo"); // webView.loadUrl("javascript:foo.bar();void(0);"); // + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testImmediateAddition() throws Throwable { injectDummyObject("testObject"); - assertEquals("\"object\"", evaluateJsSync("typeof testObject")); + Assert.assertEquals("\"object\"", evaluateJsSync("typeof testObject")); } // Now here, we evaluate some JS before injecting the object, and this behaves as // expected. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testNoImmediateAdditionAfterJSEvaluation() throws Throwable { evaluateJsSync("true"); injectDummyObject("testObject"); - assertEquals("\"undefined\"", evaluateJsSync("typeof testObject")); + Assert.assertEquals("\"undefined\"", evaluateJsSync("typeof testObject")); } + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testImmediateAdditionAfterReload() throws Throwable { reloadSync(); injectDummyObject("testObject"); - assertEquals("\"object\"", evaluateJsSync("typeof testObject")); + Assert.assertEquals("\"object\"", evaluateJsSync("typeof testObject")); } + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testReloadAfterAddition() throws Throwable { injectDummyObject("testObject"); reloadSync(); - assertEquals("\"object\"", evaluateJsSync("typeof testObject")); + Assert.assertEquals("\"object\"", evaluateJsSync("typeof testObject")); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java index 075eb59..fcccc896 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java
@@ -8,7 +8,14 @@ import dalvik.system.DexClassLoader; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.chromium.base.annotations.SuppressFBWarnings; +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.UrlUtils; import org.chromium.content.browser.JavaBridgeTestCommon.Controller; @@ -27,7 +34,13 @@ * FIXME: Consider making our implementation more compliant, if it will not * break backwards-compatibility. See b/4408210. */ -public class JavaBridgeCoercionTest extends JavaBridgeTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class JavaBridgeCoercionTest { + private static final double ASSERTION_DELTA = 0; + + @Rule + public JavaBridgeActivityTestRule mActivityTestRule = new JavaBridgeActivityTestRule(); + @SuppressFBWarnings("CHROMIUM_SYNCHRONIZED_METHOD") private static class TestObject extends Controller { private Object mObjectInstance; @@ -179,451 +192,487 @@ // Note that this requires that we can pass a JavaScript boolean to Java. private void assertRaisesException(String script) throws Throwable { - executeJavaScript("try {" - + script + ";" + mActivityTestRule.executeJavaScript("try {" + script + ";" + " testController.setBooleanValue(false);" + "} catch (exception) {" + " testController.setBooleanValue(true);" + "}"); - assertTrue(mTestController.waitForBooleanValue()); + Assert.assertTrue(mTestController.waitForBooleanValue()); } - @Override - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { mTestObject = new TestObject(); mTestController = new TestController(); - injectObjectsAndReload(mTestObject, "testObject", mTestController, "testController", null); + mActivityTestRule.injectObjectsAndReload( + mTestObject, "testObject", mTestController, "testController", null); } // Test passing a 32-bit integer JavaScript number to a method of an // injected object. Note that JavaScript may choose to represent these // values as either 32-bit integers or doubles, though this should not // affect the result. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassNumberInt32() throws Throwable { - executeJavaScript("testObject.setByteValue(42);"); - assertEquals(42, mTestObject.waitForByteValue()); - executeJavaScript("testObject.setByteValue(" + Byte.MAX_VALUE + " + 42);"); - assertEquals(Byte.MIN_VALUE + 42 - 1, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript("testObject.setByteValue(42);"); + Assert.assertEquals(42, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript( + "testObject.setByteValue(" + Byte.MAX_VALUE + " + 42);"); + Assert.assertEquals(Byte.MIN_VALUE + 42 - 1, mTestObject.waitForByteValue()); - executeJavaScript("testObject.setCharValue(42);"); - assertEquals(42, mTestObject.waitForCharValue()); + mActivityTestRule.executeJavaScript("testObject.setCharValue(42);"); + Assert.assertEquals(42, mTestObject.waitForCharValue()); - executeJavaScript("testObject.setShortValue(42);"); - assertEquals(42, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setShortValue(" + Short.MAX_VALUE + " + 42);"); - assertEquals(Short.MIN_VALUE + 42 - 1, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript("testObject.setShortValue(42);"); + Assert.assertEquals(42, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript( + "testObject.setShortValue(" + Short.MAX_VALUE + " + 42);"); + Assert.assertEquals(Short.MIN_VALUE + 42 - 1, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setIntValue(42);"); - assertEquals(42, mTestObject.waitForIntValue()); + mActivityTestRule.executeJavaScript("testObject.setIntValue(42);"); + Assert.assertEquals(42, mTestObject.waitForIntValue()); - executeJavaScript("testObject.setLongValue(42);"); - assertEquals(42L, mTestObject.waitForLongValue()); + mActivityTestRule.executeJavaScript("testObject.setLongValue(42);"); + Assert.assertEquals(42L, mTestObject.waitForLongValue()); - executeJavaScript("testObject.setFloatValue(42);"); - assertEquals(42.0f, mTestObject.waitForFloatValue()); + mActivityTestRule.executeJavaScript("testObject.setFloatValue(42);"); + Assert.assertEquals(42.0f, mTestObject.waitForFloatValue(), ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleValue(42);"); - assertEquals(42.0, mTestObject.waitForDoubleValue()); + mActivityTestRule.executeJavaScript("testObject.setDoubleValue(42);"); + Assert.assertEquals(42.0, mTestObject.waitForDoubleValue(), ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number. - executeJavaScript("testObject.setObjectValue(42);"); - assertNull(mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript("testObject.setObjectValue(42);"); + Assert.assertNull(mTestObject.waitForObjectValue()); // The spec allows the JS engine flexibility in how to format the number. - executeJavaScript("testObject.setStringValue(42);"); + mActivityTestRule.executeJavaScript("testObject.setStringValue(42);"); String str = mTestObject.waitForStringValue(); - assertTrue("42".equals(str) || "42.0".equals(str)); + Assert.assertTrue("42".equals(str) || "42.0".equals(str)); - executeJavaScript("testObject.setBooleanValue(0);"); - assertFalse(mTestObject.waitForBooleanValue()); + mActivityTestRule.executeJavaScript("testObject.setBooleanValue(0);"); + Assert.assertFalse(mTestObject.waitForBooleanValue()); // LIVECONNECT_COMPLIANCE: Should be true; - executeJavaScript("testObject.setBooleanValue(42);"); - assertFalse(mTestObject.waitForBooleanValue()); + mActivityTestRule.executeJavaScript("testObject.setBooleanValue(42);"); + Assert.assertFalse(mTestObject.waitForBooleanValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeValue(42);"); - assertNull(mTestObject.waitForCustomTypeValue()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeValue(42);"); + Assert.assertNull(mTestObject.waitForCustomTypeValue()); } // Test passing a floating-point JavaScript number to a method of an // injected object. JavaScript represents these values as doubles. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassNumberDouble() throws Throwable { - executeJavaScript("testObject.setByteValue(42.1);"); - assertEquals(42, mTestObject.waitForByteValue()); - executeJavaScript("testObject.setByteValue(" + Byte.MAX_VALUE + " + 42.1);"); - assertEquals(Byte.MIN_VALUE + 42 - 1, mTestObject.waitForByteValue()); - executeJavaScript("testObject.setByteValue(" + Byte.MIN_VALUE + " - 42.1);"); - assertEquals(Byte.MAX_VALUE - 42 + 1, mTestObject.waitForByteValue()); - executeJavaScript("testObject.setByteValue(" + Integer.MAX_VALUE + " + 42.1);"); - assertEquals(-1, mTestObject.waitForByteValue()); - executeJavaScript("testObject.setByteValue(" + Integer.MIN_VALUE + " - 42.1);"); - assertEquals(0, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript("testObject.setByteValue(42.1);"); + Assert.assertEquals(42, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript( + "testObject.setByteValue(" + Byte.MAX_VALUE + " + 42.1);"); + Assert.assertEquals(Byte.MIN_VALUE + 42 - 1, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript( + "testObject.setByteValue(" + Byte.MIN_VALUE + " - 42.1);"); + Assert.assertEquals(Byte.MAX_VALUE - 42 + 1, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript( + "testObject.setByteValue(" + Integer.MAX_VALUE + " + 42.1);"); + Assert.assertEquals(-1, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript( + "testObject.setByteValue(" + Integer.MIN_VALUE + " - 42.1);"); + Assert.assertEquals(0, mTestObject.waitForByteValue()); // LIVECONNECT_COMPLIANCE: Should convert to numeric char value. - executeJavaScript("testObject.setCharValue(42.1);"); - assertEquals('\u0000', mTestObject.waitForCharValue()); + mActivityTestRule.executeJavaScript("testObject.setCharValue(42.1);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharValue()); - executeJavaScript("testObject.setShortValue(42.1);"); - assertEquals(42, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setShortValue(" + Short.MAX_VALUE + " + 42.1);"); - assertEquals(Short.MIN_VALUE + 42 - 1, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setShortValue(" + Short.MIN_VALUE + " - 42.1);"); - assertEquals(Short.MAX_VALUE - 42 + 1, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setShortValue(" + Integer.MAX_VALUE + " + 42.1);"); - assertEquals(-1, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setShortValue(" + Integer.MIN_VALUE + " - 42.1);"); - assertEquals(0, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript("testObject.setShortValue(42.1);"); + Assert.assertEquals(42, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript( + "testObject.setShortValue(" + Short.MAX_VALUE + " + 42.1);"); + Assert.assertEquals(Short.MIN_VALUE + 42 - 1, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript( + "testObject.setShortValue(" + Short.MIN_VALUE + " - 42.1);"); + Assert.assertEquals(Short.MAX_VALUE - 42 + 1, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript( + "testObject.setShortValue(" + Integer.MAX_VALUE + " + 42.1);"); + Assert.assertEquals(-1, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript( + "testObject.setShortValue(" + Integer.MIN_VALUE + " - 42.1);"); + Assert.assertEquals(0, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setIntValue(42.1);"); - assertEquals(42, mTestObject.waitForIntValue()); - executeJavaScript("testObject.setIntValue(" + Integer.MAX_VALUE + " + 42.1);"); - assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntValue()); - executeJavaScript("testObject.setIntValue(" + Integer.MIN_VALUE + " - 42.1);"); - assertEquals(Integer.MIN_VALUE, mTestObject.waitForIntValue()); + mActivityTestRule.executeJavaScript("testObject.setIntValue(42.1);"); + Assert.assertEquals(42, mTestObject.waitForIntValue()); + mActivityTestRule.executeJavaScript( + "testObject.setIntValue(" + Integer.MAX_VALUE + " + 42.1);"); + Assert.assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntValue()); + mActivityTestRule.executeJavaScript( + "testObject.setIntValue(" + Integer.MIN_VALUE + " - 42.1);"); + Assert.assertEquals(Integer.MIN_VALUE, mTestObject.waitForIntValue()); - executeJavaScript("testObject.setLongValue(42.1);"); - assertEquals(42L, mTestObject.waitForLongValue()); - executeJavaScript("testObject.setLongValue(" + Long.MAX_VALUE + " + 42.1);"); - assertEquals(Long.MAX_VALUE, mTestObject.waitForLongValue()); - executeJavaScript("testObject.setLongValue(" + Long.MIN_VALUE + " - 42.1);"); - assertEquals(Long.MIN_VALUE, mTestObject.waitForLongValue()); + mActivityTestRule.executeJavaScript("testObject.setLongValue(42.1);"); + Assert.assertEquals(42L, mTestObject.waitForLongValue()); + mActivityTestRule.executeJavaScript( + "testObject.setLongValue(" + Long.MAX_VALUE + " + 42.1);"); + Assert.assertEquals(Long.MAX_VALUE, mTestObject.waitForLongValue()); + mActivityTestRule.executeJavaScript( + "testObject.setLongValue(" + Long.MIN_VALUE + " - 42.1);"); + Assert.assertEquals(Long.MIN_VALUE, mTestObject.waitForLongValue()); - executeJavaScript("testObject.setFloatValue(42.1);"); - assertEquals(42.1f, mTestObject.waitForFloatValue()); + mActivityTestRule.executeJavaScript("testObject.setFloatValue(42.1);"); + Assert.assertEquals(42.1f, mTestObject.waitForFloatValue(), ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleValue(42.1);"); - assertEquals(42.1, mTestObject.waitForDoubleValue()); + mActivityTestRule.executeJavaScript("testObject.setDoubleValue(42.1);"); + Assert.assertEquals(42.1, mTestObject.waitForDoubleValue(), ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number. - executeJavaScript("testObject.setObjectValue(42.1);"); - assertNull(mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript("testObject.setObjectValue(42.1);"); + Assert.assertNull(mTestObject.waitForObjectValue()); - executeJavaScript("testObject.setStringValue(42.1);"); - assertEquals("42.1", mTestObject.waitForStringValue()); + mActivityTestRule.executeJavaScript("testObject.setStringValue(42.1);"); + Assert.assertEquals("42.1", mTestObject.waitForStringValue()); - executeJavaScript("testObject.setBooleanValue(0.0);"); - assertFalse(mTestObject.waitForBooleanValue()); + mActivityTestRule.executeJavaScript("testObject.setBooleanValue(0.0);"); + Assert.assertFalse(mTestObject.waitForBooleanValue()); // LIVECONNECT_COMPLIANCE: Should be true. - executeJavaScript("testObject.setBooleanValue(42.1);"); - assertFalse(mTestObject.waitForBooleanValue()); + mActivityTestRule.executeJavaScript("testObject.setBooleanValue(42.1);"); + Assert.assertFalse(mTestObject.waitForBooleanValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeValue(42.1);"); - assertNull(mTestObject.waitForCustomTypeValue()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeValue(42.1);"); + Assert.assertNull(mTestObject.waitForCustomTypeValue()); } // Test passing JavaScript NaN to a method of an injected object. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassNumberNaN() throws Throwable { - executeJavaScript("testObject.setByteValue(Number.NaN);"); - assertEquals(0, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript("testObject.setByteValue(Number.NaN);"); + Assert.assertEquals(0, mTestObject.waitForByteValue()); - executeJavaScript("testObject.setCharValue(Number.NaN);"); - assertEquals('\u0000', mTestObject.waitForCharValue()); + mActivityTestRule.executeJavaScript("testObject.setCharValue(Number.NaN);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharValue()); - executeJavaScript("testObject.setShortValue(Number.NaN);"); - assertEquals(0, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript("testObject.setShortValue(Number.NaN);"); + Assert.assertEquals(0, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setIntValue(Number.NaN);"); - assertEquals(0, mTestObject.waitForIntValue()); + mActivityTestRule.executeJavaScript("testObject.setIntValue(Number.NaN);"); + Assert.assertEquals(0, mTestObject.waitForIntValue()); - executeJavaScript("testObject.setLongValue(Number.NaN);"); - assertEquals(0L, mTestObject.waitForLongValue()); + mActivityTestRule.executeJavaScript("testObject.setLongValue(Number.NaN);"); + Assert.assertEquals(0L, mTestObject.waitForLongValue()); - executeJavaScript("testObject.setFloatValue(Number.NaN);"); - assertEquals(Float.NaN, mTestObject.waitForFloatValue()); + mActivityTestRule.executeJavaScript("testObject.setFloatValue(Number.NaN);"); + Assert.assertEquals(Float.NaN, mTestObject.waitForFloatValue(), ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleValue(Number.NaN);"); - assertEquals(Double.NaN, mTestObject.waitForDoubleValue()); + mActivityTestRule.executeJavaScript("testObject.setDoubleValue(Number.NaN);"); + Assert.assertEquals(Double.NaN, mTestObject.waitForDoubleValue(), ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number. - executeJavaScript("testObject.setObjectValue(Number.NaN);"); - assertNull(mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript("testObject.setObjectValue(Number.NaN);"); + Assert.assertNull(mTestObject.waitForObjectValue()); - executeJavaScript("testObject.setStringValue(Number.NaN);"); - assertTrue("nan".equalsIgnoreCase(mTestObject.waitForStringValue())); + mActivityTestRule.executeJavaScript("testObject.setStringValue(Number.NaN);"); + Assert.assertTrue("nan".equalsIgnoreCase(mTestObject.waitForStringValue())); - executeJavaScript("testObject.setBooleanValue(Number.NaN);"); - assertFalse(mTestObject.waitForBooleanValue()); + mActivityTestRule.executeJavaScript("testObject.setBooleanValue(Number.NaN);"); + Assert.assertFalse(mTestObject.waitForBooleanValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeValue(Number.NaN);"); - assertNull(mTestObject.waitForCustomTypeValue()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeValue(Number.NaN);"); + Assert.assertNull(mTestObject.waitForCustomTypeValue()); } // Test passing JavaScript infinity to a method of an injected object. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassNumberInfinity() throws Throwable { - executeJavaScript("testObject.setByteValue(Infinity);"); - assertEquals(-1, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript("testObject.setByteValue(Infinity);"); + Assert.assertEquals(-1, mTestObject.waitForByteValue()); // LIVECONNECT_COMPLIANCE: Should convert to maximum numeric char value. - executeJavaScript("testObject.setCharValue(Infinity);"); - assertEquals('\u0000', mTestObject.waitForCharValue()); + mActivityTestRule.executeJavaScript("testObject.setCharValue(Infinity);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharValue()); - executeJavaScript("testObject.setShortValue(Infinity);"); - assertEquals(-1, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript("testObject.setShortValue(Infinity);"); + Assert.assertEquals(-1, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setIntValue(Infinity);"); - assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntValue()); + mActivityTestRule.executeJavaScript("testObject.setIntValue(Infinity);"); + Assert.assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntValue()); - executeJavaScript("testObject.setLongValue(Infinity);"); - assertEquals(Long.MAX_VALUE, mTestObject.waitForLongValue()); + mActivityTestRule.executeJavaScript("testObject.setLongValue(Infinity);"); + Assert.assertEquals(Long.MAX_VALUE, mTestObject.waitForLongValue()); - executeJavaScript("testObject.setFloatValue(Infinity);"); - assertEquals(Float.POSITIVE_INFINITY, mTestObject.waitForFloatValue()); + mActivityTestRule.executeJavaScript("testObject.setFloatValue(Infinity);"); + Assert.assertEquals( + Float.POSITIVE_INFINITY, mTestObject.waitForFloatValue(), ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleValue(Infinity);"); - assertEquals(Double.POSITIVE_INFINITY, mTestObject.waitForDoubleValue()); + mActivityTestRule.executeJavaScript("testObject.setDoubleValue(Infinity);"); + Assert.assertEquals( + Double.POSITIVE_INFINITY, mTestObject.waitForDoubleValue(), ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number. - executeJavaScript("testObject.setObjectValue(Infinity);"); - assertNull(mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript("testObject.setObjectValue(Infinity);"); + Assert.assertNull(mTestObject.waitForObjectValue()); - executeJavaScript("testObject.setStringValue(Infinity);"); - assertTrue("inf".equalsIgnoreCase(mTestObject.waitForStringValue())); + mActivityTestRule.executeJavaScript("testObject.setStringValue(Infinity);"); + Assert.assertTrue("inf".equalsIgnoreCase(mTestObject.waitForStringValue())); - executeJavaScript("testObject.setBooleanValue(Infinity);"); - assertFalse(mTestObject.waitForBooleanValue()); + mActivityTestRule.executeJavaScript("testObject.setBooleanValue(Infinity);"); + Assert.assertFalse(mTestObject.waitForBooleanValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeValue(Infinity);"); - assertNull(mTestObject.waitForCustomTypeValue()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeValue(Infinity);"); + Assert.assertNull(mTestObject.waitForCustomTypeValue()); } // Test passing a JavaScript boolean to a method of an injected object. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassBoolean() throws Throwable { - executeJavaScript("testObject.setBooleanValue(true);"); - assertTrue(mTestObject.waitForBooleanValue()); - executeJavaScript("testObject.setBooleanValue(false);"); - assertFalse(mTestObject.waitForBooleanValue()); + mActivityTestRule.executeJavaScript("testObject.setBooleanValue(true);"); + Assert.assertTrue(mTestObject.waitForBooleanValue()); + mActivityTestRule.executeJavaScript("testObject.setBooleanValue(false);"); + Assert.assertFalse(mTestObject.waitForBooleanValue()); // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Boolean. - executeJavaScript("testObject.setObjectValue(true);"); - assertNull(mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript("testObject.setObjectValue(true);"); + Assert.assertNull(mTestObject.waitForObjectValue()); - executeJavaScript("testObject.setStringValue(false);"); - assertEquals("false", mTestObject.waitForStringValue()); - executeJavaScript("testObject.setStringValue(true);"); - assertEquals("true", mTestObject.waitForStringValue()); + mActivityTestRule.executeJavaScript("testObject.setStringValue(false);"); + Assert.assertEquals("false", mTestObject.waitForStringValue()); + mActivityTestRule.executeJavaScript("testObject.setStringValue(true);"); + Assert.assertEquals("true", mTestObject.waitForStringValue()); // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setByteValue(true);"); - assertEquals(0, mTestObject.waitForByteValue()); - executeJavaScript("testObject.setByteValue(false);"); - assertEquals(0, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript("testObject.setByteValue(true);"); + Assert.assertEquals(0, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript("testObject.setByteValue(false);"); + Assert.assertEquals(0, mTestObject.waitForByteValue()); // LIVECONNECT_COMPLIANCE: Should convert to numeric char value 1. - executeJavaScript("testObject.setCharValue(true);"); - assertEquals('\u0000', mTestObject.waitForCharValue()); - executeJavaScript("testObject.setCharValue(false);"); - assertEquals('\u0000', mTestObject.waitForCharValue()); + mActivityTestRule.executeJavaScript("testObject.setCharValue(true);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharValue()); + mActivityTestRule.executeJavaScript("testObject.setCharValue(false);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharValue()); // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setShortValue(true);"); - assertEquals(0, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setShortValue(false);"); - assertEquals(0, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript("testObject.setShortValue(true);"); + Assert.assertEquals(0, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript("testObject.setShortValue(false);"); + Assert.assertEquals(0, mTestObject.waitForShortValue()); // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setIntValue(true);"); - assertEquals(0, mTestObject.waitForIntValue()); - executeJavaScript("testObject.setIntValue(false);"); - assertEquals(0, mTestObject.waitForIntValue()); + mActivityTestRule.executeJavaScript("testObject.setIntValue(true);"); + Assert.assertEquals(0, mTestObject.waitForIntValue()); + mActivityTestRule.executeJavaScript("testObject.setIntValue(false);"); + Assert.assertEquals(0, mTestObject.waitForIntValue()); // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setLongValue(true);"); - assertEquals(0L, mTestObject.waitForLongValue()); - executeJavaScript("testObject.setLongValue(false);"); - assertEquals(0L, mTestObject.waitForLongValue()); + mActivityTestRule.executeJavaScript("testObject.setLongValue(true);"); + Assert.assertEquals(0L, mTestObject.waitForLongValue()); + mActivityTestRule.executeJavaScript("testObject.setLongValue(false);"); + Assert.assertEquals(0L, mTestObject.waitForLongValue()); // LIVECONNECT_COMPLIANCE: Should be 1.0. - executeJavaScript("testObject.setFloatValue(true);"); - assertEquals(0.0f, mTestObject.waitForFloatValue()); - executeJavaScript("testObject.setFloatValue(false);"); - assertEquals(0.0f, mTestObject.waitForFloatValue()); + mActivityTestRule.executeJavaScript("testObject.setFloatValue(true);"); + Assert.assertEquals(0.0f, mTestObject.waitForFloatValue(), ASSERTION_DELTA); + mActivityTestRule.executeJavaScript("testObject.setFloatValue(false);"); + Assert.assertEquals(0.0f, mTestObject.waitForFloatValue(), ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should be 1.0. - executeJavaScript("testObject.setDoubleValue(true);"); - assertEquals(0.0, mTestObject.waitForDoubleValue()); - executeJavaScript("testObject.setDoubleValue(false);"); - assertEquals(0.0, mTestObject.waitForDoubleValue()); + mActivityTestRule.executeJavaScript("testObject.setDoubleValue(true);"); + Assert.assertEquals(0.0, mTestObject.waitForDoubleValue(), ASSERTION_DELTA); + mActivityTestRule.executeJavaScript("testObject.setDoubleValue(false);"); + Assert.assertEquals(0.0, mTestObject.waitForDoubleValue(), ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeValue(true);"); - assertNull(mTestObject.waitForCustomTypeValue()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeValue(true);"); + Assert.assertNull(mTestObject.waitForCustomTypeValue()); } // Test passing a JavaScript string to a method of an injected object. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassString() throws Throwable { - executeJavaScript("testObject.setStringValue(\"+042.10\");"); - assertEquals("+042.10", mTestObject.waitForStringValue()); + mActivityTestRule.executeJavaScript("testObject.setStringValue(\"+042.10\");"); + Assert.assertEquals("+042.10", mTestObject.waitForStringValue()); // Make sure that we distinguish between the empty string and NULL. - executeJavaScript("testObject.setStringValue(\"\");"); - assertEquals("", mTestObject.waitForStringValue()); + mActivityTestRule.executeJavaScript("testObject.setStringValue(\"\");"); + Assert.assertEquals("", mTestObject.waitForStringValue()); // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.String. - executeJavaScript("testObject.setObjectValue(\"+042.10\");"); - assertNull(mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript("testObject.setObjectValue(\"+042.10\");"); + Assert.assertNull(mTestObject.waitForObjectValue()); // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setByteValue(\"+042.10\");"); - assertEquals(0, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript("testObject.setByteValue(\"+042.10\");"); + Assert.assertEquals(0, mTestObject.waitForByteValue()); // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setShortValue(\"+042.10\");"); - assertEquals(0, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript("testObject.setShortValue(\"+042.10\");"); + Assert.assertEquals(0, mTestObject.waitForShortValue()); // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setIntValue(\"+042.10\");"); - assertEquals(0, mTestObject.waitForIntValue()); + mActivityTestRule.executeJavaScript("testObject.setIntValue(\"+042.10\");"); + Assert.assertEquals(0, mTestObject.waitForIntValue()); // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setLongValue(\"+042.10\");"); - assertEquals(0L, mTestObject.waitForLongValue()); + mActivityTestRule.executeJavaScript("testObject.setLongValue(\"+042.10\");"); + Assert.assertEquals(0L, mTestObject.waitForLongValue()); // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setFloatValue(\"+042.10\");"); - assertEquals(0.0f, mTestObject.waitForFloatValue()); + mActivityTestRule.executeJavaScript("testObject.setFloatValue(\"+042.10\");"); + Assert.assertEquals(0.0f, mTestObject.waitForFloatValue(), ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setDoubleValue(\"+042.10\");"); - assertEquals(0.0, mTestObject.waitForDoubleValue()); + mActivityTestRule.executeJavaScript("testObject.setDoubleValue(\"+042.10\");"); + Assert.assertEquals(0.0, mTestObject.waitForDoubleValue(), ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should decode and convert to numeric char value. - executeJavaScript("testObject.setCharValue(\"+042.10\");"); - assertEquals('\u0000', mTestObject.waitForCharValue()); + mActivityTestRule.executeJavaScript("testObject.setCharValue(\"+042.10\");"); + Assert.assertEquals('\u0000', mTestObject.waitForCharValue()); // LIVECONNECT_COMPLIANCE: Non-empty string should convert to true. - executeJavaScript("testObject.setBooleanValue(\"+042.10\");"); - assertFalse(mTestObject.waitForBooleanValue()); + mActivityTestRule.executeJavaScript("testObject.setBooleanValue(\"+042.10\");"); + Assert.assertFalse(mTestObject.waitForBooleanValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeValue(\"+042.10\");"); - assertNull(mTestObject.waitForCustomTypeValue()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeValue(\"+042.10\");"); + Assert.assertNull(mTestObject.waitForCustomTypeValue()); } // Test passing a JavaScript object to a method of an injected object. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassJavaScriptObject() throws Throwable { // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setObjectValue({foo: 42});"); - assertNull(mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript("testObject.setObjectValue({foo: 42});"); + Assert.assertNull(mTestObject.waitForObjectValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeValue({foo: 42});"); - assertNull(mTestObject.waitForCustomTypeValue()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeValue({foo: 42});"); + Assert.assertNull(mTestObject.waitForCustomTypeValue()); // LIVECONNECT_COMPLIANCE: Should call toString() on object. - executeJavaScript("testObject.setStringValue({foo: 42});"); - assertEquals("undefined", mTestObject.waitForStringValue()); + mActivityTestRule.executeJavaScript("testObject.setStringValue({foo: 42});"); + Assert.assertEquals("undefined", mTestObject.waitForStringValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setByteValue({foo: 42});"); - assertEquals(0, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript("testObject.setByteValue({foo: 42});"); + Assert.assertEquals(0, mTestObject.waitForByteValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCharValue({foo: 42});"); - assertEquals('\u0000', mTestObject.waitForCharValue()); + mActivityTestRule.executeJavaScript("testObject.setCharValue({foo: 42});"); + Assert.assertEquals('\u0000', mTestObject.waitForCharValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setShortValue({foo: 42});"); - assertEquals(0, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript("testObject.setShortValue({foo: 42});"); + Assert.assertEquals(0, mTestObject.waitForShortValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setIntValue({foo: 42});"); - assertEquals(0, mTestObject.waitForIntValue()); + mActivityTestRule.executeJavaScript("testObject.setIntValue({foo: 42});"); + Assert.assertEquals(0, mTestObject.waitForIntValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setLongValue({foo: 42});"); - assertEquals(0L, mTestObject.waitForLongValue()); + mActivityTestRule.executeJavaScript("testObject.setLongValue({foo: 42});"); + Assert.assertEquals(0L, mTestObject.waitForLongValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setFloatValue({foo: 42});"); - assertEquals(0.0f, mTestObject.waitForFloatValue()); + mActivityTestRule.executeJavaScript("testObject.setFloatValue({foo: 42});"); + Assert.assertEquals(0.0f, mTestObject.waitForFloatValue(), ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setDoubleValue({foo: 42});"); - assertEquals(0.0, mTestObject.waitForDoubleValue()); + mActivityTestRule.executeJavaScript("testObject.setDoubleValue({foo: 42});"); + Assert.assertEquals(0.0, mTestObject.waitForDoubleValue(), ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setBooleanValue({foo: 42});"); - assertFalse(mTestObject.waitForBooleanValue()); + mActivityTestRule.executeJavaScript("testObject.setBooleanValue({foo: 42});"); + Assert.assertFalse(mTestObject.waitForBooleanValue()); } // Test passing a Java object to a method of an injected object. Note that // this test requires being able to return objects from the methods of // injected objects. This is tested elsewhere. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassJavaObject() throws Throwable { - executeJavaScript("testObject.setObjectValue(testObject.getObjectInstance());"); - assertTrue(mTestObject.getObjectInstance() == mTestObject.waitForObjectValue()); - executeJavaScript("testObject.setObjectValue(testObject.getCustomTypeInstance());"); - assertTrue(mTestObject.getCustomTypeInstance() == mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript( + "testObject.setObjectValue(testObject.getObjectInstance());"); + Assert.assertTrue(mTestObject.getObjectInstance() == mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript( + "testObject.setObjectValue(testObject.getCustomTypeInstance());"); + Assert.assertTrue(mTestObject.getCustomTypeInstance() == mTestObject.waitForObjectValue()); assertRaisesException("testObject.setCustomTypeValue(testObject.getObjectInstance());"); - executeJavaScript("testObject.setCustomTypeValue(testObject.getCustomTypeInstance());"); - assertTrue(mTestObject.getCustomTypeInstance() == mTestObject.waitForCustomTypeValue()); + mActivityTestRule.executeJavaScript( + "testObject.setCustomTypeValue(testObject.getCustomTypeInstance());"); + Assert.assertTrue( + mTestObject.getCustomTypeInstance() == mTestObject.waitForCustomTypeValue()); assertRaisesException( "testObject.setCustomTypeValue(testObject.getCustomType2Instance());"); // LIVECONNECT_COMPLIANCE: Should call toString() on object. - executeJavaScript("testObject.setStringValue(testObject.getObjectInstance());"); - assertEquals("undefined", mTestObject.waitForStringValue()); + mActivityTestRule.executeJavaScript( + "testObject.setStringValue(testObject.getObjectInstance());"); + Assert.assertEquals("undefined", mTestObject.waitForStringValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setByteValue(testObject.getObjectInstance());"); - assertEquals(0, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript( + "testObject.setByteValue(testObject.getObjectInstance());"); + Assert.assertEquals(0, mTestObject.waitForByteValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCharValue(testObject.getObjectInstance());"); - assertEquals('\u0000', mTestObject.waitForCharValue()); + mActivityTestRule.executeJavaScript( + "testObject.setCharValue(testObject.getObjectInstance());"); + Assert.assertEquals('\u0000', mTestObject.waitForCharValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setShortValue(testObject.getObjectInstance());"); - assertEquals(0, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript( + "testObject.setShortValue(testObject.getObjectInstance());"); + Assert.assertEquals(0, mTestObject.waitForShortValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setIntValue(testObject.getObjectInstance());"); - assertEquals(0, mTestObject.waitForIntValue()); + mActivityTestRule.executeJavaScript( + "testObject.setIntValue(testObject.getObjectInstance());"); + Assert.assertEquals(0, mTestObject.waitForIntValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setLongValue(testObject.getObjectInstance());"); - assertEquals(0L, mTestObject.waitForLongValue()); + mActivityTestRule.executeJavaScript( + "testObject.setLongValue(testObject.getObjectInstance());"); + Assert.assertEquals(0L, mTestObject.waitForLongValue()); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setFloatValue(testObject.getObjectInstance());"); - assertEquals(0.0f, mTestObject.waitForFloatValue()); + mActivityTestRule.executeJavaScript( + "testObject.setFloatValue(testObject.getObjectInstance());"); + Assert.assertEquals(0.0f, mTestObject.waitForFloatValue(), ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setDoubleValue(testObject.getObjectInstance());"); - assertEquals(0.0, mTestObject.waitForDoubleValue()); + mActivityTestRule.executeJavaScript( + "testObject.setDoubleValue(testObject.getObjectInstance());"); + Assert.assertEquals(0.0, mTestObject.waitForDoubleValue(), ASSERTION_DELTA); // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setBooleanValue(testObject.getObjectInstance());"); - assertFalse(mTestObject.waitForBooleanValue()); + mActivityTestRule.executeJavaScript( + "testObject.setBooleanValue(testObject.getObjectInstance());"); + Assert.assertFalse(mTestObject.waitForBooleanValue()); } static void assertFileIsReadable(String filePath) { File file = new File(filePath); try { - assertTrue("Test file \"" + filePath + "\" is not readable.", file.canRead()); + Assert.assertTrue("Test file \"" + filePath + "\" is not readable.", file.canRead()); } catch (SecurityException e) { - fail("Got a SecurityException for \"" + filePath + "\": " + e.toString()); + Assert.fail("Got a SecurityException for \"" + filePath + "\": " + e.toString()); } } @@ -632,6 +681,7 @@ // WebView and the app use different class loaders, thus we need to make // sure that WebView code doesn't attempt to find an app's class using // its own class loader. See crbug.com/491800. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassJavaObjectFromCustomClassLoader() throws Throwable { @@ -649,167 +699,174 @@ final String dexFileName = "content/test/data/android/SelfConsumingObject.dex"; assertFileIsReadable(UrlUtils.getIsolatedTestFilePath(dexFileName)); final File optimizedDir = File.createTempFile("optimized", ""); - assertTrue(optimizedDir.delete()); - assertTrue(optimizedDir.mkdirs()); + Assert.assertTrue(optimizedDir.delete()); + Assert.assertTrue(optimizedDir.mkdirs()); DexClassLoader loader = new DexClassLoader(UrlUtils.getIsolatedTestFilePath(dexFileName), optimizedDir.getAbsolutePath(), null, ClassLoader.getSystemClassLoader()); final Object selfConsuming = loader.loadClass( "org.example.SelfConsumingObject").newInstance(); - runTestOnUiThread(new Runnable() { + mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { - getContentViewCore().addPossiblyUnsafeJavascriptInterface( + mActivityTestRule.getContentViewCore().addPossiblyUnsafeJavascriptInterface( selfConsuming, "selfConsuming", null); } }); - synchronousPageReload(); - executeJavaScript("testObject.setBooleanValue(" + mActivityTestRule.synchronousPageReload(); + mActivityTestRule.executeJavaScript("testObject.setBooleanValue(" + "selfConsuming.verifySelf(selfConsuming.getSelf()));"); - assertTrue(mTestObject.waitForBooleanValue()); + Assert.assertTrue(mTestObject.waitForBooleanValue()); } // Test passing JavaScript null to a method of an injected object. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassNull() throws Throwable { - executeJavaScript("testObject.setObjectValue(null);"); - assertNull(mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript("testObject.setObjectValue(null);"); + Assert.assertNull(mTestObject.waitForObjectValue()); - executeJavaScript("testObject.setCustomTypeValue(null);"); - assertNull(mTestObject.waitForCustomTypeValue()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeValue(null);"); + Assert.assertNull(mTestObject.waitForCustomTypeValue()); - executeJavaScript("testObject.setStringValue(null);"); - assertNull(mTestObject.waitForStringValue()); + mActivityTestRule.executeJavaScript("testObject.setStringValue(null);"); + Assert.assertNull(mTestObject.waitForStringValue()); - executeJavaScript("testObject.setByteValue(null);"); - assertEquals(0, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript("testObject.setByteValue(null);"); + Assert.assertEquals(0, mTestObject.waitForByteValue()); - executeJavaScript("testObject.setCharValue(null);"); - assertEquals('\u0000', mTestObject.waitForCharValue()); + mActivityTestRule.executeJavaScript("testObject.setCharValue(null);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharValue()); - executeJavaScript("testObject.setShortValue(null);"); - assertEquals(0, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript("testObject.setShortValue(null);"); + Assert.assertEquals(0, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setIntValue(null);"); - assertEquals(0, mTestObject.waitForIntValue()); + mActivityTestRule.executeJavaScript("testObject.setIntValue(null);"); + Assert.assertEquals(0, mTestObject.waitForIntValue()); - executeJavaScript("testObject.setLongValue(null);"); - assertEquals(0L, mTestObject.waitForLongValue()); + mActivityTestRule.executeJavaScript("testObject.setLongValue(null);"); + Assert.assertEquals(0L, mTestObject.waitForLongValue()); - executeJavaScript("testObject.setFloatValue(null);"); - assertEquals(0.0f, mTestObject.waitForFloatValue()); + mActivityTestRule.executeJavaScript("testObject.setFloatValue(null);"); + Assert.assertEquals(0.0f, mTestObject.waitForFloatValue(), ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleValue(null);"); - assertEquals(0.0, mTestObject.waitForDoubleValue()); + mActivityTestRule.executeJavaScript("testObject.setDoubleValue(null);"); + Assert.assertEquals(0.0, mTestObject.waitForDoubleValue(), ASSERTION_DELTA); - executeJavaScript("testObject.setBooleanValue(null);"); - assertFalse(mTestObject.waitForBooleanValue()); + mActivityTestRule.executeJavaScript("testObject.setBooleanValue(null);"); + Assert.assertFalse(mTestObject.waitForBooleanValue()); } // Test passing JavaScript undefined to a method of an injected object. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassUndefined() throws Throwable { - executeJavaScript("testObject.setObjectValue(undefined);"); - assertNull(mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript("testObject.setObjectValue(undefined);"); + Assert.assertNull(mTestObject.waitForObjectValue()); - executeJavaScript("testObject.setCustomTypeValue(undefined);"); - assertNull(mTestObject.waitForCustomTypeValue()); + mActivityTestRule.executeJavaScript("testObject.setCustomTypeValue(undefined);"); + Assert.assertNull(mTestObject.waitForCustomTypeValue()); // LIVECONNECT_COMPLIANCE: Should be NULL. - executeJavaScript("testObject.setStringValue(undefined);"); - assertEquals("undefined", mTestObject.waitForStringValue()); + mActivityTestRule.executeJavaScript("testObject.setStringValue(undefined);"); + Assert.assertEquals("undefined", mTestObject.waitForStringValue()); - executeJavaScript("testObject.setByteValue(undefined);"); - assertEquals(0, mTestObject.waitForByteValue()); + mActivityTestRule.executeJavaScript("testObject.setByteValue(undefined);"); + Assert.assertEquals(0, mTestObject.waitForByteValue()); - executeJavaScript("testObject.setCharValue(undefined);"); - assertEquals('\u0000', mTestObject.waitForCharValue()); + mActivityTestRule.executeJavaScript("testObject.setCharValue(undefined);"); + Assert.assertEquals('\u0000', mTestObject.waitForCharValue()); - executeJavaScript("testObject.setShortValue(undefined);"); - assertEquals(0, mTestObject.waitForShortValue()); + mActivityTestRule.executeJavaScript("testObject.setShortValue(undefined);"); + Assert.assertEquals(0, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setIntValue(undefined);"); - assertEquals(0, mTestObject.waitForIntValue()); + mActivityTestRule.executeJavaScript("testObject.setIntValue(undefined);"); + Assert.assertEquals(0, mTestObject.waitForIntValue()); - executeJavaScript("testObject.setLongValue(undefined);"); - assertEquals(0L, mTestObject.waitForLongValue()); + mActivityTestRule.executeJavaScript("testObject.setLongValue(undefined);"); + Assert.assertEquals(0L, mTestObject.waitForLongValue()); - executeJavaScript("testObject.setFloatValue(undefined);"); - assertEquals(0.0f, mTestObject.waitForFloatValue()); + mActivityTestRule.executeJavaScript("testObject.setFloatValue(undefined);"); + Assert.assertEquals(0.0f, mTestObject.waitForFloatValue(), ASSERTION_DELTA); - executeJavaScript("testObject.setDoubleValue(undefined);"); - assertEquals(0.0, mTestObject.waitForDoubleValue()); + mActivityTestRule.executeJavaScript("testObject.setDoubleValue(undefined);"); + Assert.assertEquals(0.0, mTestObject.waitForDoubleValue(), ASSERTION_DELTA); - executeJavaScript("testObject.setBooleanValue(undefined);"); - assertFalse(mTestObject.waitForBooleanValue()); + mActivityTestRule.executeJavaScript("testObject.setBooleanValue(undefined);"); + Assert.assertFalse(mTestObject.waitForBooleanValue()); } // Verify that ArrayBuffers are not converted into objects or strings when passed // to Java. Basically, ArrayBuffers are treated as generic JavaScript objects. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassArrayBuffer() throws Throwable { - executeJavaScript("buffer = new ArrayBuffer(16);"); + mActivityTestRule.executeJavaScript("buffer = new ArrayBuffer(16);"); - executeJavaScript("testObject.setObjectValue(buffer);"); - assertNull(mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript("testObject.setObjectValue(buffer);"); + Assert.assertNull(mTestObject.waitForObjectValue()); - executeJavaScript("testObject.setStringValue(buffer);"); - assertEquals("undefined", mTestObject.waitForStringValue()); + mActivityTestRule.executeJavaScript("testObject.setStringValue(buffer);"); + Assert.assertEquals("undefined", mTestObject.waitForStringValue()); } // Verify that ArrayBufferViewss are not converted into objects or strings when passed // to Java. Basically, ArrayBufferViews are treated as generic JavaScript objects. // Here, a DataView is used as an ArrayBufferView instance (since the latter is // an interface and can't be instantiated directly). + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassDataView() throws Throwable { - executeJavaScript("buffer = new ArrayBuffer(16);"); + mActivityTestRule.executeJavaScript("buffer = new ArrayBuffer(16);"); - executeJavaScript("testObject.setObjectValue(new DataView(buffer));"); - assertNull(mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript("testObject.setObjectValue(new DataView(buffer));"); + Assert.assertNull(mTestObject.waitForObjectValue()); - executeJavaScript("testObject.setStringValue(new DataView(buffer));"); - assertEquals("undefined", mTestObject.waitForStringValue()); + mActivityTestRule.executeJavaScript("testObject.setStringValue(new DataView(buffer));"); + Assert.assertEquals("undefined", mTestObject.waitForStringValue()); } // Verify that Date objects are not converted into double values, strings or objects. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassDateObject() throws Throwable { - executeJavaScript("testObject.setDoubleValue(new Date(2000, 0, 1));"); - assertEquals(0.0, mTestObject.waitForDoubleValue()); + mActivityTestRule.executeJavaScript("testObject.setDoubleValue(new Date(2000, 0, 1));"); + Assert.assertEquals(0.0, mTestObject.waitForDoubleValue(), ASSERTION_DELTA); - executeJavaScript("testObject.setStringValue(new Date(2000, 0, 1));"); - assertEquals("undefined", mTestObject.waitForStringValue()); + mActivityTestRule.executeJavaScript("testObject.setStringValue(new Date(2000, 0, 1));"); + Assert.assertEquals("undefined", mTestObject.waitForStringValue()); - executeJavaScript("testObject.setObjectValue(new Date(2000, 0, 1));"); - assertNull(mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript("testObject.setObjectValue(new Date(2000, 0, 1));"); + Assert.assertNull(mTestObject.waitForObjectValue()); } // Verify that RegExp objects are not converted into strings or objects. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassRegExpObject() throws Throwable { - executeJavaScript("testObject.setStringValue(/abc/);"); - assertEquals("undefined", mTestObject.waitForStringValue()); + mActivityTestRule.executeJavaScript("testObject.setStringValue(/abc/);"); + Assert.assertEquals("undefined", mTestObject.waitForStringValue()); - executeJavaScript("testObject.setObjectValue(/abc/);"); - assertNull(mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript("testObject.setObjectValue(/abc/);"); + Assert.assertNull(mTestObject.waitForObjectValue()); } // Verify that Function objects are not converted into strings or objects. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testPassFunctionObject() throws Throwable { - executeJavaScript("func = new Function('a', 'b', 'return a + b');"); + mActivityTestRule.executeJavaScript("func = new Function('a', 'b', 'return a + b');"); - executeJavaScript("testObject.setStringValue(func);"); - assertEquals("undefined", mTestObject.waitForStringValue()); + mActivityTestRule.executeJavaScript("testObject.setStringValue(func);"); + Assert.assertEquals("undefined", mTestObject.waitForStringValue()); - executeJavaScript("testObject.setObjectValue(func);"); - assertNull(mTestObject.waitForObjectValue()); + mActivityTestRule.executeJavaScript("testObject.setObjectValue(func);"); + Assert.assertNull(mTestObject.waitForObjectValue()); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeFieldsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeFieldsTest.java index e1cb4b21..6f9a6de 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeFieldsTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeFieldsTest.java
@@ -6,7 +6,14 @@ import android.support.test.filters.SmallTest; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.chromium.base.annotations.SuppressFBWarnings; +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.content.browser.JavaBridgeTestCommon.Controller; @@ -14,7 +21,11 @@ * Part of the test suite for the Java Bridge. This test tests the * use of fields. */ -public class JavaBridgeFieldsTest extends JavaBridgeTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class JavaBridgeFieldsTest { + @Rule + public JavaBridgeActivityTestRule mActivityTestRule = new JavaBridgeActivityTestRule(); + @SuppressFBWarnings({"CHROMIUM_SYNCHRONIZED_METHOD", "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD"}) private static class TestObject extends Controller { private String mStringValue; @@ -48,45 +59,45 @@ TestObject mTestObject; - @Override - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { mTestObject = new TestObject(); - injectObjectAndReload(mTestObject, "testObject"); + mActivityTestRule.injectObjectAndReload(mTestObject, "testObject"); } // Note that this requires that we can pass a JavaScript string to Java. protected String executeJavaScriptAndGetStringResult(String script) throws Throwable { - executeJavaScript("testObject.setStringValue(" + script + ");"); + mActivityTestRule.executeJavaScript("testObject.setStringValue(" + script + ");"); return mTestObject.waitForStringValue(); } // The Java bridge does not provide access to fields. // FIXME: Consider providing support for this. See See b/4408210. + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testFieldTypes() throws Throwable { - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.booleanField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.byteField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.charField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.shortField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.intField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.longField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.floatField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.doubleField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.objectField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.stringField")); - assertEquals("undefined", + Assert.assertEquals( + "undefined", executeJavaScriptAndGetStringResult("typeof testObject.booleanField")); + Assert.assertEquals( + "undefined", executeJavaScriptAndGetStringResult("typeof testObject.byteField")); + Assert.assertEquals( + "undefined", executeJavaScriptAndGetStringResult("typeof testObject.charField")); + Assert.assertEquals( + "undefined", executeJavaScriptAndGetStringResult("typeof testObject.shortField")); + Assert.assertEquals( + "undefined", executeJavaScriptAndGetStringResult("typeof testObject.intField")); + Assert.assertEquals( + "undefined", executeJavaScriptAndGetStringResult("typeof testObject.longField")); + Assert.assertEquals( + "undefined", executeJavaScriptAndGetStringResult("typeof testObject.floatField")); + Assert.assertEquals( + "undefined", executeJavaScriptAndGetStringResult("typeof testObject.doubleField")); + Assert.assertEquals( + "undefined", executeJavaScriptAndGetStringResult("typeof testObject.objectField")); + Assert.assertEquals( + "undefined", executeJavaScriptAndGetStringResult("typeof testObject.stringField")); + Assert.assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject.customTypeField")); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeReturnValuesTest.java b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeReturnValuesTest.java index 3b46841..904e4538 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeReturnValuesTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeReturnValuesTest.java
@@ -6,7 +6,14 @@ import android.support.test.filters.SmallTest; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.chromium.base.annotations.SuppressFBWarnings; +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.content.browser.JavaBridgeTestCommon.Controller; @@ -21,7 +28,11 @@ * FIXME: Consider making our implementation more compliant, if it will not * break backwards-compatibility. See b/4408210. */ -public class JavaBridgeReturnValuesTest extends JavaBridgeTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class JavaBridgeReturnValuesTest { + @Rule + public JavaBridgeActivityTestRule mActivityTestRule = new JavaBridgeActivityTestRule(); + // An instance of this class is injected into the page to test returning // Java values to JavaScript. @SuppressFBWarnings("CHROMIUM_SYNCHRONIZED_METHOD") @@ -105,88 +116,93 @@ TestObject mTestObject; - @Override - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { mTestObject = new TestObject(); - injectObjectAndReload(mTestObject, "testObject"); + mActivityTestRule.injectObjectAndReload(mTestObject, "testObject"); } // Note that this requires that we can pass a JavaScript string to Java. protected String executeJavaScriptAndGetStringResult(String script) throws Throwable { - executeJavaScript("testObject.setStringResult(" + script + ");"); + mActivityTestRule.executeJavaScript("testObject.setStringResult(" + script + ");"); return mTestObject.waitForStringResult(); } // Note that this requires that we can pass a JavaScript boolean to Java. private boolean executeJavaScriptAndGetBooleanResult(String script) throws Throwable { - executeJavaScript("testObject.setBooleanResult(" + script + ");"); + mActivityTestRule.executeJavaScript("testObject.setBooleanResult(" + script + ");"); return mTestObject.waitForBooleanResult(); } + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testMethodReturnTypes() throws Throwable { - assertEquals("boolean", + Assert.assertEquals("boolean", executeJavaScriptAndGetStringResult("typeof testObject.getBooleanValue()")); - assertEquals("number", - executeJavaScriptAndGetStringResult("typeof testObject.getByteValue()")); + Assert.assertEquals( + "number", executeJavaScriptAndGetStringResult("typeof testObject.getByteValue()")); // char values are returned to JavaScript as numbers. - assertEquals("number", - executeJavaScriptAndGetStringResult("typeof testObject.getCharValue()")); - assertEquals("number", - executeJavaScriptAndGetStringResult("typeof testObject.getShortValue()")); - assertEquals("number", - executeJavaScriptAndGetStringResult("typeof testObject.getIntValue()")); - assertEquals("number", - executeJavaScriptAndGetStringResult("typeof testObject.getLongValue()")); - assertEquals("number", - executeJavaScriptAndGetStringResult("typeof testObject.getFloatValue()")); - assertEquals("number", + Assert.assertEquals( + "number", executeJavaScriptAndGetStringResult("typeof testObject.getCharValue()")); + Assert.assertEquals( + "number", executeJavaScriptAndGetStringResult("typeof testObject.getShortValue()")); + Assert.assertEquals( + "number", executeJavaScriptAndGetStringResult("typeof testObject.getIntValue()")); + Assert.assertEquals( + "number", executeJavaScriptAndGetStringResult("typeof testObject.getLongValue()")); + Assert.assertEquals( + "number", executeJavaScriptAndGetStringResult("typeof testObject.getFloatValue()")); + Assert.assertEquals("number", executeJavaScriptAndGetStringResult("typeof testObject.getFloatValueNoDecimal()")); - assertEquals("number", + Assert.assertEquals("number", executeJavaScriptAndGetStringResult("typeof testObject.getDoubleValue()")); - assertEquals("number", + Assert.assertEquals("number", executeJavaScriptAndGetStringResult("typeof testObject.getDoubleValueNoDecimal()")); - assertEquals("string", + Assert.assertEquals("string", executeJavaScriptAndGetStringResult("typeof testObject.getStringValue()")); - assertEquals("string", + Assert.assertEquals("string", executeJavaScriptAndGetStringResult("typeof testObject.getEmptyStringValue()")); // LIVECONNECT_COMPLIANCE: This should have type object. - assertEquals("undefined", + Assert.assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject.getNullStringValue()")); - assertEquals("object", + Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject.getObjectValue()")); - assertEquals("object", + Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject.getNullObjectValue()")); - assertEquals("object", + Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject.getCustomTypeValue()")); - assertEquals("undefined", + Assert.assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject.getVoidValue()")); } + @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) public void testMethodReturnValues() throws Throwable { // We do the string comparison in JavaScript, to avoid relying on the // coercion algorithm from JavaScript to Java. - assertTrue(executeJavaScriptAndGetBooleanResult("testObject.getBooleanValue()")); - assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getByteValue()")); + Assert.assertTrue(executeJavaScriptAndGetBooleanResult("testObject.getBooleanValue()")); + Assert.assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getByteValue()")); // char values are returned to JavaScript as numbers. - assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getCharValue()")); - assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getShortValue()")); - assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getIntValue()")); - assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getLongValue()")); - assertTrue(executeJavaScriptAndGetBooleanResult( + Assert.assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getCharValue()")); + Assert.assertTrue( + executeJavaScriptAndGetBooleanResult("42 === testObject.getShortValue()")); + Assert.assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getIntValue()")); + Assert.assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getLongValue()")); + Assert.assertTrue(executeJavaScriptAndGetBooleanResult( "Math.abs(42.1 - testObject.getFloatValue()) < 0.001")); - assertTrue(executeJavaScriptAndGetBooleanResult( + Assert.assertTrue(executeJavaScriptAndGetBooleanResult( "42.0 === testObject.getFloatValueNoDecimal()")); - assertTrue(executeJavaScriptAndGetBooleanResult( + Assert.assertTrue(executeJavaScriptAndGetBooleanResult( "Math.abs(42.1 - testObject.getDoubleValue()) < 0.001")); - assertTrue(executeJavaScriptAndGetBooleanResult( + Assert.assertTrue(executeJavaScriptAndGetBooleanResult( "42.0 === testObject.getDoubleValueNoDecimal()")); - assertEquals("foo", executeJavaScriptAndGetStringResult("testObject.getStringValue()")); - assertEquals("", executeJavaScriptAndGetStringResult("testObject.getEmptyStringValue()")); - assertTrue(executeJavaScriptAndGetBooleanResult("undefined === testObject.getVoidValue()")); + Assert.assertEquals( + "foo", executeJavaScriptAndGetStringResult("testObject.getStringValue()")); + Assert.assertEquals( + "", executeJavaScriptAndGetStringResult("testObject.getEmptyStringValue()")); + Assert.assertTrue( + executeJavaScriptAndGetBooleanResult("undefined === testObject.getVoidValue()")); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/MediaResourceGetterTest.java b/content/public/android/javatests/src/org/chromium/content/browser/MediaResourceGetterTest.java index 6d99aff..3b6775dc 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/MediaResourceGetterTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/MediaResourceGetterTest.java
@@ -1,4 +1,4 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. +// Copyright 2012 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. @@ -11,10 +11,15 @@ import android.net.ConnectivityManager; import android.net.Uri; import android.support.test.filters.SmallTest; -import android.test.InstrumentationTestCase; import android.test.mock.MockContext; import android.util.SparseArray; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.content.browser.MediaResourceGetter.MediaMetadata; import java.io.File; @@ -25,8 +30,9 @@ /** * Tests for MediaResourceGetter. */ +@RunWith(BaseJUnit4ClassRunner.class) @SuppressLint("SdCardPath") -public class MediaResourceGetterTest extends InstrumentationTestCase { +public class MediaResourceGetterTest { private static final String TEST_HTTP_URL = "http://example.com"; private static final String TEST_USER_AGENT = // Anything, really "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 " @@ -207,8 +213,7 @@ boolean mAllowPermission = false; @Override public int checkCallingOrSelfPermission(String permission) { - assertEquals(android.Manifest.permission.ACCESS_NETWORK_STATE, - permission); + Assert.assertEquals(android.Manifest.permission.ACCESS_NETWORK_STATE, permission); return mAllowPermission ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED; } @@ -223,153 +228,166 @@ private FakeMediaResourceGetter mFakeMRG; private InternalMockContext mMockContext; - @Override - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { mFakeMRG = new FakeMediaResourceGetter(); mMockContext = new InternalMockContext(); } + @Test @SmallTest public void testMediaMetadataEquals() { - assertEquals(sEmptyMetadata, sEmptyMetadata); - assertEquals(sEmptyMetadata, new MediaMetadata(0, 0, 0, false)); - assertFalse(sEmptyMetadata.equals(null)); - assertFalse(sEmptyMetadata.equals("test")); - assertFalse(sEmptyMetadata.equals(new MediaMetadata(1, 0, 0, false))); - assertFalse(sEmptyMetadata.equals(new MediaMetadata(0, 1, 0, false))); - assertFalse(sEmptyMetadata.equals(new MediaMetadata(0, 0, 1, false))); - assertFalse(sEmptyMetadata.equals(new MediaMetadata(0, 0, 0, true))); + Assert.assertEquals(sEmptyMetadata, sEmptyMetadata); + Assert.assertEquals(sEmptyMetadata, new MediaMetadata(0, 0, 0, false)); + Assert.assertFalse(sEmptyMetadata.equals(null)); + Assert.assertFalse(sEmptyMetadata.equals("test")); + Assert.assertFalse(sEmptyMetadata.equals(new MediaMetadata(1, 0, 0, false))); + Assert.assertFalse(sEmptyMetadata.equals(new MediaMetadata(0, 1, 0, false))); + Assert.assertFalse(sEmptyMetadata.equals(new MediaMetadata(0, 0, 1, false))); + Assert.assertFalse(sEmptyMetadata.equals(new MediaMetadata(0, 0, 0, true))); } + @Test @SmallTest public void testMediaMetadataHashCode() { - assertEquals(sEmptyMetadata.hashCode(), sEmptyMetadata.hashCode()); - assertEquals(sEmptyMetadata.hashCode(), new MediaMetadata(0, 0, 0, false).hashCode()); - assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(1, 0, 0, false).hashCode()); - assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(0, 1, 0, false).hashCode()); - assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(0, 0, 1, false).hashCode()); - assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(0, 0, 0, true).hashCode()); + Assert.assertEquals(sEmptyMetadata.hashCode(), sEmptyMetadata.hashCode()); + Assert.assertEquals( + sEmptyMetadata.hashCode(), new MediaMetadata(0, 0, 0, false).hashCode()); + Assert.assertFalse( + sEmptyMetadata.hashCode() == new MediaMetadata(1, 0, 0, false).hashCode()); + Assert.assertFalse( + sEmptyMetadata.hashCode() == new MediaMetadata(0, 1, 0, false).hashCode()); + Assert.assertFalse( + sEmptyMetadata.hashCode() == new MediaMetadata(0, 0, 1, false).hashCode()); + Assert.assertFalse( + sEmptyMetadata.hashCode() == new MediaMetadata(0, 0, 0, true).hashCode()); } + @Test @SmallTest public void testMediaMetadataGetters() { MediaMetadata data = new MediaMetadata(1, 2, 3, true); - assertEquals(1, data.getDurationInMilliseconds()); - assertEquals(2, data.getWidth()); - assertEquals(3, data.getHeight()); - assertTrue(data.isSuccess()); + Assert.assertEquals(1, data.getDurationInMilliseconds()); + Assert.assertEquals(2, data.getWidth()); + Assert.assertEquals(3, data.getHeight()); + Assert.assertTrue(data.isSuccess()); // Validate no overlap of test values with defaults data = new MediaMetadata(4, 5, 6, false); - assertEquals(4, data.getDurationInMilliseconds()); - assertEquals(5, data.getWidth()); - assertEquals(6, data.getHeight()); - assertFalse(data.isSuccess()); + Assert.assertEquals(4, data.getDurationInMilliseconds()); + Assert.assertEquals(5, data.getWidth()); + Assert.assertEquals(6, data.getHeight()); + Assert.assertFalse(data.isSuccess()); } + @Test @SmallTest public void testConfigure_Net_NoPermissions() { mMockContext.mAllowPermission = false; - assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL, - TEST_COOKIES, TEST_USER_AGENT)); + Assert.assertFalse( + mFakeMRG.configure(mMockContext, TEST_HTTP_URL, TEST_COOKIES, TEST_USER_AGENT)); } + @Test @SmallTest public void testConfigure_Net_NoActiveNetwork() { mMockContext.mAllowPermission = true; mFakeMRG.mNetworkType = null; - assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL, - TEST_COOKIES, TEST_USER_AGENT)); + Assert.assertFalse( + mFakeMRG.configure(mMockContext, TEST_HTTP_URL, TEST_COOKIES, TEST_USER_AGENT)); } + @Test @SmallTest public void testConfigure_Net_Disallowed_Mobile() { mMockContext.mAllowPermission = true; mFakeMRG.mNetworkType = ConnectivityManager.TYPE_MOBILE; - assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL, - TEST_COOKIES, TEST_USER_AGENT)); + Assert.assertFalse( + mFakeMRG.configure(mMockContext, TEST_HTTP_URL, TEST_COOKIES, TEST_USER_AGENT)); } + @Test @SmallTest public void testConfigure_Net_Disallowed_Wimax() { mMockContext.mAllowPermission = true; mFakeMRG.mNetworkType = ConnectivityManager.TYPE_WIMAX; - assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL, - TEST_COOKIES, TEST_USER_AGENT)); + Assert.assertFalse( + mFakeMRG.configure(mMockContext, TEST_HTTP_URL, TEST_COOKIES, TEST_USER_AGENT)); } + @Test @SmallTest public void testConfigure_Net_Allowed_Ethernet_Cookies_NoUA() { mMockContext.mAllowPermission = true; mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET; - assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL, - TEST_COOKIES, null)); - assertEquals(TEST_HTTP_URL, mFakeMRG.mUri); - assertEquals(sHeadersCookieOnly, mFakeMRG.mHeaders); - assertNull(mFakeMRG.mPath); - assertNull(mFakeMRG.mContentUri); + Assert.assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL, TEST_COOKIES, null)); + Assert.assertEquals(TEST_HTTP_URL, mFakeMRG.mUri); + Assert.assertEquals(sHeadersCookieOnly, mFakeMRG.mHeaders); + Assert.assertNull(mFakeMRG.mPath); + Assert.assertNull(mFakeMRG.mContentUri); } + @Test @SmallTest public void testConfigure_Net_Allowed_Wifi_Cookies_NoUA() { mMockContext.mAllowPermission = true; mFakeMRG.mNetworkType = ConnectivityManager.TYPE_WIFI; - assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL, - TEST_COOKIES, null)); - assertEquals(TEST_HTTP_URL, mFakeMRG.mUri); - assertEquals(sHeadersCookieOnly, mFakeMRG.mHeaders); - assertNull(mFakeMRG.mPath); - assertNull(mFakeMRG.mContentUri); + Assert.assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL, TEST_COOKIES, null)); + Assert.assertEquals(TEST_HTTP_URL, mFakeMRG.mUri); + Assert.assertEquals(sHeadersCookieOnly, mFakeMRG.mHeaders); + Assert.assertNull(mFakeMRG.mPath); + Assert.assertNull(mFakeMRG.mContentUri); } + @Test @SmallTest public void testConfigure_Net_Allowed_Ethernet_NoCookies_NoUA() { mMockContext.mAllowPermission = true; mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET; - assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL, - "", null)); - assertEquals(TEST_HTTP_URL, mFakeMRG.mUri); - assertEquals(Collections.emptyMap(), mFakeMRG.mHeaders); - assertNull(mFakeMRG.mPath); - assertNull(mFakeMRG.mContentUri); + Assert.assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL, "", null)); + Assert.assertEquals(TEST_HTTP_URL, mFakeMRG.mUri); + Assert.assertEquals(Collections.emptyMap(), mFakeMRG.mHeaders); + Assert.assertNull(mFakeMRG.mPath); + Assert.assertNull(mFakeMRG.mContentUri); } + @Test @SmallTest public void testConfigure_Net_Allowed_Ethernet_Cookies_WithUA() { mMockContext.mAllowPermission = true; mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET; - assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL, - TEST_COOKIES, TEST_USER_AGENT)); - assertEquals(TEST_HTTP_URL, mFakeMRG.mUri); - assertEquals(sHeadersCookieAndUA, mFakeMRG.mHeaders); - assertNull(mFakeMRG.mPath); - assertNull(mFakeMRG.mContentUri); + Assert.assertTrue( + mFakeMRG.configure(mMockContext, TEST_HTTP_URL, TEST_COOKIES, TEST_USER_AGENT)); + Assert.assertEquals(TEST_HTTP_URL, mFakeMRG.mUri); + Assert.assertEquals(sHeadersCookieAndUA, mFakeMRG.mHeaders); + Assert.assertNull(mFakeMRG.mPath); + Assert.assertNull(mFakeMRG.mContentUri); } + @Test @SmallTest public void testConfigure_Net_Allowed_Ethernet_NoCookies_WithUA() { mMockContext.mAllowPermission = true; mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET; - assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL, - "", TEST_USER_AGENT)); - assertEquals(TEST_HTTP_URL, mFakeMRG.mUri); - assertEquals(sHeadersUAOnly, mFakeMRG.mHeaders); - assertNull(mFakeMRG.mPath); - assertNull(mFakeMRG.mContentUri); + Assert.assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL, "", TEST_USER_AGENT)); + Assert.assertEquals(TEST_HTTP_URL, mFakeMRG.mUri); + Assert.assertEquals(sHeadersUAOnly, mFakeMRG.mHeaders); + Assert.assertNull(mFakeMRG.mPath); + Assert.assertNull(mFakeMRG.mContentUri); } + @Test @SmallTest public void testConfigure_Net_Allowed_Ethernet_Exception() { mMockContext.mAllowPermission = true; mFakeMRG.mThrowExceptionInConfigure = true; mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET; - assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL, - "", TEST_USER_AGENT)); - assertNull(mFakeMRG.mUri); - assertNull(mFakeMRG.mHeaders); + Assert.assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL, "", TEST_USER_AGENT)); + Assert.assertNull(mFakeMRG.mUri); + Assert.assertNull(mFakeMRG.mHeaders); } + @Test @SmallTest public void testConfigure_Net_Allowed_LocalHost_WithNoNetwork() { String[] localHostUrls = { @@ -382,195 +400,219 @@ mMockContext.mAllowPermission = true; mFakeMRG.mNetworkType = null; for (String localHostUrl : localHostUrls) { - assertTrue(mFakeMRG.configure(mMockContext, localHostUrl, - TEST_COOKIES, TEST_USER_AGENT)); - assertEquals(localHostUrl, mFakeMRG.mUri); - assertEquals(sHeadersCookieAndUA, mFakeMRG.mHeaders); - assertNull(mFakeMRG.mPath); - assertNull(mFakeMRG.mContentUri); + Assert.assertTrue( + mFakeMRG.configure(mMockContext, localHostUrl, TEST_COOKIES, TEST_USER_AGENT)); + Assert.assertEquals(localHostUrl, mFakeMRG.mUri); + Assert.assertEquals(sHeadersCookieAndUA, mFakeMRG.mHeaders); + Assert.assertNull(mFakeMRG.mPath); + Assert.assertNull(mFakeMRG.mContentUri); } } + @Test @SmallTest public void testConfigure_File_Allowed_MntSdcard() { final String path = "/mnt/sdcard/test"; final String url = "file://" + path; mFakeMRG.mFileExists = true; - assertTrue(mFakeMRG.configure(mMockContext, url, "", null)); - assertEquals(path, mFakeMRG.mPath); - assertNull(mFakeMRG.mUri); - assertNull(mFakeMRG.mContentUri); - assertNull(mFakeMRG.mHeaders); + Assert.assertTrue(mFakeMRG.configure(mMockContext, url, "", null)); + Assert.assertEquals(path, mFakeMRG.mPath); + Assert.assertNull(mFakeMRG.mUri); + Assert.assertNull(mFakeMRG.mContentUri); + Assert.assertNull(mFakeMRG.mHeaders); } + @Test @SmallTest public void testConfigure_File_Allowed_Sdcard() { final String path = "/sdcard/test"; final String url = "file://" + path; mFakeMRG.mFileExists = true; - assertTrue(mFakeMRG.configure(mMockContext, url, "", null)); - assertEquals(path, mFakeMRG.mPath); - assertNull(mFakeMRG.mUri); - assertNull(mFakeMRG.mContentUri); - assertNull(mFakeMRG.mHeaders); + Assert.assertTrue(mFakeMRG.configure(mMockContext, url, "", null)); + Assert.assertEquals(path, mFakeMRG.mPath); + Assert.assertNull(mFakeMRG.mUri); + Assert.assertNull(mFakeMRG.mContentUri); + Assert.assertNull(mFakeMRG.mHeaders); } + @Test @SmallTest public void testConfigure_File_Allowed_Sdcard_DoesntExist() { final String path = "/sdcard/test"; final String url = "file://" + path; mFakeMRG.mFileExists = false; - assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); - assertNull(mFakeMRG.mPath); + Assert.assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); + Assert.assertNull(mFakeMRG.mPath); } + @Test @SmallTest public void testConfigure_File_Allowed_ExternalStorage() { final String path = sExternalStorageDirectory + "/test"; final String url = "file://" + path; mFakeMRG.mFileExists = true; - assertTrue(mFakeMRG.configure(mMockContext, url, "", null)); - assertEquals(path, mFakeMRG.mPath); - assertNull(mFakeMRG.mUri); - assertNull(mFakeMRG.mContentUri); - assertNull(mFakeMRG.mHeaders); + Assert.assertTrue(mFakeMRG.configure(mMockContext, url, "", null)); + Assert.assertEquals(path, mFakeMRG.mPath); + Assert.assertNull(mFakeMRG.mUri); + Assert.assertNull(mFakeMRG.mContentUri); + Assert.assertNull(mFakeMRG.mHeaders); } + @Test @SmallTest public void testConfigure_File_Disallowed_Innocent() { final String path = "/malicious/path"; final String url = "file://" + path; mFakeMRG.mFileExists = true; - assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); - assertNull(mFakeMRG.mPath); + Assert.assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); + Assert.assertNull(mFakeMRG.mPath); } + @Test @SmallTest public void testConfigure_File_Disallowed_Malicious() { final String path = "/mnt/sdcard/../../data"; final String url = "file://" + path; mFakeMRG.mFileExists = true; - assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); - assertNull(mFakeMRG.mPath); + Assert.assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); + Assert.assertNull(mFakeMRG.mPath); } + @Test @SmallTest public void testConfigure_File_Allowed_Exception() { final String path = "/mnt/sdcard/test"; final String url = "file://" + path; mFakeMRG.mFileExists = true; mFakeMRG.mThrowExceptionInConfigure = true; - assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); - assertNull(mFakeMRG.mPath); + Assert.assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); + Assert.assertNull(mFakeMRG.mPath); } + @Test @SmallTest public void testConfigure_Blob_Disallow_Null_Cache() { final String path = "/data/data/" + null + "/cache/"; final String url = path; mFakeMRG.mFileExists = true; mFakeMRG.mThrowExceptionInConfigure = true; - assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); - assertNull(mFakeMRG.mPath); + Assert.assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); + Assert.assertNull(mFakeMRG.mPath); } + @Test @SmallTest public void testConfigure_Blob_Disallowed_Incomplete_Path() { final String path = "/data/data/"; final String url = path; mFakeMRG.mFileExists = true; mFakeMRG.mThrowExceptionInConfigure = true; - assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); - assertNull(mFakeMRG.mPath); + Assert.assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); + Assert.assertNull(mFakeMRG.mPath); } + @Test @SmallTest public void testConfigure_Blob_Disallowed_Unknown_Path() { final String path = "/unknown/path/"; final String url = path; mFakeMRG.mFileExists = true; mFakeMRG.mThrowExceptionInConfigure = true; - assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); - assertNull(mFakeMRG.mPath); + Assert.assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); + Assert.assertNull(mFakeMRG.mPath); } + @Test @SmallTest public void testConfigure_Blob_Disallowed_Other_Application() { final String path = "/data/data/org.some.other.app/cache/"; final String url = path; mFakeMRG.mFileExists = true; mFakeMRG.mThrowExceptionInConfigure = true; - assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); - assertNull(mFakeMRG.mPath); + Assert.assertFalse(mFakeMRG.configure(mMockContext, url, "", null)); + Assert.assertNull(mFakeMRG.mPath); } + @Test @SmallTest public void testConfigure_Content_Uri_Allowed() { - assertTrue(mFakeMRG.configure(mMockContext, TEST_CONTENT_URI, "", null)); - assertNull(mFakeMRG.mPath); - assertNull(mFakeMRG.mUri); - assertEquals(TEST_CONTENT_URI, mFakeMRG.mContentUri); + Assert.assertTrue(mFakeMRG.configure(mMockContext, TEST_CONTENT_URI, "", null)); + Assert.assertNull(mFakeMRG.mPath); + Assert.assertNull(mFakeMRG.mUri); + Assert.assertEquals(TEST_CONTENT_URI, mFakeMRG.mContentUri); } + @Test @SmallTest public void testConfigure_Content_Uri_Disallowed() { mFakeMRG.mThrowExceptionInConfigure = true; - assertFalse(mFakeMRG.configure(mMockContext, TEST_CONTENT_URI, "", null)); - assertNull(mFakeMRG.mPath); - assertNull(mFakeMRG.mUri); - assertNull(mFakeMRG.mContentUri); + Assert.assertFalse(mFakeMRG.configure(mMockContext, TEST_CONTENT_URI, "", null)); + Assert.assertNull(mFakeMRG.mPath); + Assert.assertNull(mFakeMRG.mUri); + Assert.assertNull(mFakeMRG.mContentUri); } + @Test @SmallTest public void testExtract_NoMetadata() { mFakeMRG.mFileExists = true; - assertEquals(sEmptyMetadata, mFakeMRG.extract( - mMockContext, TEST_FILE_URL, null, null)); - assertEquals("configured successfully when we shouldn't have", - TEST_FILE_PATH, mFakeMRG.mPath); // tricky + Assert.assertEquals( + sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); + Assert.assertEquals("configured successfully when we shouldn't have", TEST_FILE_PATH, + mFakeMRG.mPath); // tricky } + @Test @SmallTest public void testExtract_WithMetadata_ValidDuration() { mFakeMRG.mFileExists = true; mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1"); final MediaMetadata expected = new MediaMetadata(1, 0, 0, true); - assertEquals(expected, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); + Assert.assertEquals(expected, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); } + @Test @SmallTest public void testExtract_WithMetadata_InvalidDuration() { mFakeMRG.mFileExists = true; mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "i am not an integer"); - assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); + Assert.assertEquals( + sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); } + @Test @SmallTest public void testExtract_WithMetadata_ValidDuration_HasVideo_NoWidth_NoHeight() { mFakeMRG.mFileExists = true; mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1"); mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes"); - assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); + Assert.assertEquals( + sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); } + @Test @SmallTest public void testExtract_WithMetadata_ValidDuration_HasVideo_ValidWidth_NoHeight() { mFakeMRG.mFileExists = true; mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1"); mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes"); mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "1"); - assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); + Assert.assertEquals( + sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); } + @Test @SmallTest public void testExtract_WithMetadata_ValidDuration_HasVideo_InvalidWidth_NoHeight() { mFakeMRG.mFileExists = true; mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1"); mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes"); mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "i am not an integer"); - assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); + Assert.assertEquals( + sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); } + @Test @SmallTest public void testExtract_WithMetadata_ValidDuration_HasVideo_ValidWidth_ValidHeight() { mFakeMRG.mFileExists = true; @@ -579,9 +621,10 @@ mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "2"); mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT, "3"); final MediaMetadata expected = new MediaMetadata(1, 2, 3, true); - assertEquals(expected, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); + Assert.assertEquals(expected, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); } + @Test @SmallTest public void testExtract_WithMetadata_ValidDuration_HasVideo_ValidWidth_InvalidHeight() { mFakeMRG.mFileExists = true; @@ -589,17 +632,21 @@ mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes"); mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "1"); mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT, "i am not an integer"); - assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); + Assert.assertEquals( + sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); } + @Test @SmallTest public void testExtract_WithMetadata_ValidDuration_ExceptionInExtract() { mFakeMRG.mFileExists = true; mFakeMRG.mThrowExceptionInExtract = true; mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1"); - assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); + Assert.assertEquals( + sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null)); } + @Test @SmallTest public void testExtractFromFileDescriptor_ValidMetadata() { mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1"); @@ -610,9 +657,9 @@ int fd = 1234; long offset = 1000; long length = 9000; - assertEquals(expected, mFakeMRG.extract(fd, offset, length)); - assertEquals(fd, mFakeMRG.mFd); - assertEquals(offset, mFakeMRG.mOffset); - assertEquals(length, mFakeMRG.mLength); + Assert.assertEquals(expected, mFakeMRG.extract(fd, offset, length)); + Assert.assertEquals(fd, mFakeMRG.mFd); + Assert.assertEquals(offset, mFakeMRG.mOffset); + Assert.assertEquals(length, mFakeMRG.mLength); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/NavigationTest.java b/content/public/android/javatests/src/org/chromium/content/browser/NavigationTest.java index 30bf112..46243c8 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/NavigationTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/NavigationTest.java
@@ -6,6 +6,12 @@ import android.support.test.filters.MediumTest; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.FlakyTest; import org.chromium.base.test.util.UrlUtils; @@ -15,12 +21,15 @@ import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.NavigationHistory; import org.chromium.content_shell_apk.ContentShellActivity; -import org.chromium.content_shell_apk.ContentShellTestBase; +import org.chromium.content_shell_apk.ContentShellActivityTestRule; /** * Tests for various aspects of navigation. */ -public class NavigationTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class NavigationTest { + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); private static final String URL_1 = UrlUtils.encodeHtmlDataUri("<html>1</html>"); private static final String URL_2 = UrlUtils.encodeHtmlDataUri("<html>2</html>"); @@ -32,9 +41,8 @@ private void goBack(final NavigationController navigationController, TestCallbackHelperContainer testCallbackHelperContainer) throws Throwable { - handleBlockingCallbackAction( - testCallbackHelperContainer.getOnPageFinishedHelper(), - new Runnable() { + mActivityTestRule.handleBlockingCallbackAction( + testCallbackHelperContainer.getOnPageFinishedHelper(), new Runnable() { @Override public void run() { navigationController.goBack(); @@ -44,9 +52,8 @@ private void reload(final NavigationController navigationController, TestCallbackHelperContainer testCallbackHelperContainer) throws Throwable { - handleBlockingCallbackAction( - testCallbackHelperContainer.getOnPageFinishedHelper(), - new Runnable() { + mActivityTestRule.handleBlockingCallbackAction( + testCallbackHelperContainer.getOnPageFinishedHelper(), new Runnable() { @Override public void run() { navigationController.reload(true); @@ -54,49 +61,56 @@ }); } + @Test @MediumTest @Feature({"Navigation"}) @FlakyTest public void testDirectedNavigationHistory() throws Throwable { - ContentShellActivity activity = launchContentShellWithUrl(URL_1); - waitForActiveShellToBeDoneLoading(); + ContentShellActivity activity = mActivityTestRule.launchContentShellWithUrl(URL_1); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); ContentViewCore contentViewCore = activity.getActiveContentViewCore(); NavigationController navigationController = contentViewCore.getWebContents() .getNavigationController(); TestCallbackHelperContainer testCallbackHelperContainer = new TestCallbackHelperContainer(contentViewCore); - loadUrl(navigationController, testCallbackHelperContainer, new LoadUrlParams(URL_2)); - loadUrl(navigationController, testCallbackHelperContainer, new LoadUrlParams(URL_3)); - loadUrl(navigationController, testCallbackHelperContainer, new LoadUrlParams(URL_4)); - loadUrl(navigationController, testCallbackHelperContainer, new LoadUrlParams(URL_5)); - loadUrl(navigationController, testCallbackHelperContainer, new LoadUrlParams(URL_6)); - loadUrl(navigationController, testCallbackHelperContainer, new LoadUrlParams(URL_7)); + mActivityTestRule.loadUrl( + navigationController, testCallbackHelperContainer, new LoadUrlParams(URL_2)); + mActivityTestRule.loadUrl( + navigationController, testCallbackHelperContainer, new LoadUrlParams(URL_3)); + mActivityTestRule.loadUrl( + navigationController, testCallbackHelperContainer, new LoadUrlParams(URL_4)); + mActivityTestRule.loadUrl( + navigationController, testCallbackHelperContainer, new LoadUrlParams(URL_5)); + mActivityTestRule.loadUrl( + navigationController, testCallbackHelperContainer, new LoadUrlParams(URL_6)); + mActivityTestRule.loadUrl( + navigationController, testCallbackHelperContainer, new LoadUrlParams(URL_7)); NavigationHistory history = navigationController.getDirectedNavigationHistory(false, 3); - assertEquals(3, history.getEntryCount()); - assertEquals(URL_6, history.getEntryAtIndex(0).getUrl()); - assertEquals(URL_5, history.getEntryAtIndex(1).getUrl()); - assertEquals(URL_4, history.getEntryAtIndex(2).getUrl()); + Assert.assertEquals(3, history.getEntryCount()); + Assert.assertEquals(URL_6, history.getEntryAtIndex(0).getUrl()); + Assert.assertEquals(URL_5, history.getEntryAtIndex(1).getUrl()); + Assert.assertEquals(URL_4, history.getEntryAtIndex(2).getUrl()); history = navigationController.getDirectedNavigationHistory(true, 3); - assertEquals(history.getEntryCount(), 0); + Assert.assertEquals(history.getEntryCount(), 0); goBack(navigationController, testCallbackHelperContainer); goBack(navigationController, testCallbackHelperContainer); goBack(navigationController, testCallbackHelperContainer); history = navigationController.getDirectedNavigationHistory(false, 4); - assertEquals(3, history.getEntryCount()); - assertEquals(URL_3, history.getEntryAtIndex(0).getUrl()); - assertEquals(URL_2, history.getEntryAtIndex(1).getUrl()); - assertEquals(URL_1, history.getEntryAtIndex(2).getUrl()); + Assert.assertEquals(3, history.getEntryCount()); + Assert.assertEquals(URL_3, history.getEntryAtIndex(0).getUrl()); + Assert.assertEquals(URL_2, history.getEntryAtIndex(1).getUrl()); + Assert.assertEquals(URL_1, history.getEntryAtIndex(2).getUrl()); history = navigationController.getDirectedNavigationHistory(true, 4); - assertEquals(3, history.getEntryCount()); - assertEquals(URL_5, history.getEntryAtIndex(0).getUrl()); - assertEquals(URL_6, history.getEntryAtIndex(1).getUrl()); - assertEquals(URL_7, history.getEntryAtIndex(2).getUrl()); + Assert.assertEquals(3, history.getEntryCount()); + Assert.assertEquals(URL_5, history.getEntryAtIndex(0).getUrl()); + Assert.assertEquals(URL_6, history.getEntryAtIndex(1).getUrl()); + Assert.assertEquals(URL_7, history.getEntryAtIndex(2).getUrl()); } /** @@ -104,6 +118,7 @@ * Checks to make sure that OnPageFinished events were fired and that the timestamps of when * the page loaded are different after the reload. */ + @Test @MediumTest @Feature({"Navigation"}) public void testPageReload() throws Throwable { @@ -112,8 +127,8 @@ + "function getLoadtime() { return loadTimestamp; }</script></head></html>"; final String urlLoadTime = UrlUtils.encodeHtmlDataUri(htmlLoadTime); - ContentShellActivity activity = launchContentShellWithUrl(urlLoadTime); - waitForActiveShellToBeDoneLoading(); + ContentShellActivity activity = mActivityTestRule.launchContentShellWithUrl(urlLoadTime); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); ContentViewCore contentViewCore = activity.getActiveContentViewCore(); TestCallbackHelperContainer testCallbackHelperContainer = new TestCallbackHelperContainer(contentViewCore); @@ -124,7 +139,7 @@ contentViewCore.getWebContents(), "getLoadtime();"); javascriptHelper.waitUntilHasValue(); String firstTimestamp = javascriptHelper.getJsonResultAndClear(); - assertNotNull("Timestamp was null.", firstTimestamp); + Assert.assertNotNull("Timestamp was null.", firstTimestamp); // Grab the timestamp after a reload and make sure they don't match. reload(contentViewCore.getWebContents().getNavigationController(), @@ -133,7 +148,7 @@ contentViewCore.getWebContents(), "getLoadtime();"); javascriptHelper.waitUntilHasValue(); String secondTimestamp = javascriptHelper.getJsonResultAndClear(); - assertNotNull("Timestamp was null.", secondTimestamp); - assertFalse("Timestamps matched.", firstTimestamp.equals(secondTimestamp)); + Assert.assertNotNull("Timestamp was null.", secondTimestamp); + Assert.assertFalse("Timestamps matched.", firstTimestamp.equals(secondTimestamp)); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java index a03f016..49c90b3 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java
@@ -8,11 +8,19 @@ import android.support.test.filters.MediumTest; import android.view.Surface; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.chromium.base.ThreadUtils; +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.Feature; import org.chromium.content_public.common.ScreenOrientationValues; -import org.chromium.content_shell_apk.ContentShellTestBase; +import org.chromium.content_shell_apk.ContentShellActivityTestRule; import org.chromium.ui.display.DisplayAndroid; import org.chromium.ui.display.DisplayAndroid.DisplayAndroidObserver; @@ -26,7 +34,11 @@ * orientation: ActivityInfo.SCREEN_ORIENTATION_* * orientation value: ScreenOrientationValues.* */ -public class ScreenOrientationListenerTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class ScreenOrientationListenerTest { + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); + private static class OrientationChangeCallbackHelper extends CallbackHelper implements DisplayAndroidObserver { private int mLastOrientation; @@ -49,16 +61,15 @@ private DisplayAndroid mDisplayAndroid; private int mNaturalOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; - @Override + @Before public void setUp() throws Exception { - super.setUp(); - - launchContentShellWithUrl("about:blank"); + mActivityTestRule.launchContentShellWithUrl("about:blank"); mCallbackHelper = new OrientationChangeCallbackHelper(); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - mDisplayAndroid = getContentViewCore().getWindowAndroid().getDisplay(); + mDisplayAndroid = + mActivityTestRule.getContentViewCore().getWindowAndroid().getDisplay(); mDisplayAndroid.addObserver(mCallbackHelper); DisplayAndroid.startAccurateListening(); } @@ -72,20 +83,20 @@ lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } - @Override + @After public void tearDown() throws Exception { ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { mDisplayAndroid.removeObserver(mCallbackHelper); mDisplayAndroid = null; - getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + mActivityTestRule.getActivity().setRequestedOrientation( + ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); DisplayAndroid.stopAccurateListening(); } }); mCallbackHelper = null; - super.tearDown(); } private static int getNaturalOrientation(DisplayAndroid display) { @@ -115,7 +126,7 @@ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: return Surface.ROTATION_270; default: - fail("Should not be there!"); + Assert.fail("Should not be there!"); return Surface.ROTATION_0; } } else { // mNaturalOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE @@ -129,7 +140,7 @@ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: return Surface.ROTATION_180; default: - fail("Should not be there!"); + Assert.fail("Should not be there!"); return Surface.ROTATION_0; } } @@ -154,24 +165,27 @@ ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - getActivity().setRequestedOrientation(orientation); + mActivityTestRule.getActivity().setRequestedOrientation(orientation); } }); mCallbackHelper.waitForCallback(callCount); return mCallbackHelper.getLastRotation(); } + @Test @MediumTest @Feature({"ScreenOrientation"}) public void testOrientationChanges() throws Exception { int rotation = lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - assertEquals(orientationToRotation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE), rotation); + Assert.assertEquals( + orientationToRotation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE), rotation); rotation = lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - assertEquals(orientationToRotation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT), rotation); + Assert.assertEquals( + orientationToRotation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT), rotation); rotation = lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); - assertEquals( + Assert.assertEquals( orientationToRotation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE), rotation); // Note: REVERSE_PORTRAIT does not work when device orientation is locked by user (eg from @@ -195,7 +209,7 @@ case ScreenOrientationValues.PORTRAIT_SECONDARY: return Surface.ROTATION_180; default: - fail("Can't requiest this orientation value " + orientationValue); + Assert.fail("Can't requiest this orientation value " + orientationValue); return 0; } } else { // mNaturalOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE @@ -213,7 +227,7 @@ case ScreenOrientationValues.PORTRAIT_SECONDARY: return Surface.ROTATION_90; default: - fail("Can't requiest this orientation value " + orientationValue); + Assert.fail("Can't requiest this orientation value " + orientationValue); return 0; } } @@ -230,26 +244,28 @@ @Override public void run() { ScreenOrientationProvider.lockOrientation( - getContentViewCore().getWindowAndroid(), (byte) orientationValue); + mActivityTestRule.getContentViewCore().getWindowAndroid(), + (byte) orientationValue); } }); mCallbackHelper.waitForCallback(callCount); return mCallbackHelper.getLastRotation(); } + @Test @MediumTest @Feature({"ScreenOrientation"}) public void testBasicValues() throws Exception { int rotation = lockOrientationValueAndWait(ScreenOrientationValues.LANDSCAPE_PRIMARY); - assertEquals( + Assert.assertEquals( orientationValueToRotation(ScreenOrientationValues.LANDSCAPE_PRIMARY), rotation); rotation = lockOrientationValueAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY); - assertEquals( + Assert.assertEquals( orientationValueToRotation(ScreenOrientationValues.PORTRAIT_PRIMARY), rotation); rotation = lockOrientationValueAndWait(ScreenOrientationValues.LANDSCAPE_SECONDARY); - assertEquals( + Assert.assertEquals( orientationValueToRotation(ScreenOrientationValues.LANDSCAPE_SECONDARY), rotation); // The note in testOrientationChanges about REVERSE_PORTRAIT applies to PORTRAIT_SECONDARY.
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/TestsJavaScriptEvalTest.java b/content/public/android/javatests/src/org/chromium/content/browser/TestsJavaScriptEvalTest.java index 1f50f05..5bfcf6a 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/TestsJavaScriptEvalTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/TestsJavaScriptEvalTest.java
@@ -6,16 +6,26 @@ import android.support.test.filters.LargeTest; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.UrlUtils; import org.chromium.content.browser.test.util.DOMUtils; import org.chromium.content_public.browser.WebContents; -import org.chromium.content_shell_apk.ContentShellTestBase; +import org.chromium.content_shell_apk.ContentShellActivityTestRule; /** * Integration tests for JavaScript execution. */ -public class TestsJavaScriptEvalTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class TestsJavaScriptEvalTest { + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); + private static final String JSTEST_URL = UrlUtils.encodeHtmlDataUri("<html><head><script>" + " function foobar() { return 'foobar'; }" + "</script></head>" @@ -28,22 +38,23 @@ * Tests that evaluation of JavaScript for test purposes (using JavaScriptUtils, DOMUtils etc) * works even in presence of "background" (non-test-initiated) JavaScript evaluation activity. */ + @Test @LargeTest @Feature({"Browser"}) public void testJavaScriptEvalIsCorrectlyOrdered() throws InterruptedException, Exception, Throwable { - launchContentShellWithUrl(JSTEST_URL); - waitForActiveShellToBeDoneLoading(); + mActivityTestRule.launchContentShellWithUrl(JSTEST_URL); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); - final WebContents webContents = getWebContents(); + final WebContents webContents = mActivityTestRule.getWebContents(); for (int i = 0; i < 30; ++i) { for (int j = 0; j < 10; ++j) { // Start evaluation of a JavaScript script -- we don't need a result. webContents.evaluateJavaScriptForTests("foobar();", null); } // DOMUtils does need to evaluate a JavaScript and get its result to get DOM bounds. - assertNotNull("Failed to get bounds", - DOMUtils.getNodeBounds(webContents, "test")); + Assert.assertNotNull( + "Failed to get bounds", DOMUtils.getNodeBounds(webContents, "test")); } } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/TracingControllerAndroidTest.java b/content/public/android/javatests/src/org/chromium/content/browser/TracingControllerAndroidTest.java index ead616c..586bc15 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/TracingControllerAndroidTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/TracingControllerAndroidTest.java
@@ -9,42 +9,52 @@ import android.os.SystemClock; import android.support.test.filters.MediumTest; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.chromium.base.ThreadUtils; +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.content_shell_apk.ContentShellActivity; -import org.chromium.content_shell_apk.ContentShellTestBase; +import org.chromium.content_shell_apk.ContentShellActivityTestRule; import java.io.File; /** * Test suite for TracingControllerAndroid. */ -public class TracingControllerAndroidTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class TracingControllerAndroidTest { + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); private static final long TIMEOUT_MILLIS = scaleTimeout(30 * 1000); + @Test @MediumTest @Feature({"GPU"}) @DisabledTest(message = "crbug.com/621956") public void testTraceFileCreation() throws Exception { - ContentShellActivity activity = launchContentShellWithUrl("about:blank"); - waitForActiveShellToBeDoneLoading(); + ContentShellActivity activity = mActivityTestRule.launchContentShellWithUrl("about:blank"); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); final TracingControllerAndroid tracingController = new TracingControllerAndroid(activity); - assertFalse(tracingController.isTracing()); - assertNull(tracingController.getOutputPath()); + Assert.assertFalse(tracingController.isTracing()); + Assert.assertNull(tracingController.getOutputPath()); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - assertTrue(tracingController.startTracing(true, "*", "record-until-full")); + Assert.assertTrue(tracingController.startTracing(true, "*", "record-until-full")); } }); - assertTrue(tracingController.isTracing()); + Assert.assertTrue(tracingController.isTracing()); File file = new File(tracingController.getOutputPath()); - assertTrue(file.getName().startsWith("chrome-profile-results")); + Assert.assertTrue(file.getName().startsWith("chrome-profile-results")); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override @@ -58,14 +68,14 @@ long startTime = SystemClock.uptimeMillis(); while (tracingController.isTracing()) { if (SystemClock.uptimeMillis() > startTime + TIMEOUT_MILLIS) { - fail("Timed out waiting for tracing to stop."); + Assert.fail("Timed out waiting for tracing to stop."); } Thread.sleep(1000); } // It says it stopped, so it should have written the output file. - assertTrue(file.exists()); - assertTrue(file.delete()); + Assert.assertTrue(file.exists()); + Assert.assertTrue(file.delete()); tracingController.destroy(); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/VSyncMonitorTest.java b/content/public/android/javatests/src/org/chromium/content/browser/VSyncMonitorTest.java index 16c37f7..ab26b15f 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/VSyncMonitorTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/VSyncMonitorTest.java
@@ -5,11 +5,16 @@ package org.chromium.content.browser; import android.content.Context; +import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; -import android.test.InstrumentationTestCase; import android.view.WindowManager; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.chromium.base.ThreadUtils; +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.DisabledTest; import org.chromium.ui.VSyncMonitor; @@ -19,7 +24,8 @@ /** * Tests VSyncMonitor to make sure it generates correct VSync timestamps. */ -public class VSyncMonitorTest extends InstrumentationTestCase { +@RunWith(BaseJUnit4ClassRunner.class) +public class VSyncMonitorTest { private static final int FRAME_COUNT = 60; private static class VSyncDataCollector implements VSyncMonitor.Listener { @@ -74,7 +80,7 @@ return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<VSyncMonitor>() { @Override public VSyncMonitor call() { - Context context = getInstrumentation().getContext(); + Context context = InstrumentationRegistry.getInstrumentation().getContext(); return new VSyncMonitor(context, listener); } }); @@ -92,6 +98,7 @@ } // Check that the vsync period roughly matches the timestamps that the monitor generates. + @Test @MediumTest @DisabledTest(message = "crbug.com/674129") public void testVSyncPeriod() throws InterruptedException { @@ -100,30 +107,30 @@ VSyncMonitor monitor = createVSyncMonitor(collector); long reportedFramePeriod = monitor.getVSyncPeriodInMicroseconds(); - assertTrue(reportedFramePeriod > 0); + Assert.assertTrue(reportedFramePeriod > 0); - assertFalse(collector.isDone()); + Assert.assertFalse(collector.isDone()); requestVSyncMonitorUpdate(monitor); collector.waitTillDone(); - assertTrue(collector.isDone()); + Assert.assertTrue(collector.isDone()); // Check that the median frame rate is within 10% of the reported frame period. - assertTrue(collector.mFrameCount == FRAME_COUNT - 1); + Assert.assertTrue(collector.mFrameCount == FRAME_COUNT - 1); Arrays.sort(collector.mFramePeriods, 0, collector.mFramePeriods.length); long medianFramePeriod = collector.mFramePeriods[collector.mFramePeriods.length / 2]; if (Math.abs(medianFramePeriod - reportedFramePeriod) > reportedFramePeriod * .1) { - fail("Measured median frame period " + medianFramePeriod + Assert.fail("Measured median frame period " + medianFramePeriod + " differs by more than 10% from the reported frame period " + reportedFramePeriod + " for requested frames"); } - Context context = getInstrumentation().getContext(); + Context context = InstrumentationRegistry.getInstrumentation().getContext(); float refreshRate = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)) .getDefaultDisplay().getRefreshRate(); if (refreshRate < 30.0f) { // Reported refresh rate is most likely incorrect. // Estimated vsync period is expected to be lower than (1000000 / 30) microseconds - assertTrue(monitor.getVSyncPeriodInMicroseconds() < 1000000 / 30); + Assert.assertTrue(monitor.getVSyncPeriodInMicroseconds() < 1000000 / 30); } } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/VibrationManagerImplTest.java b/content/public/android/javatests/src/org/chromium/content/browser/VibrationManagerImplTest.java index dcfb0a21..7db250a 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/VibrationManagerImplTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/VibrationManagerImplTest.java
@@ -7,18 +7,29 @@ import android.os.Vibrator; import android.support.test.filters.MediumTest; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.UrlUtils; import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; -import org.chromium.content_shell_apk.ContentShellTestBase; +import org.chromium.content_shell_apk.ContentShellActivityTestRule; import org.chromium.device.vibration.VibrationManagerImpl; /** * Tests java implementation of VibrationManager mojo service on android. */ -public class VibrationManagerImplTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class VibrationManagerImplTest { + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); + private static final String URL_VIBRATOR_VIBRATE = UrlUtils.encodeHtmlDataUri("<html><body>" + " <script type=\"text/javascript\">" + " navigator.vibrate(3000);" @@ -57,16 +68,15 @@ } } - @Override - protected void setUp() throws Exception { - super.setUp(); - launchContentShellWithUrl("about:blank"); - waitForActiveShellToBeDoneLoading(); + @Before + public void setUp() throws Exception { + mActivityTestRule.launchContentShellWithUrl("about:blank"); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); mFakeWrapper = new FakeAndroidVibratorWrapper(); VibrationManagerImpl.setVibratorWrapperForTesting(mFakeWrapper); - assertEquals(-1, mFakeWrapper.mMilliSeconds); - assertFalse(mFakeWrapper.mCancelled); + Assert.assertEquals(-1, mFakeWrapper.mMilliSeconds); + Assert.assertFalse(mFakeWrapper.mCancelled); } /** @@ -77,9 +87,10 @@ */ // @MediumTest // @Feature({"Vibration"}) + @Test @DisabledTest public void testVibrate() throws Throwable { - loadNewShell(URL_VIBRATOR_VIBRATE); + mActivityTestRule.loadNewShell(URL_VIBRATOR_VIBRATE); // Waits until VibrationManagerImpl.Vibrate() got called. CriteriaHelper.pollUiThread(new Criteria() { @@ -89,7 +100,7 @@ } }); - assertEquals( + Assert.assertEquals( "Did not get vibrate mMilliSeconds correctly", 3000, mFakeWrapper.mMilliSeconds); } @@ -98,10 +109,11 @@ * load the webpage which will request vibrate and then request cancel, * the fake wrapper cancel() should be called. */ + @Test @MediumTest @Feature({"Vibration"}) public void testCancel() throws Throwable { - loadNewShell(URL_VIBRATOR_CANCEL); + mActivityTestRule.loadNewShell(URL_VIBRATOR_CANCEL); // Waits until VibrationManagerImpl.Cancel() got called. CriteriaHelper.pollUiThread(new Criteria() { @@ -111,6 +123,6 @@ } }); - assertTrue("Did not get cancelled", mFakeWrapper.mCancelled); + Assert.assertTrue("Did not get cancelled", mFakeWrapper.mCancelled); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ViewportTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ViewportTest.java index dfd6ade3..2b86f8f0 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ViewportTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ViewportTest.java
@@ -5,22 +5,32 @@ package org.chromium.content.browser; import android.content.Context; +import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.util.DisplayMetrics; import android.view.WindowManager; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.content.browser.test.util.JavaScriptUtils; -import org.chromium.content_shell_apk.ContentShellTestBase; +import org.chromium.content_shell_apk.ContentShellActivityTestRule; /** * Test suite for viewport-related properties. */ -public class ViewportTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class ViewportTest { + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); protected String evaluateStringValue(String expression) throws Throwable { - return JavaScriptUtils.executeJavaScriptAndWaitForResult(getWebContents(), - expression); + return JavaScriptUtils.executeJavaScriptAndWaitForResult( + mActivityTestRule.getWebContents(), expression); } protected float evaluateFloatValue(String expression) throws Throwable { @@ -31,25 +41,27 @@ return Integer.parseInt(evaluateStringValue(expression)); } + @Test @MediumTest @Feature({"Viewport", "InitialViewportSize"}) public void testDefaultViewportSize() throws Throwable { - launchContentShellWithUrl("about:blank"); - waitForActiveShellToBeDoneLoading(); + mActivityTestRule.launchContentShellWithUrl("about:blank"); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); - Context context = getInstrumentation().getTargetContext(); + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); WindowManager winManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics metrics = new DisplayMetrics(); winManager.getDefaultDisplay().getMetrics(metrics); // window.devicePixelRatio should match the default display. Only check to 1 decimal place // to allow for rounding. - assertEquals(metrics.density, evaluateFloatValue("window.devicePixelRatio"), 0.1); + Assert.assertEquals(metrics.density, evaluateFloatValue("window.devicePixelRatio"), 0.1); // Check that the viewport width is vaguely sensible. int viewportWidth = evaluateIntegerValue("document.documentElement.clientWidth"); - assertTrue(Math.abs(evaluateIntegerValue("window.innerWidth") - viewportWidth) <= 1); - assertTrue(viewportWidth >= 979); - assertTrue(viewportWidth <= Math.max(981, metrics.widthPixels / metrics.density + 1)); + Assert.assertTrue(Math.abs(evaluateIntegerValue("window.innerWidth") - viewportWidth) <= 1); + Assert.assertTrue(viewportWidth >= 979); + Assert.assertTrue( + viewportWidth <= Math.max(981, metrics.widthPixels / metrics.density + 1)); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/WebContentsObserverAndroidTest.java b/content/public/android/javatests/src/org/chromium/content/browser/WebContentsObserverAndroidTest.java index b89d1d2..4a299bd 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/WebContentsObserverAndroidTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/WebContentsObserverAndroidTest.java
@@ -4,7 +4,16 @@ package org.chromium.content.browser; +import android.support.test.InstrumentationRegistry; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.chromium.base.ThreadUtils; +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.UrlUtils; @@ -12,14 +21,18 @@ import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsObserver; import org.chromium.content_shell_apk.ContentShellActivity; -import org.chromium.content_shell_apk.ContentShellTestBase; +import org.chromium.content_shell_apk.ContentShellActivityTestRule; import java.util.concurrent.Callable; /** * Tests for the WebContentsObserver APIs. */ -public class WebContentsObserverAndroidTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class WebContentsObserverAndroidTest { + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); + private static final String URL = UrlUtils.encodeHtmlDataUri( "<html><head></head><body>didFirstVisuallyNonEmptyPaint test</body></html>"); @@ -40,33 +53,36 @@ } } - @Override - protected void setUp() throws Exception { - super.setUp(); - ContentShellActivity activity = launchContentShellWithUrl(null); - assertNotNull(activity); - waitForActiveShellToBeDoneLoading(); + @Before + public void setUp() throws Exception { + ContentShellActivity activity = mActivityTestRule.launchContentShellWithUrl(null); + Assert.assertNotNull(activity); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); } /* @SmallTest @Feature({"Navigation"}) */ + @Test @DisabledTest(message = "crbug.com/411931") public void testDidFirstVisuallyNonEmptyPaint() throws Throwable { TestWebContentsObserver observer = ThreadUtils.runOnUiThreadBlocking( new Callable<TestWebContentsObserver>() { @Override public TestWebContentsObserver call() throws Exception { - return new TestWebContentsObserver(getContentViewCore().getWebContents()); + return new TestWebContentsObserver( + mActivityTestRule.getContentViewCore().getWebContents()); } }); int callCount = observer.getDidFirstVisuallyNonEmptyPaintCallbackHelper().getCallCount(); - getInstrumentation().runOnMainSync(new Runnable() { + InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() { - getContentViewCore().getWebContents().getNavigationController() + mActivityTestRule.getContentViewCore() + .getWebContents() + .getNavigationController() .loadUrl(new LoadUrlParams(URL)); } });
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/captioning/CaptioningChangeDelegateTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/captioning/CaptioningChangeDelegateTest.java index f136d67..2f25c265 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/captioning/CaptioningChangeDelegateTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/captioning/CaptioningChangeDelegateTest.java
@@ -8,134 +8,141 @@ import android.graphics.Typeface; import android.support.test.filters.SmallTest; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.content.browser.accessibility.captioning.CaptioningChangeDelegate.ClosedCaptionEdgeAttribute; import org.chromium.content.browser.accessibility.captioning.CaptioningChangeDelegate.ClosedCaptionFont; -import org.chromium.content_shell_apk.ContentShellTestBase; /** * Test suite to ensure that platform settings are translated to CSS appropriately */ -public class CaptioningChangeDelegateTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class CaptioningChangeDelegateTest { private static final String DEFAULT_CAPTIONING_PREF_VALUE = CaptioningChangeDelegate.DEFAULT_CAPTIONING_PREF_VALUE; + @Test @SmallTest public void testFontScaleToPercentage() { String result = CaptioningChangeDelegate.androidFontScaleToPercentage(0f); - assertEquals("0%", result); + Assert.assertEquals("0%", result); result = CaptioningChangeDelegate.androidFontScaleToPercentage(0.000f); - assertEquals("0%", result); + Assert.assertEquals("0%", result); result = CaptioningChangeDelegate.androidFontScaleToPercentage(0.25f); - assertEquals("25%", result); + Assert.assertEquals("25%", result); result = CaptioningChangeDelegate.androidFontScaleToPercentage(1f); - assertEquals("100%", result); + Assert.assertEquals("100%", result); result = CaptioningChangeDelegate.androidFontScaleToPercentage(1.5f); - assertEquals("150%", result); + Assert.assertEquals("150%", result); result = CaptioningChangeDelegate.androidFontScaleToPercentage(0.50125f); - assertEquals("50%", result); + Assert.assertEquals("50%", result); result = CaptioningChangeDelegate.androidFontScaleToPercentage(0.50925f); - assertEquals("51%", result); + Assert.assertEquals("51%", result); } + @Test @SmallTest public void testAndroidColorToCssColor() { String result = CaptioningChangeDelegate.androidColorToCssColor(null); - assertEquals(DEFAULT_CAPTIONING_PREF_VALUE, result); + Assert.assertEquals(DEFAULT_CAPTIONING_PREF_VALUE, result); result = CaptioningChangeDelegate.androidColorToCssColor(Color.BLACK); - assertEquals("rgba(0, 0, 0, 1)", result); + Assert.assertEquals("rgba(0, 0, 0, 1)", result); result = CaptioningChangeDelegate.androidColorToCssColor(Color.WHITE); - assertEquals("rgba(255, 255, 255, 1)", result); + Assert.assertEquals("rgba(255, 255, 255, 1)", result); result = CaptioningChangeDelegate.androidColorToCssColor(Color.BLUE); - assertEquals("rgba(0, 0, 255, 1)", result); + Assert.assertEquals("rgba(0, 0, 255, 1)", result); // Transparent-black result = CaptioningChangeDelegate.androidColorToCssColor(0x00000000); - assertEquals("rgba(0, 0, 0, 0)", result); + Assert.assertEquals("rgba(0, 0, 0, 0)", result); // Transparent-white result = CaptioningChangeDelegate.androidColorToCssColor(0x00FFFFFF); - assertEquals("rgba(255, 255, 255, 0)", result); + Assert.assertEquals("rgba(255, 255, 255, 0)", result); // 50% opaque blue result = CaptioningChangeDelegate.androidColorToCssColor(0x7f0000ff); - assertEquals("rgba(0, 0, 255, 0.5)", result); + Assert.assertEquals("rgba(0, 0, 255, 0.5)", result); // No alpha information result = CaptioningChangeDelegate.androidColorToCssColor(0xFFFFFF); - assertEquals("rgba(255, 255, 255, 0)", result); + Assert.assertEquals("rgba(255, 255, 255, 0)", result); } + @Test @SmallTest public void testClosedCaptionEdgeAttributeWithDefaults() { ClosedCaptionEdgeAttribute edge = ClosedCaptionEdgeAttribute.fromSystemEdgeAttribute( null, null); - assertEquals(DEFAULT_CAPTIONING_PREF_VALUE, edge.getTextShadow()); + Assert.assertEquals(DEFAULT_CAPTIONING_PREF_VALUE, edge.getTextShadow()); edge = ClosedCaptionEdgeAttribute.fromSystemEdgeAttribute(null, "red"); - assertEquals(DEFAULT_CAPTIONING_PREF_VALUE, edge.getTextShadow()); + Assert.assertEquals(DEFAULT_CAPTIONING_PREF_VALUE, edge.getTextShadow()); edge = ClosedCaptionEdgeAttribute.fromSystemEdgeAttribute(0, "red"); - assertEquals(DEFAULT_CAPTIONING_PREF_VALUE, edge.getTextShadow()); + Assert.assertEquals(DEFAULT_CAPTIONING_PREF_VALUE, edge.getTextShadow()); edge = ClosedCaptionEdgeAttribute.fromSystemEdgeAttribute(2, null); - assertEquals("silver 0.05em 0.05em 0.1em", edge.getTextShadow()); + Assert.assertEquals("silver 0.05em 0.05em 0.1em", edge.getTextShadow()); edge = ClosedCaptionEdgeAttribute.fromSystemEdgeAttribute(2, ""); - assertEquals("silver 0.05em 0.05em 0.1em", edge.getTextShadow()); + Assert.assertEquals("silver 0.05em 0.05em 0.1em", edge.getTextShadow()); edge = ClosedCaptionEdgeAttribute.fromSystemEdgeAttribute(2, "red"); - assertEquals("red 0.05em 0.05em 0.1em", edge.getTextShadow()); + Assert.assertEquals("red 0.05em 0.05em 0.1em", edge.getTextShadow()); } + @Test @SmallTest public void testClosedCaptionEdgeAttributeWithCustomDefaults() { ClosedCaptionEdgeAttribute.setShadowOffset("0.00em"); ClosedCaptionEdgeAttribute.setDefaultEdgeColor("red"); ClosedCaptionEdgeAttribute edge = ClosedCaptionEdgeAttribute.fromSystemEdgeAttribute( null, null); - assertEquals(DEFAULT_CAPTIONING_PREF_VALUE, edge.getTextShadow()); + Assert.assertEquals(DEFAULT_CAPTIONING_PREF_VALUE, edge.getTextShadow()); edge = ClosedCaptionEdgeAttribute.fromSystemEdgeAttribute(null, "red"); - assertEquals(DEFAULT_CAPTIONING_PREF_VALUE, edge.getTextShadow()); + Assert.assertEquals(DEFAULT_CAPTIONING_PREF_VALUE, edge.getTextShadow()); edge = ClosedCaptionEdgeAttribute.fromSystemEdgeAttribute(0, "red"); - assertEquals(DEFAULT_CAPTIONING_PREF_VALUE, edge.getTextShadow()); + Assert.assertEquals(DEFAULT_CAPTIONING_PREF_VALUE, edge.getTextShadow()); edge = ClosedCaptionEdgeAttribute.fromSystemEdgeAttribute(2, null); - assertEquals("red 0.00em 0.00em 0.1em", edge.getTextShadow()); + Assert.assertEquals("red 0.00em 0.00em 0.1em", edge.getTextShadow()); edge = ClosedCaptionEdgeAttribute.fromSystemEdgeAttribute(2, "silver"); - assertEquals("silver 0.00em 0.00em 0.1em", edge.getTextShadow()); + Assert.assertEquals("silver 0.00em 0.00em 0.1em", edge.getTextShadow()); } /** * Verifies that certain system fonts always correspond to the default captioning font. */ + @Test @SmallTest public void testClosedCaptionDefaultFonts() { final ClosedCaptionFont nullFont = ClosedCaptionFont.fromSystemFont(null); - assertEquals( - "Null typeface should return the default font family.", + Assert.assertEquals("Null typeface should return the default font family.", DEFAULT_CAPTIONING_PREF_VALUE, nullFont.getFontFamily()); final ClosedCaptionFont defaultFont = ClosedCaptionFont.fromSystemFont(Typeface.DEFAULT); - assertEquals( - "Typeface.DEFAULT should return the default font family.", + Assert.assertEquals("Typeface.DEFAULT should return the default font family.", DEFAULT_CAPTIONING_PREF_VALUE, defaultFont.getFontFamily()); final ClosedCaptionFont defaultBoldFont = ClosedCaptionFont.fromSystemFont( Typeface.DEFAULT_BOLD); - assertEquals( - "Typeface.BOLD should return the default font family.", + Assert.assertEquals("Typeface.BOLD should return the default font family.", DEFAULT_CAPTIONING_PREF_VALUE, defaultBoldFont.getFontFamily()); } @@ -144,40 +151,38 @@ * so this test ensures that each typeface returns DEFAULT_CAPTIONING_PREF_VALUE if it is * equal to Typeface.DEFAULT or returns an explicit font family otherwise. */ + @Test @SmallTest public void testClosedCaptionNonDefaultFonts() { final ClosedCaptionFont monospaceFont = ClosedCaptionFont.fromSystemFont( Typeface.MONOSPACE); if (Typeface.MONOSPACE.equals(Typeface.DEFAULT)) { - assertEquals( + Assert.assertEquals( "Since the default font is monospace, the default family should be returned.", DEFAULT_CAPTIONING_PREF_VALUE, monospaceFont.getFontFamily()); } else { - assertTrue( - "Typeface.MONOSPACE should return a monospace font family.", + Assert.assertTrue("Typeface.MONOSPACE should return a monospace font family.", monospaceFont.mFlags.contains(ClosedCaptionFont.Flags.MONOSPACE)); } final ClosedCaptionFont sansSerifFont = ClosedCaptionFont.fromSystemFont( Typeface.SANS_SERIF); if (Typeface.SANS_SERIF.equals(Typeface.DEFAULT)) { - assertEquals( + Assert.assertEquals( "Since the default font is sans-serif, the default family should be returned.", DEFAULT_CAPTIONING_PREF_VALUE, sansSerifFont.getFontFamily()); } else { - assertTrue( - "Typeface.SANS_SERIF should return a sans-serif font family.", + Assert.assertTrue("Typeface.SANS_SERIF should return a sans-serif font family.", sansSerifFont.mFlags.contains(ClosedCaptionFont.Flags.SANS_SERIF)); } final ClosedCaptionFont serifFont = ClosedCaptionFont.fromSystemFont(Typeface.SERIF); if (Typeface.SERIF.equals(Typeface.DEFAULT)) { - assertEquals( + Assert.assertEquals( "Since the default font is serif, the default font family should be returned.", DEFAULT_CAPTIONING_PREF_VALUE, serifFont.getFontFamily()); } else { - assertTrue( - "Typeface.SERIF should return a serif font family.", + Assert.assertTrue("Typeface.SERIF should return a serif font family.", serifFont.mFlags.contains(ClosedCaptionFont.Flags.SERIF)); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/crypto/CipherFactoryTest.java b/content/public/android/javatests/src/org/chromium/content/browser/crypto/CipherFactoryTest.java index e379e0d..f8868b3 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/crypto/CipherFactoryTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/crypto/CipherFactoryTest.java
@@ -6,9 +6,14 @@ import android.os.Bundle; import android.support.test.filters.MediumTest; -import android.test.InstrumentationTestCase; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; import org.chromium.base.ThreadUtils; +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.content.browser.crypto.CipherFactory.CipherDataObserver; import java.io.IOException; @@ -24,7 +29,8 @@ * Tests that confirm that the class is thread-safe would require putting potentially flaky hooks * throughout the class to simulate artificial blockages. */ -public class CipherFactoryTest extends InstrumentationTestCase { +@RunWith(BaseJUnit4ClassRunner.class) +public class CipherFactoryTest { private static final byte[] INPUT_DATA = {1, 16, 84}; /** Generates non-random byte[] for testing. */ @@ -77,9 +83,8 @@ * Overrides the {@link ByteArrayGenerator} used by the {@link CipherFactory} to ensure * deterministic results. */ - @Override - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { mNumberProvider = new DeterministicParameterGenerator(); CipherFactory.getInstance().setRandomNumberProviderForTests(mNumberProvider); } @@ -87,6 +92,7 @@ /** * {@link Cipher} instances initialized using the same parameters work in exactly the same way. */ + @Test @MediumTest public void testCipherUse() throws Exception { // Check encryption. @@ -98,13 +104,14 @@ Cipher aDecrypt = CipherFactory.getInstance().getCipher(Cipher.DECRYPT_MODE); Cipher bDecrypt = CipherFactory.getInstance().getCipher(Cipher.DECRYPT_MODE); byte[] decrypted = sameOutputDifferentCiphers(output, aDecrypt, bDecrypt); - assertTrue(Arrays.equals(decrypted, INPUT_DATA)); + Assert.assertTrue(Arrays.equals(decrypted, INPUT_DATA)); } /** * Restoring a {@link Bundle} containing the same parameters already in use by the * {@link CipherFactory} should keep the same keys. */ + @Test @MediumTest public void testSameBundleRestoration() throws Exception { // Create two bundles with the same saved state. @@ -120,9 +127,9 @@ bBundle.putByteArray(CipherFactory.BUNDLE_KEY, sameKey); // Restore using the first bundle, then the second. Both should succeed. - assertTrue(CipherFactory.getInstance().restoreFromBundle(aBundle)); + Assert.assertTrue(CipherFactory.getInstance().restoreFromBundle(aBundle)); Cipher aCipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE); - assertTrue(CipherFactory.getInstance().restoreFromBundle(bBundle)); + Assert.assertTrue(CipherFactory.getInstance().restoreFromBundle(bBundle)); Cipher bCipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE); // Make sure the CipherFactory instances are using the same key. @@ -134,6 +141,7 @@ * by the {@link CipherFactory} should fail. Any Ciphers created after the failed restoration * attempt should use the already-existing keys. */ + @Test @MediumTest public void testDifferentBundleRestoration() throws Exception { // Restore one set of parameters. @@ -142,7 +150,7 @@ byte[] aKey = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 100); aBundle.putByteArray(CipherFactory.BUNDLE_IV, aIv); aBundle.putByteArray(CipherFactory.BUNDLE_KEY, aKey); - assertTrue(CipherFactory.getInstance().restoreFromBundle(aBundle)); + Assert.assertTrue(CipherFactory.getInstance().restoreFromBundle(aBundle)); Cipher aCipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE); // Restore using a different set of parameters. @@ -151,7 +159,7 @@ byte[] bKey = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 200); bBundle.putByteArray(CipherFactory.BUNDLE_IV, bIv); bBundle.putByteArray(CipherFactory.BUNDLE_KEY, bKey); - assertFalse(CipherFactory.getInstance().restoreFromBundle(bBundle)); + Assert.assertFalse(CipherFactory.getInstance().restoreFromBundle(bBundle)); Cipher bCipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE); // Make sure they're using the same (original) key by encrypting the same data. @@ -161,22 +169,23 @@ /** * Restoration from a {@link Bundle} missing data should fail. */ + @Test @MediumTest public void testIncompleteBundleRestoration() throws Exception { // Make sure we handle the null case. - assertFalse(CipherFactory.getInstance().restoreFromBundle(null)); + Assert.assertFalse(CipherFactory.getInstance().restoreFromBundle(null)); // Try restoring without the key. Bundle aBundle = new Bundle(); byte[] iv = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 50); aBundle.putByteArray(CipherFactory.BUNDLE_IV, iv); - assertFalse(CipherFactory.getInstance().restoreFromBundle(aBundle)); + Assert.assertFalse(CipherFactory.getInstance().restoreFromBundle(aBundle)); // Try restoring without the initialization vector. Bundle bBundle = new Bundle(); byte[] key = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 100); bBundle.putByteArray(CipherFactory.BUNDLE_KEY, key); - assertFalse(CipherFactory.getInstance().restoreFromBundle(bBundle)); + Assert.assertFalse(CipherFactory.getInstance().restoreFromBundle(bBundle)); } /** @@ -184,6 +193,7 @@ * parameters from a {@link Bundle} before this point should result in {@link Cipher}s using the * restored parameters instead of any generated ones. */ + @Test @MediumTest public void testRestorationSucceedsBeforeCipherCreated() throws Exception { byte[] iv = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 50); @@ -193,15 +203,16 @@ bundle.putByteArray(CipherFactory.BUNDLE_KEY, key); // The keys should be initialized only after restoration. - assertNull(CipherFactory.getInstance().getCipherData(false)); - assertTrue(CipherFactory.getInstance().restoreFromBundle(bundle)); - assertNotNull(CipherFactory.getInstance().getCipherData(false)); + Assert.assertNull(CipherFactory.getInstance().getCipherData(false)); + Assert.assertTrue(CipherFactory.getInstance().restoreFromBundle(bundle)); + Assert.assertNotNull(CipherFactory.getInstance().getCipherData(false)); } /** * If the {@link CipherFactory} has already generated parameters, restorations of different data * should fail. All {@link Cipher}s should use the generated parameters. */ + @Test @MediumTest public void testRestorationDiscardsAfterOtherCipherAlreadyCreated() throws Exception { byte[] iv = mNumberProvider.getBytes(CipherFactory.NUM_BYTES, (byte) 50); @@ -212,7 +223,7 @@ // The keys should be initialized after creating the cipher, so the keys shouldn't match. Cipher aCipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE); - assertFalse(CipherFactory.getInstance().restoreFromBundle(bundle)); + Assert.assertFalse(CipherFactory.getInstance().restoreFromBundle(bundle)); Cipher bCipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE); // B's cipher should use the keys generated for A. @@ -222,42 +233,44 @@ /** * Data saved out to the {@link Bundle} should match what is held by the {@link CipherFactory}. */ + @Test @MediumTest public void testSavingToBundle() throws Exception { // Nothing should get saved out before Cipher data exists. Bundle initialBundle = new Bundle(); CipherFactory.getInstance().saveToBundle(initialBundle); - assertFalse(initialBundle.containsKey(CipherFactory.BUNDLE_IV)); - assertFalse(initialBundle.containsKey(CipherFactory.BUNDLE_KEY)); + Assert.assertFalse(initialBundle.containsKey(CipherFactory.BUNDLE_IV)); + Assert.assertFalse(initialBundle.containsKey(CipherFactory.BUNDLE_KEY)); // Check that Cipher data gets saved if it exists. CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE); Bundle afterBundle = new Bundle(); CipherFactory.getInstance().saveToBundle(afterBundle); - assertTrue(afterBundle.containsKey(CipherFactory.BUNDLE_IV)); - assertTrue(afterBundle.containsKey(CipherFactory.BUNDLE_KEY)); + Assert.assertTrue(afterBundle.containsKey(CipherFactory.BUNDLE_IV)); + Assert.assertTrue(afterBundle.containsKey(CipherFactory.BUNDLE_KEY)); // Confirm the saved keys match by restoring it. - assertTrue(CipherFactory.getInstance().restoreFromBundle(afterBundle)); + Assert.assertTrue(CipherFactory.getInstance().restoreFromBundle(afterBundle)); } /** * Checks that an observer is notified when cipher data is created. */ + @Test @MediumTest public void testCipherFactoryObserver() throws Exception { TestCipherDataObserver observer = new TestCipherDataObserver(); CipherFactory.getInstance().addCipherDataObserver(observer); - assertEquals(0, observer.getTimesNotified()); + Assert.assertEquals(0, observer.getTimesNotified()); CipherFactory.getInstance().getCipher(Cipher.DECRYPT_MODE); ThreadUtils.runOnUiThreadBlocking(mEmptyRunnable); - assertEquals(1, observer.getTimesNotified()); + Assert.assertEquals(1, observer.getTimesNotified()); CipherFactory.getInstance().getCipher(Cipher.DECRYPT_MODE); ThreadUtils.runOnUiThreadBlocking(mEmptyRunnable); - assertEquals(1, observer.getTimesNotified()); + Assert.assertEquals(1, observer.getTimesNotified()); CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE); ThreadUtils.runOnUiThreadBlocking(mEmptyRunnable); - assertEquals(1, observer.getTimesNotified()); + Assert.assertEquals(1, observer.getTimesNotified()); CipherFactory.getInstance().removeCipherDataObserver(observer); } @@ -265,6 +278,7 @@ * Verifies that if the observer is attached after cipher data has already been * created the observer doesn't fire. */ + @Test @MediumTest public void testCipherFactoryObserverTooLate() throws Exception { CipherFactory.getInstance().getCipher(Cipher.DECRYPT_MODE); @@ -273,10 +287,10 @@ TestCipherDataObserver observer = new TestCipherDataObserver(); CipherFactory.getInstance().addCipherDataObserver(observer); ThreadUtils.runOnUiThreadBlocking(mEmptyRunnable); - assertEquals(0, observer.getTimesNotified()); + Assert.assertEquals(0, observer.getTimesNotified()); CipherFactory.getInstance().getCipher(Cipher.DECRYPT_MODE); ThreadUtils.runOnUiThreadBlocking(mEmptyRunnable); - assertEquals(0, observer.getTimesNotified()); + Assert.assertEquals(0, observer.getTimesNotified()); } /** @@ -285,16 +299,16 @@ */ private byte[] sameOutputDifferentCiphers(byte[] input, Cipher aCipher, Cipher bCipher) throws Exception { - assertNotNull(aCipher); - assertNotNull(bCipher); - assertNotSame(aCipher, bCipher); + Assert.assertNotNull(aCipher); + Assert.assertNotNull(bCipher); + Assert.assertNotSame(aCipher, bCipher); byte[] aOutput = aCipher.doFinal(input); byte[] bOutput = bCipher.doFinal(input); - assertNotNull(aOutput); - assertNotNull(bOutput); - assertTrue(Arrays.equals(aOutput, bOutput)); + Assert.assertNotNull(aOutput); + Assert.assertNotNull(bOutput); + Assert.assertTrue(Arrays.equals(aOutput, bOutput)); return aOutput; }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/InputDialogContainerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/InputDialogContainerTest.java index 0201310..37afba4 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/InputDialogContainerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/InputDialogContainerTest.java
@@ -5,9 +5,15 @@ package org.chromium.content.browser.input; import android.content.Context; +import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; -import android.test.AndroidTestCase; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.content.browser.picker.InputDialogContainer; import org.chromium.ui.base.ime.TextInputType; @@ -15,7 +21,8 @@ /** * Unittests for the {@link org.chromium.content.browser.picker.InputDialogContainer} class. */ -public class InputDialogContainerTest extends AndroidTestCase { +@RunWith(BaseJUnit4ClassRunner.class) +public class InputDialogContainerTest { // Defined in third_party/WebKit/Source/platform/DateComponents.h private static final double DATE_DIALOG_DEFAULT_MIN = -62135596800000.0; private static final double DATE_DIALOG_DEFAULT_MAX = 8640000000000000.0; @@ -28,17 +35,19 @@ private static final double WEEK_DIALOG_DEFAULT_MIN = -62135596800000.0; private static final double WEEK_DIALOG_DEFAULT_MAX = 8639999568000000.0; + private static final double ASSERTION_DELTA = 0; + InputActionDelegateForTests mInputActionDelegate; InputDialogContainerForTests mInputDialogContainer; - @Override + @Before public void setUp() throws Exception { - super.setUp(); mInputActionDelegate = new InputActionDelegateForTests(); - mInputDialogContainer = new InputDialogContainerForTests(getContext(), - mInputActionDelegate); + mInputDialogContainer = new InputDialogContainerForTests( + InstrumentationRegistry.getContext(), mInputActionDelegate); } + @Test @SmallTest @Feature({"DateTimeDialog"}) public void testDateValueParsing() { @@ -71,6 +80,7 @@ DATE_DIALOG_DEFAULT_MIN, DATE_DIALOG_DEFAULT_MAX, 1.0); } + @Test @SmallTest @Feature({"DateTimeDialog"}) public void testDatetimelocalValueParsing() { @@ -103,6 +113,7 @@ DATETIMELOCAL_DIALOG_DEFAULT_MIN, DATETIMELOCAL_DIALOG_DEFAULT_MAX, 0.001); } + @Test @SmallTest @Feature({"DateTimeDialog"}) public void testMonthValueParsing() { @@ -135,6 +146,7 @@ MONTH_DIALOG_DEFAULT_MIN, MONTH_DIALOG_DEFAULT_MAX, 1.0); } + @Test @SmallTest @Feature({"DateTimeDialog"}) public void testTimeValueParsing() { @@ -161,6 +173,7 @@ TIME_DIALOG_DEFAULT_MIN, TIME_DIALOG_DEFAULT_MAX, 1.0); } + @Test @SmallTest @Feature({"DateTimeDialog"}) public void testWeekValueParsing() { @@ -193,6 +206,7 @@ WEEK_DIALOG_DEFAULT_MIN, WEEK_DIALOG_DEFAULT_MAX, 1.0); } + @Test @SmallTest @Feature({"DateTimeDialog"}) public void testDateValueGenerating() { @@ -217,6 +231,7 @@ 0, 0, 0, 0, 0); } + @Test @SmallTest @Feature({"DateTimeDialog"}) public void testDatetimelocalValueGenerating() { @@ -241,6 +256,7 @@ 1, 1, 2, 196, 0); } + @Test @SmallTest @Feature({"DateTimeDialog"}) public void testMonthValueGenerating() { @@ -265,6 +281,7 @@ 0, 0, 0, 0, 0); } + @Test @SmallTest @Feature({"DateTimeDialog"}) public void testTimeValueGenerating() { @@ -284,6 +301,7 @@ 3, 23, 45, 678, 0); } + @Test @SmallTest @Feature({"DateTimeDialog"}) public void testWeekValueGenerating() { @@ -318,7 +336,7 @@ @Override public void replaceDateTime(double dialogValue) { - assertEquals(mExpectedDialogValue, dialogValue); + Assert.assertEquals(mExpectedDialogValue, dialogValue, ASSERTION_DELTA); } @Override @@ -375,18 +393,18 @@ int year, int month, int monthDay, int hourOfDay, int minute, int second, int millis, int week, double min, double max, double step) { - assertEquals(mExpectedDialogType, dialogType); - assertEquals(mExpectedYear, year); - assertEquals(mExpectedMonth, month); - assertEquals(mExpectedMonthDay, monthDay); - assertEquals(mExpectedHourOfDay, hourOfDay); - assertEquals(mExpectedMinute, minute); - assertEquals(mExpectedSecond, second); - assertEquals(mExpectedMillis, millis); - assertEquals(mExpectedWeek, week); - assertEquals(mExpectedMin, min); - assertEquals(mExpectedMax, max); - assertEquals(mExpectedStep, step); + Assert.assertEquals(mExpectedDialogType, dialogType); + Assert.assertEquals(mExpectedYear, year); + Assert.assertEquals(mExpectedMonth, month); + Assert.assertEquals(mExpectedMonthDay, monthDay); + Assert.assertEquals(mExpectedHourOfDay, hourOfDay); + Assert.assertEquals(mExpectedMinute, minute); + Assert.assertEquals(mExpectedSecond, second); + Assert.assertEquals(mExpectedMillis, millis); + Assert.assertEquals(mExpectedWeek, week); + Assert.assertEquals(mExpectedMin, min, ASSERTION_DELTA); + Assert.assertEquals(mExpectedMax, max, ASSERTION_DELTA); + Assert.assertEquals(mExpectedStep, step, ASSERTION_DELTA); } @Override
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/picker/DateTimePickerDialogTest.java b/content/public/android/javatests/src/org/chromium/content/browser/picker/DateTimePickerDialogTest.java index 7c769ba..3b8229ab 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/picker/DateTimePickerDialogTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/picker/DateTimePickerDialogTest.java
@@ -4,20 +4,29 @@ package org.chromium.content.browser.picker; +import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; -import android.test.InstrumentationTestCase; import android.widget.TimePicker; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; + /** * Tests for DateTimePickerDialog. */ -public class DateTimePickerDialogTest extends InstrumentationTestCase { +@RunWith(BaseJUnit4ClassRunner.class) +public class DateTimePickerDialogTest { //TODO(tkent): fix deprecation warnings crbug.com/537037 + @Test @SuppressWarnings("deprecation") @SmallTest public void testOnTimeChanged() { int september = 8; - TimePicker picker = new TimePicker(getInstrumentation().getContext()); + TimePicker picker = + new TimePicker(InstrumentationRegistry.getInstrumentation().getContext()); // 2015-09-16 00:00 UTC long min = 1442361600000L; // 2015-09-17 00:00 UTC @@ -27,15 +36,15 @@ picker.setCurrentHour(1); picker.setCurrentMinute(30); DateTimePickerDialog.onTimeChangedInternal(2015, september, 16, picker, min, max); - assertEquals(1, picker.getCurrentHour().intValue()); - assertEquals(30, picker.getCurrentMinute().intValue()); + Assert.assertEquals(1, picker.getCurrentHour().intValue()); + Assert.assertEquals(30, picker.getCurrentMinute().intValue()); // Test a value near to the maximum. picker.setCurrentHour(22); picker.setCurrentMinute(56); DateTimePickerDialog.onTimeChangedInternal(2015, september, 16, picker, min, max); - assertEquals(22, picker.getCurrentHour().intValue()); - assertEquals(56, picker.getCurrentMinute().intValue()); + Assert.assertEquals(22, picker.getCurrentHour().intValue()); + Assert.assertEquals(56, picker.getCurrentMinute().intValue()); // Clamping. picker.setCurrentHour(23); @@ -43,7 +52,7 @@ // 2015-09-16 23:30 UTC max = 1442446200000L; DateTimePickerDialog.onTimeChangedInternal(2015, september, 16, picker, min, max); - assertEquals(23, picker.getCurrentHour().intValue()); - assertEquals(30, picker.getCurrentMinute().intValue()); + Assert.assertEquals(23, picker.getCurrentHour().intValue()); + Assert.assertEquals(30, picker.getCurrentMinute().intValue()); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/webcontents/AccessibilitySnapshotTest.java b/content/public/android/javatests/src/org/chromium/content/browser/webcontents/AccessibilitySnapshotTest.java index 633470ae..a03cf73 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/webcontents/AccessibilitySnapshotTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/webcontents/AccessibilitySnapshotTest.java
@@ -6,17 +6,29 @@ import android.support.test.filters.SmallTest; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.UrlUtils; import org.chromium.content.browser.test.util.JavaScriptUtils; import org.chromium.content_public.browser.AccessibilitySnapshotCallback; import org.chromium.content_public.browser.AccessibilitySnapshotNode; -import org.chromium.content_shell_apk.ContentShellTestBase; +import org.chromium.content_shell_apk.ContentShellActivityTestRule; /** * Accessibility snapshot tests for Assist feature. */ -public class AccessibilitySnapshotTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class AccessibilitySnapshotTest { + private static final double ASSERTION_DELTA = 0; + + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); + private static class AccessibilityCallbackHelper extends CallbackHelper { private AccessibilitySnapshotNode mRoot; @@ -32,10 +44,11 @@ private AccessibilitySnapshotNode receiveAccessibilitySnapshot(String data, String js) throws Throwable { - launchContentShellWithUrl(UrlUtils.encodeHtmlDataUri(data)); - waitForActiveShellToBeDoneLoading(); + mActivityTestRule.launchContentShellWithUrl(UrlUtils.encodeHtmlDataUri(data)); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); if (js != null) { - JavaScriptUtils.executeJavaScriptAndWaitForResult(getWebContents(), js); + JavaScriptUtils.executeJavaScriptAndWaitForResult( + mActivityTestRule.getWebContents(), js); } final AccessibilityCallbackHelper callbackHelper = new AccessibilityCallbackHelper(); @@ -48,10 +61,10 @@ // read the callbackcount before executing the call on UI thread, since it may // synchronously complete. final int callbackCount = callbackHelper.getCallCount(); - runTestOnUiThread(new Runnable() { + mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { - getWebContents().requestAccessibilitySnapshot(callback); + mActivityTestRule.getWebContents().requestAccessibilitySnapshot(callback); } }); callbackHelper.waitForCallback(callbackCount); @@ -61,117 +74,125 @@ /** * Verifies that AX tree is returned. */ + @Test @SmallTest public void testRequestAccessibilitySnapshot() throws Throwable { final String data = "<button>Click</button>"; AccessibilitySnapshotNode root = receiveAccessibilitySnapshot(data, null); - assertEquals(1, root.children.size()); - assertEquals("", root.text); + Assert.assertEquals(1, root.children.size()); + Assert.assertEquals("", root.text); AccessibilitySnapshotNode child = root.children.get(0); - assertEquals(1, child.children.size()); - assertEquals("", child.text); + Assert.assertEquals(1, child.children.size()); + Assert.assertEquals("", child.text); AccessibilitySnapshotNode grandChild = child.children.get(0); - assertEquals(0, grandChild.children.size()); - assertEquals("Click", grandChild.text); + Assert.assertEquals(0, grandChild.children.size()); + Assert.assertEquals("Click", grandChild.text); } + @Test @SmallTest public void testRequestAccessibilitySnapshotColors() throws Throwable { final String data = "<p style=\"color:#123456;background:#abcdef\">color</p>"; AccessibilitySnapshotNode root = receiveAccessibilitySnapshot(data, null); - assertEquals(1, root.children.size()); - assertEquals("", root.text); + Assert.assertEquals(1, root.children.size()); + Assert.assertEquals("", root.text); AccessibilitySnapshotNode child = root.children.get(0); - assertEquals("color", child.text); - assertTrue(child.hasStyle); - assertEquals("ff123456", Integer.toHexString(child.color)); - assertEquals("ffabcdef", Integer.toHexString(child.bgcolor)); + Assert.assertEquals("color", child.text); + Assert.assertTrue(child.hasStyle); + Assert.assertEquals("ff123456", Integer.toHexString(child.color)); + Assert.assertEquals("ffabcdef", Integer.toHexString(child.bgcolor)); } + @Test @SmallTest public void testRequestAccessibilitySnapshotFontSize() throws Throwable { final String data = "<html><head><style> " + " p { font-size:16px; transform: scale(2); }" + " </style></head><body><p>foo</p></body></html>"; AccessibilitySnapshotNode root = receiveAccessibilitySnapshot(data, null); - assertEquals(1, root.children.size()); - assertEquals("", root.text); + Assert.assertEquals(1, root.children.size()); + Assert.assertEquals("", root.text); AccessibilitySnapshotNode child = root.children.get(0); - assertTrue(child.hasStyle); - assertEquals("foo", child.text); + Assert.assertTrue(child.hasStyle); + Assert.assertEquals("foo", child.text); // The font size should take the scale into account. - assertEquals(32.0, child.textSize, 1.0); + Assert.assertEquals(32.0, child.textSize, 1.0); } + @Test @SmallTest public void testRequestAccessibilitySnapshotStyles() throws Throwable { final String data = "<html><head><style> " + " body { font: italic bold 12px Courier; }" + " </style></head><body><p>foo</p></body></html>"; AccessibilitySnapshotNode root = receiveAccessibilitySnapshot(data, null); - assertEquals(1, root.children.size()); - assertEquals("", root.text); + Assert.assertEquals(1, root.children.size()); + Assert.assertEquals("", root.text); AccessibilitySnapshotNode child = root.children.get(0); - assertEquals("foo", child.text); - assertTrue(child.hasStyle); - assertTrue(child.bold); - assertTrue(child.italic); - assertFalse(child.lineThrough); - assertFalse(child.underline); + Assert.assertEquals("foo", child.text); + Assert.assertTrue(child.hasStyle); + Assert.assertTrue(child.bold); + Assert.assertTrue(child.italic); + Assert.assertFalse(child.lineThrough); + Assert.assertFalse(child.underline); } + @Test @SmallTest public void testRequestAccessibilitySnapshotStrongStyle() throws Throwable { final String data = "<html><body><p>foo</p><p><strong>bar</strong></p></body></html>"; AccessibilitySnapshotNode root = receiveAccessibilitySnapshot(data, null); - assertEquals(2, root.children.size()); - assertEquals("", root.text); + Assert.assertEquals(2, root.children.size()); + Assert.assertEquals("", root.text); AccessibilitySnapshotNode child1 = root.children.get(0); - assertEquals("foo", child1.text); - assertTrue(child1.hasStyle); - assertFalse(child1.bold); + Assert.assertEquals("foo", child1.text); + Assert.assertTrue(child1.hasStyle); + Assert.assertFalse(child1.bold); AccessibilitySnapshotNode child2 = root.children.get(1); AccessibilitySnapshotNode child2child = child2.children.get(0); - assertEquals("bar", child2child.text); - assertEquals(child1.textSize, child2child.textSize); - assertTrue(child2child.bold); + Assert.assertEquals("bar", child2child.text); + Assert.assertEquals(child1.textSize, child2child.textSize, ASSERTION_DELTA); + Assert.assertTrue(child2child.bold); } + @Test @SmallTest public void testRequestAccessibilitySnapshotItalicStyle() throws Throwable { final String data = "<html><body><i>foo</i></body></html>"; AccessibilitySnapshotNode root = receiveAccessibilitySnapshot(data, null); - assertEquals(1, root.children.size()); - assertEquals("", root.text); + Assert.assertEquals(1, root.children.size()); + Assert.assertEquals("", root.text); AccessibilitySnapshotNode child = root.children.get(0); AccessibilitySnapshotNode grandchild = child.children.get(0); - assertEquals("foo", grandchild.text); - assertTrue(grandchild.hasStyle); - assertTrue(grandchild.italic); + Assert.assertEquals("foo", grandchild.text); + Assert.assertTrue(grandchild.hasStyle); + Assert.assertTrue(grandchild.italic); } + @Test @SmallTest public void testRequestAccessibilitySnapshotBoldStyle() throws Throwable { final String data = "<html><body><b>foo</b></body></html>"; AccessibilitySnapshotNode root = receiveAccessibilitySnapshot(data, null); - assertEquals(1, root.children.size()); - assertEquals("", root.text); + Assert.assertEquals(1, root.children.size()); + Assert.assertEquals("", root.text); AccessibilitySnapshotNode child = root.children.get(0); AccessibilitySnapshotNode grandchild = child.children.get(0); - assertEquals("foo", grandchild.text); - assertTrue(grandchild.hasStyle); - assertTrue(grandchild.bold); + Assert.assertEquals("foo", grandchild.text); + Assert.assertTrue(grandchild.hasStyle); + Assert.assertTrue(grandchild.bold); } + @Test @SmallTest public void testRequestAccessibilitySnapshotNoStyle() throws Throwable { final String data = "<table><thead></thead></table>"; AccessibilitySnapshotNode root = receiveAccessibilitySnapshot(data, null); - assertEquals(1, root.children.size()); - assertEquals("", root.text); + Assert.assertEquals(1, root.children.size()); + Assert.assertEquals("", root.text); AccessibilitySnapshotNode grandChild = root.children.get(0).children.get(0); - assertFalse(grandChild.hasStyle); + Assert.assertFalse(grandChild.hasStyle); } private String getSelectionScript(String node1, int start, String node2, int end) { @@ -187,55 +208,60 @@ + "selection.addRange(range);"; } + @Test @SmallTest public void testRequestAccessibilitySnapshotOneCharacterSelection() throws Throwable { final String data = "<html><body><b id='node'>foo</b></body></html>"; AccessibilitySnapshotNode root = receiveAccessibilitySnapshot(data, getSelectionScript("node", 0, "node", 1)); - assertEquals(1, root.children.size()); - assertEquals("", root.text); + Assert.assertEquals(1, root.children.size()); + Assert.assertEquals("", root.text); AccessibilitySnapshotNode child = root.children.get(0); AccessibilitySnapshotNode grandchild = child.children.get(0); - assertEquals("foo", grandchild.text); - assertEquals(0, grandchild.startSelection); - assertEquals(1, grandchild.endSelection); + Assert.assertEquals("foo", grandchild.text); + Assert.assertEquals(0, grandchild.startSelection); + Assert.assertEquals(1, grandchild.endSelection); } + @Test + @SmallTest public void testRequestAccessibilitySnapshotOneNodeSelection() throws Throwable { final String data = "<html><body><b id='node'>foo</b></body></html>"; AccessibilitySnapshotNode root = receiveAccessibilitySnapshot(data, getSelectionScript("node", 0, "node", 3)); - assertEquals(1, root.children.size()); - assertEquals("", root.text); + Assert.assertEquals(1, root.children.size()); + Assert.assertEquals("", root.text); AccessibilitySnapshotNode child = root.children.get(0); AccessibilitySnapshotNode grandchild = child.children.get(0); - assertEquals("foo", grandchild.text); - assertEquals(0, grandchild.startSelection); - assertEquals(3, grandchild.endSelection); + Assert.assertEquals("foo", grandchild.text); + Assert.assertEquals(0, grandchild.startSelection); + Assert.assertEquals(3, grandchild.endSelection); } + @Test @SmallTest public void testRequestAccessibilitySnapshotSubsequentNodeSelection() throws Throwable { final String data = "<html><body><b id='node1'>foo</b><b id='node2'>bar</b></body></html>"; AccessibilitySnapshotNode root = receiveAccessibilitySnapshot(data, getSelectionScript("node1", 1, "node2", 1)); - assertEquals(1, root.children.size()); - assertEquals("", root.text); + Assert.assertEquals(1, root.children.size()); + Assert.assertEquals("", root.text); AccessibilitySnapshotNode child = root.children.get(0); AccessibilitySnapshotNode grandchild = child.children.get(0); - assertEquals("foo", grandchild.text); - assertEquals(1, grandchild.startSelection); - assertEquals(3, grandchild.endSelection); + Assert.assertEquals("foo", grandchild.text); + Assert.assertEquals(1, grandchild.startSelection); + Assert.assertEquals(3, grandchild.endSelection); grandchild = child.children.get(1); - assertEquals("bar", grandchild.text); - assertEquals(0, grandchild.startSelection); - assertEquals(1, grandchild.endSelection); + Assert.assertEquals("bar", grandchild.text); + Assert.assertEquals(0, grandchild.startSelection); + Assert.assertEquals(1, grandchild.endSelection); } + @Test @SmallTest public void testRequestAccessibilitySnapshotMultiNodeSelection() throws Throwable { final String data = @@ -243,23 +269,24 @@ AccessibilitySnapshotNode root = receiveAccessibilitySnapshot(data, getSelectionScript("node1", 1, "node2", 1)); - assertEquals(1, root.children.size()); - assertEquals("", root.text); + Assert.assertEquals(1, root.children.size()); + Assert.assertEquals("", root.text); AccessibilitySnapshotNode child = root.children.get(0); AccessibilitySnapshotNode grandchild = child.children.get(0); - assertEquals("foo", grandchild.text); - assertEquals(1, grandchild.startSelection); - assertEquals(3, grandchild.endSelection); + Assert.assertEquals("foo", grandchild.text); + Assert.assertEquals(1, grandchild.startSelection); + Assert.assertEquals(3, grandchild.endSelection); grandchild = child.children.get(1); - assertEquals("middle", grandchild.text); - assertEquals(0, grandchild.startSelection); - assertEquals(6, grandchild.endSelection); + Assert.assertEquals("middle", grandchild.text); + Assert.assertEquals(0, grandchild.startSelection); + Assert.assertEquals(6, grandchild.endSelection); grandchild = child.children.get(2); - assertEquals("bar", grandchild.text); - assertEquals(0, grandchild.startSelection); - assertEquals(1, grandchild.endSelection); + Assert.assertEquals("bar", grandchild.text); + Assert.assertEquals(0, grandchild.startSelection); + Assert.assertEquals(1, grandchild.endSelection); } + @Test @SmallTest public void testRequestAccessibilitySnapshotInputSelection() throws Throwable { final String data = "<html><body><input id='input' value='Hello, world'></body></html>"; @@ -268,24 +295,25 @@ + "input.selectionStart = 0;" + "input.selectionEnd = 5;"; AccessibilitySnapshotNode root = receiveAccessibilitySnapshot(data, js); - assertEquals(1, root.children.size()); - assertEquals("", root.text); + Assert.assertEquals(1, root.children.size()); + Assert.assertEquals("", root.text); AccessibilitySnapshotNode child = root.children.get(0); AccessibilitySnapshotNode grandchild = child.children.get(0); - assertEquals("Hello, world", grandchild.text); - assertEquals(0, grandchild.startSelection); - assertEquals(5, grandchild.endSelection); + Assert.assertEquals("Hello, world", grandchild.text); + Assert.assertEquals(0, grandchild.startSelection); + Assert.assertEquals(5, grandchild.endSelection); } + @Test @SmallTest public void testRequestAccessibilitySnapshotPasswordField() throws Throwable { final String data = "<html><body><input id='input' type='password' value='foo'></body></html>"; AccessibilitySnapshotNode root = receiveAccessibilitySnapshot(data, null); - assertEquals(1, root.children.size()); - assertEquals("", root.text); + Assert.assertEquals(1, root.children.size()); + Assert.assertEquals("", root.text); AccessibilitySnapshotNode child = root.children.get(0); AccessibilitySnapshotNode grandchild = child.children.get(0); - assertEquals("•••", grandchild.text); + Assert.assertEquals("•••", grandchild.text); } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java index f6b99ed2..508a224 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java
@@ -10,13 +10,19 @@ import android.os.Parcel; import android.support.test.filters.SmallTest; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.chromium.base.ThreadUtils; +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.UrlUtils; import org.chromium.content_public.browser.RenderFrameHost; import org.chromium.content_public.browser.WebContents; import org.chromium.content_shell.Shell; import org.chromium.content_shell_apk.ContentShellActivity; -import org.chromium.content_shell_apk.ContentShellTestBase; +import org.chromium.content_shell_apk.ContentShellActivityTestRule; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; @@ -25,7 +31,11 @@ * Test various Java WebContents specific features. * TODO(dtrainor): Add more testing for the WebContents methods. */ -public class WebContentsTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class WebContentsTest { + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); + private static final String TEST_URL_1 = "about://blank"; private static final String TEST_URL_2 = UrlUtils.encodeHtmlDataUri("<html>1</html>"); private static final String WEB_CONTENTS_KEY = "WEBCONTENTSKEY"; @@ -39,21 +49,23 @@ * @throws InterruptedException * @throws ExecutionException */ + @Test @SmallTest public void testWebContentsIsDestroyedMethod() throws InterruptedException, ExecutionException { - final ContentShellActivity activity = launchContentShellWithUrl(TEST_URL_1); - waitForActiveShellToBeDoneLoading(); + final ContentShellActivity activity = + mActivityTestRule.launchContentShellWithUrl(TEST_URL_1); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); WebContents webContents = activity.getActiveWebContents(); - assertFalse("WebContents incorrectly marked as destroyed", - isWebContentsDestroyed(webContents)); + Assert.assertFalse( + "WebContents incorrectly marked as destroyed", isWebContentsDestroyed(webContents)); // Launch a new shell. Shell originalShell = activity.getActiveShell(); - loadNewShell(TEST_URL_1); - assertNotSame("New shell not created", activity.getActiveShell(), originalShell); + mActivityTestRule.loadNewShell(TEST_URL_1); + Assert.assertNotSame("New shell not created", activity.getActiveShell(), originalShell); - assertTrue("WebContents incorrectly marked as not destroyed", + Assert.assertTrue("WebContents incorrectly marked as not destroyed", isWebContentsDestroyed(webContents)); } @@ -62,11 +74,12 @@ * * @throws InterruptedException */ + @Test @SmallTest public void testWebContentsSerializeDeserializeInParcel() throws InterruptedException { - launchContentShellWithUrl(TEST_URL_1); - waitForActiveShellToBeDoneLoading(); - WebContents webContents = getWebContents(); + mActivityTestRule.launchContentShellWithUrl(TEST_URL_1); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); + WebContents webContents = mActivityTestRule.getWebContents(); Parcel parcel = Parcel.obtain(); @@ -80,8 +93,8 @@ WebContents.class.getClassLoader()); // Make sure they're equal. - assertEquals("Deserialized object does not match", - webContents, deserializedWebContents); + Assert.assertEquals( + "Deserialized object does not match", webContents, deserializedWebContents); } finally { parcel.recycle(); } @@ -91,13 +104,14 @@ * Check that it is possible to serialize and deserialize a WebContents object through Bundles. * @throws InterruptedException */ + @Test @SmallTest // TODO(crbug.com/635567): Fix this properly. @SuppressLint("ParcelClassLoader") public void testWebContentsSerializeDeserializeInBundle() throws InterruptedException { - launchContentShellWithUrl(TEST_URL_1); - waitForActiveShellToBeDoneLoading(); - WebContents webContents = getWebContents(); + mActivityTestRule.launchContentShellWithUrl(TEST_URL_1); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); + WebContents webContents = mActivityTestRule.getWebContents(); // Use a parcel to force the Bundle to actually serialize and deserialize, otherwise it can // cache the WebContents object. @@ -121,8 +135,8 @@ deserializedBundle.getParcelable(WEB_CONTENTS_KEY); // Make sure they're equal. - assertEquals("Deserialized object does not match", - webContents, deserializedWebContents); + Assert.assertEquals( + "Deserialized object does not match", webContents, deserializedWebContents); } finally { parcel.recycle(); } @@ -132,13 +146,14 @@ * Check that it is possible to serialize and deserialize a WebContents object through Intents. * @throws InterruptedException */ + @Test @SmallTest // TODO(crbug.com/635567): Fix this properly. @SuppressLint("ParcelClassLoader") public void testWebContentsSerializeDeserializeInIntent() throws InterruptedException { - launchContentShellWithUrl(TEST_URL_1); - waitForActiveShellToBeDoneLoading(); - WebContents webContents = getWebContents(); + mActivityTestRule.launchContentShellWithUrl(TEST_URL_1); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); + WebContents webContents = mActivityTestRule.getWebContents(); // Use a parcel to force the Intent to actually serialize and deserialize, otherwise it can // cache the WebContents object. @@ -162,8 +177,8 @@ (WebContents) deserializedIntent.getParcelableExtra(WEB_CONTENTS_KEY); // Make sure they're equal. - assertEquals("Deserialized object does not match", - webContents, deserializedWebContents); + Assert.assertEquals( + "Deserialized object does not match", webContents, deserializedWebContents); } finally { parcel.recycle(); } @@ -174,12 +189,13 @@ * instance fails. * @throws InterruptedException */ + @Test @SmallTest public void testWebContentsFailDeserializationAcrossProcessBoundary() throws InterruptedException { - launchContentShellWithUrl(TEST_URL_1); - waitForActiveShellToBeDoneLoading(); - WebContents webContents = getWebContents(); + mActivityTestRule.launchContentShellWithUrl(TEST_URL_1); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); + WebContents webContents = mActivityTestRule.getWebContents(); Parcel parcel = Parcel.obtain(); @@ -196,7 +212,7 @@ WebContents.class.getClassLoader()); // Make sure we weren't able to deserialize the WebContents. - assertNull("Unexpectedly deserialized a WebContents", deserializedWebContents); + Assert.assertNull("Unexpectedly deserialized a WebContents", deserializedWebContents); } finally { parcel.recycle(); } @@ -208,15 +224,16 @@ * @throws InterruptedException * @throws ExecutionException */ + @Test @SmallTest public void testSerializingADestroyedWebContentsDoesNotDeserialize() throws InterruptedException, ExecutionException { - ContentShellActivity activity = launchContentShellWithUrl(TEST_URL_1); - waitForActiveShellToBeDoneLoading(); + ContentShellActivity activity = mActivityTestRule.launchContentShellWithUrl(TEST_URL_1); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); WebContents webContents = activity.getActiveWebContents(); - loadNewShell(TEST_URL_1); + mActivityTestRule.loadNewShell(TEST_URL_1); - assertTrue("WebContents not destroyed", isWebContentsDestroyed(webContents)); + Assert.assertTrue("WebContents not destroyed", isWebContentsDestroyed(webContents)); Parcel parcel = Parcel.obtain(); @@ -230,8 +247,8 @@ WebContents.class.getClassLoader()); // Make sure we weren't able to deserialize the WebContents. - assertNull("Unexpectedly deserialized a destroyed WebContents", - deserializedWebContents); + Assert.assertNull( + "Unexpectedly deserialized a destroyed WebContents", deserializedWebContents); } finally { parcel.recycle(); } @@ -243,11 +260,12 @@ * @throws InterruptedException * @throws ExecutionException */ + @Test @SmallTest public void testDestroyingAWebContentsAfterSerializingDoesNotDeserialize() throws InterruptedException, ExecutionException { - ContentShellActivity activity = launchContentShellWithUrl(TEST_URL_1); - waitForActiveShellToBeDoneLoading(); + ContentShellActivity activity = mActivityTestRule.launchContentShellWithUrl(TEST_URL_1); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); WebContents webContents = activity.getActiveWebContents(); Parcel parcel = Parcel.obtain(); @@ -257,8 +275,8 @@ parcel.writeParcelable(webContents, 0); // Destroy the WebContents. - loadNewShell(TEST_URL_1); - assertTrue("WebContents not destroyed", isWebContentsDestroyed(webContents)); + mActivityTestRule.loadNewShell(TEST_URL_1); + Assert.assertTrue("WebContents not destroyed", isWebContentsDestroyed(webContents)); // Try to read back the WebContents. parcel.setDataPosition(0); @@ -266,8 +284,8 @@ WebContents.class.getClassLoader()); // Make sure we weren't able to deserialize the WebContents. - assertNull("Unexpectedly deserialized a destroyed WebContents", - deserializedWebContents); + Assert.assertNull( + "Unexpectedly deserialized a destroyed WebContents", deserializedWebContents); } finally { parcel.recycle(); } @@ -278,12 +296,12 @@ * Parcel. * @throws InterruptedException */ + @Test @SmallTest - public void testFailedDeserializationDoesntCorruptParcel() - throws InterruptedException { - launchContentShellWithUrl(TEST_URL_1); - waitForActiveShellToBeDoneLoading(); - WebContents webContents = getWebContents(); + public void testFailedDeserializationDoesntCorruptParcel() throws InterruptedException { + mActivityTestRule.launchContentShellWithUrl(TEST_URL_1); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); + WebContents webContents = mActivityTestRule.getWebContents(); Parcel parcel = Parcel.obtain(); @@ -303,10 +321,10 @@ WebContents.class.getClassLoader()); // Make sure we weren't able to deserialize the WebContents. - assertNull("Unexpectedly deserialized a WebContents", deserializedWebContents); + Assert.assertNull("Unexpectedly deserialized a WebContents", deserializedWebContents); // Make sure we can properly deserialize the String after the WebContents. - assertEquals("Failing to read the WebContents corrupted the parcel", + Assert.assertEquals("Failing to read the WebContents corrupted the parcel", PARCEL_STRING_TEST_DATA, parcel.readString()); } finally { parcel.recycle(); @@ -319,10 +337,12 @@ * * @throws InterruptedException */ + @Test @SmallTest public void testWebContentsMainFrame() throws InterruptedException { - final ContentShellActivity activity = launchContentShellWithUrl(TEST_URL_2); - waitForActiveShellToBeDoneLoading(); + final ContentShellActivity activity = + mActivityTestRule.launchContentShellWithUrl(TEST_URL_2); + mActivityTestRule.waitForActiveShellToBeDoneLoading(); final WebContents webContents = activity.getActiveWebContents(); ThreadUtils.postOnUiThread(new Runnable() { @@ -330,14 +350,14 @@ public void run() { RenderFrameHost frameHost = webContents.getMainFrame(); - assertNotNull(frameHost); + Assert.assertNotNull(frameHost); - assertEquals("RenderFrameHost has incorrect last committed URL", TEST_URL_2, + Assert.assertEquals("RenderFrameHost has incorrect last committed URL", TEST_URL_2, frameHost.getLastCommittedURL()); WebContents associatedWebContents = WebContentsImpl.fromRenderFrameHost(frameHost); - assertEquals("RenderFrameHost associated with different WebContents", webContents, - associatedWebContents); + Assert.assertEquals("RenderFrameHost associated with different WebContents", + webContents, associatedWebContents); } }); }
diff --git a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellPreconditionsTest.java b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellPreconditionsTest.java index ab3f798..352c1088 100644 --- a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellPreconditionsTest.java +++ b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellPreconditionsTest.java
@@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file.
diff --git a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellShellManagementTest.java b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellShellManagementTest.java index e5f81048..37419f5 100644 --- a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellShellManagementTest.java +++ b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellShellManagementTest.java
@@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file.
diff --git a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellUrlTest.java b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellUrlTest.java index 5402b64..59ef4cd 100644 --- a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellUrlTest.java +++ b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellUrlTest.java
@@ -6,24 +6,36 @@ import android.support.test.filters.SmallTest; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; /** * Example test that just starts the content shell. */ -public class ContentShellUrlTest extends ContentShellTestBase { +@RunWith(BaseJUnit4ClassRunner.class) +public class ContentShellUrlTest { + @Rule + public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule(); + // URL used for base tests. private static final String URL = "data:text"; + @Test @SmallTest @Feature({"Main"}) public void testBaseStartup() throws Exception { - ContentShellActivity activity = launchContentShellWithUrl(URL); + ContentShellActivity activity = mActivityTestRule.launchContentShellWithUrl(URL); // Make sure the activity was created as expected. - assertNotNull(activity); + Assert.assertNotNull(activity); // Make sure that the URL is set as expected. - assertEquals(URL, activity.getActiveShell().getContentViewCore().getWebContents().getUrl()); + Assert.assertEquals( + URL, activity.getActiveShell().getContentViewCore().getWebContents().getUrl()); } }
diff --git a/docs/android_debugging_instructions.md b/docs/android_debugging_instructions.md index 1102fbf..8fd2dd8 100644 --- a/docs/android_debugging_instructions.md +++ b/docs/android_debugging_instructions.md
@@ -92,6 +92,7 @@ ## Debugging Java +### Eclipse * In Eclipse, make a debug configuration of type "Remote Java Application". Choose a "Name" and set "Port" to `8700`. @@ -109,6 +110,12 @@ * Run your debug configuration, and switch to the Debug perspective. +### Android Studio +* Build and install the desired target + +* Click the "Attach debugger to Android process" (see +[here](https://developer.android.com/studio/debug/index.html) for more) + ## Waiting for Java Debugger on Early Startup * To debug early startup, pass `--wait-for-java-debugger` as a command line
diff --git a/docs/android_studio.md b/docs/android_studio.md index 37521225..900f090 100644 --- a/docs/android_studio.md +++ b/docs/android_studio.md
@@ -125,6 +125,8 @@ * Instrumentation tests included as androidTest. * Symlinks to existing .so files in jniLibs (doesn't generate them). * Editing resource xml files. +* Java debugging (see +[here](/docs/android_debugging_instructions.md#Android-Studio)) ### What doesn't work (yet) ([crbug](https://bugs.chromium.org/p/chromium/issues/detail?id=620034))
diff --git a/gpu/command_buffer/tests/gl_ext_multisample_compatibility_unittest.cc b/gpu/command_buffer/tests/gl_ext_multisample_compatibility_unittest.cc index df65efe2..b618ecc 100644 --- a/gpu/command_buffer/tests/gl_ext_multisample_compatibility_unittest.cc +++ b/gpu/command_buffer/tests/gl_ext_multisample_compatibility_unittest.cc
@@ -195,6 +195,15 @@ return; } +#if defined(OS_ANDROID) + // TODO: Figure out why this fails on NVIDIA Shield. crbug.com/700060. + std::string renderer(reinterpret_cast<const char*>(glGetString(GL_RENDERER))); + std::string version(reinterpret_cast<const char*>(glGetString(GL_VERSION))); + if (renderer.find("NVIDIA Tegra") != std::string::npos && + version.find("OpenGL ES 3.2 NVIDIA 361.00") != std::string::npos) + return; +#endif + // SAMPLE_ALPHA_TO_ONE is specified to transform alpha values of // covered samples to 1.0. In order to detect it, we use non-1.0 // alpha.
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index 0758389f..3cc1487 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -477,12 +477,14 @@ @property(nonatomic, readonly) NSDictionary* currentHTTPHeaders; // TODO(crbug.com/684098): Remove these methods and inline their content. -// Called before finishing a history navigation from |item|. -- (void)webWillFinishHistoryNavigationFromItem:(web::NavigationItem*)item; +// Called before finishing a history navigation from a page with the given +// UserAgentType. +- (void)webWillFinishHistoryNavigationWithPreviousUserAgentType: + (web::UserAgentType)userAgentType; // Requires page reconstruction if |item| has a non-NONE UserAgentType and it // differs from that of |fromItem|. - (void)updateDesktopUserAgentForItem:(web::NavigationItem*)item - fromItem:(web::NavigationItem*)fromItem; + previousUserAgentType:(web::UserAgentType)userAgentType; // Removes the container view from the hierarchy and resets the ivar. - (void)resetContainerView; @@ -602,9 +604,12 @@ // TODO(crbug.com/661316): Move this method to NavigationManager. - (void)goDelta:(int)delta; // Loads a new URL if the current entry is not from a pushState() navigation. -// |item| is the NavigationItem that was the current entry prior to the -// navigation. -- (void)finishHistoryNavigationFromItem:(web::NavigationItem*)item; +// |fromURL| is the URL of the previous NavigationItem, |fromUserAgentType| is +// that item's UserAgentType, and |sameDocument| is YES if the navigation is +// between two pages with the same document. +- (void)finishHistoryNavigationFromURL:(const GURL&)fromURL + userAgentType:(web::UserAgentType)fromUserAgentType + sameDocument:(BOOL)sameDocument; // Informs the native controller if web usage is allowed or not. - (void)setNativeControllerWebUsageEnabled:(BOOL)webUsageEnabled; // Called when web controller receives a new message from the web page. @@ -716,9 +721,8 @@ // Compares the two URLs being navigated between during a history navigation to // determine if a # needs to be appended to the URL of |toItem| to trigger a // hashchange event. If so, also saves the modified URL into |toItem|. -- (GURL)URLForHistoryNavigationFromItem:(web::NavigationItem*)fromItem - toItem:(web::NavigationItem*)toItem; - +- (GURL)URLForHistoryNavigationToItem:(web::NavigationItem*)toItem + previousURL:(const GURL&)previousURL; // Finds all the scrollviews in the view hierarchy and makes sure they do not // interfere with scroll to top when tapping the statusbar. - (void)optOutScrollsToTopForSubviews; @@ -1405,8 +1409,8 @@ [list.backList indexOfObject:item] != NSNotFound; } -- (GURL)URLForHistoryNavigationFromItem:(web::NavigationItem*)fromItem - toItem:(web::NavigationItem*)toItem { +- (GURL)URLForHistoryNavigationToItem:(web::NavigationItem*)toItem + previousURL:(const GURL&)previousURL { // If navigating with native API, i.e. using a back forward list item, // hashchange events will be triggered automatically, so no URL tampering is // required. @@ -1416,26 +1420,25 @@ return toItem->GetURL(); } - const GURL& startURL = fromItem->GetURL(); - const GURL& endURL = toItem->GetURL(); + const GURL& URL = toItem->GetURL(); // Check the state of the fragments on both URLs (aka, is there a '#' in the // url or not). - if (!startURL.has_ref() || endURL.has_ref()) { - return endURL; + if (!previousURL.has_ref() || URL.has_ref()) { + return URL; } // startURL contains a fragment and endURL doesn't. Remove the fragment from // startURL and compare the resulting string to endURL. If they are equal, add // # to endURL to cause a hashchange event. - GURL hashless = web::GURLByRemovingRefFromGURL(startURL); + GURL hashless = web::GURLByRemovingRefFromGURL(previousURL); - if (hashless != endURL) - return endURL; + if (hashless != URL) + return URL; url::StringPieceReplacements<std::string> emptyRef; emptyRef.SetRefStr(""); - GURL newEndURL = endURL.ReplaceComponents(emptyRef); + GURL newEndURL = URL.ReplaceComponents(emptyRef); toItem->SetURL(newEndURL); return newEndURL; } @@ -2116,19 +2119,25 @@ if (!_webStateImpl->IsShowingWebInterstitial()) [self recordStateInHistory]; - web::NavigationItem* fromItem = sessionController.currentItem; + + web::NavigationItem* previousItem = sessionController.currentItem; + GURL previousURL = previousItem ? previousItem->GetURL() : GURL::EmptyGURL(); + web::UserAgentType previousUserAgentType = + previousItem ? previousItem->GetUserAgentType() + : web::UserAgentType::NONE; web::NavigationItem* toItem = items[index].get(); + BOOL sameDocumentNavigation = + [sessionController isSameDocumentNavigationBetweenItem:previousItem + andItem:toItem]; NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults]; if (![userDefaults boolForKey:@"PendingIndexNavigationDisabled"]) { [self clearTransientContentView]; // Update the user agent before attempting the navigation. - [self updateDesktopUserAgentForItem:toItem fromItem:fromItem]; + [self updateDesktopUserAgentForItem:toItem + previousUserAgentType:previousUserAgentType]; - BOOL sameDocumentNavigation = - [sessionController isSameDocumentNavigationBetweenItem:fromItem - andItem:toItem]; if (sameDocumentNavigation) { [sessionController goToItemAtIndex:index]; [self updateHTML5HistoryState]; @@ -2144,8 +2153,11 @@ } } else { [sessionController goToItemAtIndex:index]; - if (fromItem) - [self finishHistoryNavigationFromItem:fromItem]; + if (previousURL.is_valid()) { + [self finishHistoryNavigationFromURL:previousURL + userAgentType:previousUserAgentType + sameDocument:sameDocumentNavigation]; + } } } @@ -2239,18 +2251,19 @@ } } -- (void)finishHistoryNavigationFromItem:(web::NavigationItem*)item { - [self webWillFinishHistoryNavigationFromItem:item]; +- (void)finishHistoryNavigationFromURL:(const GURL&)fromURL + userAgentType:(web::UserAgentType)fromUserAgentType + sameDocument:(BOOL)sameDocument { + [self webWillFinishHistoryNavigationWithPreviousUserAgentType: + fromUserAgentType]; // Only load the new URL if it has a different document than |fromEntry| to // prevent extra page loads from NavigationItems created by hash changes or // calls to window.history.pushState(). - BOOL shouldLoadURL = ![self.sessionController - isSameDocumentNavigationBetweenItem:item - andItem:self.currentNavItem]; web::NavigationItem* currentItem = self.currentNavItem; - GURL endURL = [self URLForHistoryNavigationFromItem:item toItem:currentItem]; - if (shouldLoadURL) { + GURL endURL = + [self URLForHistoryNavigationToItem:currentItem previousURL:fromURL]; + if (!sameDocument) { ui::PageTransition transition = ui::PageTransitionFromInt( ui::PAGE_TRANSITION_RELOAD | ui::PAGE_TRANSITION_FORWARD_BACK); @@ -2266,7 +2279,7 @@ // updated after the navigation is committed, as attempting to replace the URL // here will result in a JavaScript SecurityError due to the URLs having // different origins. - if (!shouldLoadURL) + if (sameDocument) [self updateHTML5HistoryState]; } @@ -2359,20 +2372,21 @@ return _passKitDownloader.get(); } -- (void)webWillFinishHistoryNavigationFromItem:(web::NavigationItem*)item { - DCHECK(item); - [self updateDesktopUserAgentForItem:self.currentNavItem fromItem:item]; +- (void)webWillFinishHistoryNavigationWithPreviousUserAgentType: + (web::UserAgentType)userAgentType { + [self updateDesktopUserAgentForItem:self.currentNavItem + previousUserAgentType:userAgentType]; [_delegate webWillFinishHistoryNavigation]; } - (void)updateDesktopUserAgentForItem:(web::NavigationItem*)item - fromItem:(web::NavigationItem*)fromItem { - if (!item || !fromItem) + previousUserAgentType:(web::UserAgentType)userAgentType { + if (!item) return; web::UserAgentType itemUserAgentType = item->GetUserAgentType(); if (itemUserAgentType == web::UserAgentType::NONE) return; - if (itemUserAgentType != fromItem->GetUserAgentType()) + if (itemUserAgentType != userAgentType) [self requirePageReconstruction]; }
diff --git a/ios/web/web_state/ui/crw_web_controller_unittest.mm b/ios/web/web_state/ui/crw_web_controller_unittest.mm index 9a6f792..c204bcc 100644 --- a/ios/web/web_state/ui/crw_web_controller_unittest.mm +++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -50,8 +50,8 @@ @interface CRWWebController (PrivateAPI) @property(nonatomic, readwrite) web::PageDisplayState pageDisplayState; -- (GURL)URLForHistoryNavigationFromItem:(web::NavigationItem*)fromItem - toItem:(web::NavigationItem*)toItem; +- (GURL)URLForHistoryNavigationToItem:(web::NavigationItem*)toItem + previousURL:(const GURL&)previousURL; @end // Used to mock CRWWebDelegate methods with C++ params. @@ -238,27 +238,28 @@ [urlsWithFragments addObject:[url stringByAppendingString:fragment]]; } } - web::NavigationItemImpl fromItem; + + GURL previous_url; web::NavigationItemImpl toItem; // No start fragment: the end url is never changed. for (NSString* start in urlsNoFragments) { for (NSString* end in urlsWithFragments) { - fromItem.SetURL(MAKE_URL(start)); + previous_url = MAKE_URL(start); toItem.SetURL(MAKE_URL(end)); EXPECT_EQ(MAKE_URL(end), - [web_controller() URLForHistoryNavigationFromItem:&fromItem - toItem:&toItem]); + [web_controller() URLForHistoryNavigationToItem:&toItem + previousURL:previous_url]); } } // Both contain fragments: the end url is never changed. for (NSString* start in urlsWithFragments) { for (NSString* end in urlsWithFragments) { - fromItem.SetURL(MAKE_URL(start)); + previous_url = MAKE_URL(start); toItem.SetURL(MAKE_URL(end)); EXPECT_EQ(MAKE_URL(end), - [web_controller() URLForHistoryNavigationFromItem:&fromItem - toItem:&toItem]); + [web_controller() URLForHistoryNavigationToItem:&toItem + previousURL:previous_url]); } } for (unsigned start_index = 0; start_index < [urlsWithFragments count]; @@ -267,21 +268,22 @@ for (unsigned end_index = 0; end_index < [urlsNoFragments count]; ++end_index) { NSString* end = urlsNoFragments[end_index]; + previous_url = MAKE_URL(start); if (start_index / 2 != end_index) { // The URLs have nothing in common, they are left untouched. - fromItem.SetURL(MAKE_URL(start)); toItem.SetURL(MAKE_URL(end)); - EXPECT_EQ(MAKE_URL(end), - [web_controller() URLForHistoryNavigationFromItem:&fromItem - toItem:&toItem]); + EXPECT_EQ( + MAKE_URL(end), + [web_controller() URLForHistoryNavigationToItem:&toItem + previousURL:previous_url]); } else { // Start contains a fragment and matches end: An empty fragment is // added. - fromItem.SetURL(MAKE_URL(start)); toItem.SetURL(MAKE_URL(end)); - EXPECT_EQ(MAKE_URL([end stringByAppendingString:@"#"]), - [web_controller() URLForHistoryNavigationFromItem:&fromItem - toItem:&toItem]); + EXPECT_EQ( + MAKE_URL([end stringByAppendingString:@"#"]), + [web_controller() URLForHistoryNavigationToItem:&toItem + previousURL:previous_url]); } } }
diff --git a/media/capture/video/OWNERS b/media/capture/video/OWNERS index 9b67500..ea5ac3b3 100644 --- a/media/capture/video/OWNERS +++ b/media/capture/video/OWNERS
@@ -1,5 +1,5 @@ emircan@chromium.org -magjed@chromium.org +chfremer@chromium.org mcasas@chromium.org tommi@chromium.org
diff --git a/mojo/public/interfaces/BUILD.gn b/mojo/public/interfaces/BUILD.gn index 654145bd..fb11ec2 100644 --- a/mojo/public/interfaces/BUILD.gn +++ b/mojo/public/interfaces/BUILD.gn
@@ -4,8 +4,6 @@ group("interfaces") { deps = [ - "application", "bindings", - "network", ] }
diff --git a/net/BUILD.gn b/net/BUILD.gn index a6b20ba..091518f 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1199,8 +1199,6 @@ "quic/core/frames/quic_mtu_discovery_frame.h", "quic/core/frames/quic_padding_frame.cc", "quic/core/frames/quic_padding_frame.h", - "quic/core/frames/quic_path_close_frame.cc", - "quic/core/frames/quic_path_close_frame.h", "quic/core/frames/quic_ping_frame.h", "quic/core/frames/quic_rst_stream_frame.cc", "quic/core/frames/quic_rst_stream_frame.h",
diff --git a/net/quic/core/frames/quic_frame.cc b/net/quic/core/frames/quic_frame.cc index 4e086744..e209b76 100644 --- a/net/quic/core/frames/quic_frame.cc +++ b/net/quic/core/frames/quic_frame.cc
@@ -43,9 +43,6 @@ QuicFrame::QuicFrame(QuicBlockedFrame* frame) : type(BLOCKED_FRAME), blocked_frame(frame) {} -QuicFrame::QuicFrame(QuicPathCloseFrame* frame) - : type(PATH_CLOSE_FRAME), path_close_frame(frame) {} - void DeleteFrames(QuicFrames* frames) { for (QuicFrame& frame : *frames) { switch (frame.type) { @@ -78,9 +75,6 @@ case WINDOW_UPDATE_FRAME: delete frame.window_update_frame; break; - case PATH_CLOSE_FRAME: - delete frame.path_close_frame; - break; case NUM_FRAME_TYPES: DCHECK(false) << "Cannot delete type: " << frame.type; } @@ -147,10 +141,6 @@ os << "type { MTU_DISCOVERY_FRAME } "; break; } - case PATH_CLOSE_FRAME: { - os << "type { PATH_CLOSE_FRAME } " << *(frame.path_close_frame); - break; - } default: { QUIC_LOG(ERROR) << "Unknown frame type: " << frame.type; break;
diff --git a/net/quic/core/frames/quic_frame.h b/net/quic/core/frames/quic_frame.h index 3ebe1cf..fce45b5 100644 --- a/net/quic/core/frames/quic_frame.h +++ b/net/quic/core/frames/quic_frame.h
@@ -15,7 +15,6 @@ #include "net/quic/core/frames/quic_goaway_frame.h" #include "net/quic/core/frames/quic_mtu_discovery_frame.h" #include "net/quic/core/frames/quic_padding_frame.h" -#include "net/quic/core/frames/quic_path_close_frame.h" #include "net/quic/core/frames/quic_ping_frame.h" #include "net/quic/core/frames/quic_rst_stream_frame.h" #include "net/quic/core/frames/quic_stop_waiting_frame.h" @@ -40,7 +39,6 @@ explicit QuicFrame(QuicGoAwayFrame* frame); explicit QuicFrame(QuicWindowUpdateFrame* frame); explicit QuicFrame(QuicBlockedFrame* frame); - explicit QuicFrame(QuicPathCloseFrame* frame); QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os, const QuicFrame& frame); @@ -61,7 +59,6 @@ QuicGoAwayFrame* goaway_frame; QuicWindowUpdateFrame* window_update_frame; QuicBlockedFrame* blocked_frame; - QuicPathCloseFrame* path_close_frame; }; }; // QuicFrameType consumes 8 bytes with padding.
diff --git a/net/quic/core/frames/quic_frames_test.cc b/net/quic/core/frames/quic_frames_test.cc index 82b9667..dbc0d0c 100644 --- a/net/quic/core/frames/quic_frames_test.cc +++ b/net/quic/core/frames/quic_frames_test.cc
@@ -9,7 +9,6 @@ #include "net/quic/core/frames/quic_goaway_frame.h" #include "net/quic/core/frames/quic_mtu_discovery_frame.h" #include "net/quic/core/frames/quic_padding_frame.h" -#include "net/quic/core/frames/quic_path_close_frame.h" #include "net/quic/core/frames/quic_ping_frame.h" #include "net/quic/core/frames/quic_rst_stream_frame.h" #include "net/quic/core/frames/quic_stop_waiting_frame.h" @@ -116,14 +115,6 @@ EXPECT_EQ("{ least_unacked: 2 }\n", stream.str()); } -TEST(QuicFramesTest, PathCloseFrameToString) { - QuicPathCloseFrame frame; - frame.path_id = 1; - std::ostringstream stream; - stream << frame; - EXPECT_EQ("{ path_id: 1 }\n", stream.str()); -} - TEST(QuicFramesTest, IsAwaitingPacket) { QuicAckFrame ack_frame1; ack_frame1.largest_observed = 10u;
diff --git a/net/quic/core/quic_config.cc b/net/quic/core/quic_config.cc index 3d2415a..1ee9df7 100644 --- a/net/quic/core/quic_config.cc +++ b/net/quic/core/quic_config.cc
@@ -12,6 +12,7 @@ #include "net/quic/core/quic_socket_address_coder.h" #include "net/quic/core/quic_utils.h" #include "net/quic/platform/api/quic_bug_tracker.h" +#include "net/quic/platform/api/quic_flag_utils.h" #include "net/quic/platform/api/quic_logging.h" #include "net/quic/platform/api/quic_string_piece.h" @@ -337,11 +338,12 @@ initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL), initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL), socket_receive_buffer_(kSRBF, PRESENCE_OPTIONAL), - multipath_enabled_(kMPTH, PRESENCE_OPTIONAL), connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL), alternate_server_address_(kASAD, PRESENCE_OPTIONAL), force_hol_blocking_(kFHL2, PRESENCE_OPTIONAL), - support_max_header_list_size_(kSMHL, PRESENCE_OPTIONAL) { + support_max_header_list_size_(kSMHL, PRESENCE_OPTIONAL), + latched_no_socket_receive_buffer_( + FLAGS_quic_reloadable_flag_quic_no_socket_receive_buffer) { SetDefaults(); } @@ -543,7 +545,11 @@ } void QuicConfig::SetSocketReceiveBufferToSend(uint32_t tcp_receive_window) { - socket_receive_buffer_.SetSendValue(tcp_receive_window); + if (latched_no_socket_receive_buffer_) { + QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_no_socket_receive_buffer, 1, 3); + } else { + socket_receive_buffer_.SetSendValue(tcp_receive_window); + } } bool QuicConfig::HasReceivedSocketReceiveBuffer() const { @@ -554,15 +560,6 @@ return socket_receive_buffer_.GetReceivedValue(); } -void QuicConfig::SetMultipathEnabled(bool multipath_enabled) { - uint32_t value = multipath_enabled ? 1 : 0; - multipath_enabled_.set(value, value); -} - -bool QuicConfig::MultipathEnabled() const { - return multipath_enabled_.GetUint32() > 0; -} - void QuicConfig::SetDisableConnectionMigration() { connection_migration_disabled_.SetSendValue(1); } @@ -641,7 +638,11 @@ initial_round_trip_time_us_.ToHandshakeMessage(out); initial_stream_flow_control_window_bytes_.ToHandshakeMessage(out); initial_session_flow_control_window_bytes_.ToHandshakeMessage(out); - socket_receive_buffer_.ToHandshakeMessage(out); + if (latched_no_socket_receive_buffer_) { + QUIC_FLAG_COUNT_N(gfe2_reloadable_flag_quic_no_socket_receive_buffer, 2, 3); + } else { + socket_receive_buffer_.ToHandshakeMessage(out); + } connection_migration_disabled_.ToHandshakeMessage(out); connection_options_.ToHandshakeMessage(out); alternate_server_address_.ToHandshakeMessage(out); @@ -688,7 +689,9 @@ error = initial_session_flow_control_window_bytes_.ProcessPeerHello( peer_hello, hello_type, error_details); } - if (error == QUIC_NO_ERROR) { + if (latched_no_socket_receive_buffer_) { + QUIC_FLAG_COUNT_N(gfe2_reloadable_flag_quic_no_socket_receive_buffer, 3, 3); + } else if (error == QUIC_NO_ERROR) { error = socket_receive_buffer_.ProcessPeerHello(peer_hello, hello_type, error_details); }
diff --git a/net/quic/core/quic_config.h b/net/quic/core/quic_config.h index 286ba1c..c1d7a89 100644 --- a/net/quic/core/quic_config.h +++ b/net/quic/core/quic_config.h
@@ -351,10 +351,6 @@ uint32_t ReceivedSocketReceiveBuffer() const; - void SetMultipathEnabled(bool multipath_enabled); - - bool MultipathEnabled() const; - void SetDisableConnectionMigration(); bool DisableConnectionMigration() const; @@ -428,9 +424,6 @@ // TODO(ianswett): Deprecate once QUIC_VERSION_34 is deprecated. QuicFixedUint32 socket_receive_buffer_; - // Whether to support multipath for this connection. - QuicNegotiableUint32 multipath_enabled_; - // Whether tell peer not to attempt connection migration. QuicFixedUint32 connection_migration_disabled_; @@ -442,6 +435,9 @@ // Whether support HTTP/2 SETTINGS_MAX_HEADER_LIST_SIZE SETTINGS frame. QuicFixedUint32 support_max_header_list_size_; + + // Latched copy of FLAGS_quic_reloadable_flag_quic_no_socket_receive_buffer + bool latched_no_socket_receive_buffer_; }; } // namespace net
diff --git a/net/quic/core/quic_config_test.cc b/net/quic/core/quic_config_test.cc index 4445e00..06e789d 100644 --- a/net/quic/core/quic_config_test.cc +++ b/net/quic/core/quic_config_test.cc
@@ -33,7 +33,9 @@ config_.SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(5), QuicTime::Delta::FromSeconds(2)); config_.SetMaxStreamsPerConnection(4, 2); - config_.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer); + if (!FLAGS_quic_reloadable_flag_quic_no_socket_receive_buffer) { + config_.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer); + } CryptoHandshakeMessage msg; config_.ToHandshakeMessage(&msg); @@ -54,9 +56,11 @@ EXPECT_EQ(QUIC_NO_ERROR, error); EXPECT_EQ(kInitialSessionFlowControlWindowForTest, value); - error = msg.GetUint32(kSRBF, &value); - EXPECT_EQ(QUIC_NO_ERROR, error); - EXPECT_EQ(kDefaultSocketReceiveBuffer, value); + if (!FLAGS_quic_reloadable_flag_quic_no_socket_receive_buffer) { + error = msg.GetUint32(kSRBF, &value); + EXPECT_EQ(QUIC_NO_ERROR, error); + EXPECT_EQ(kDefaultSocketReceiveBuffer, value); + } } TEST_F(QuicConfigTest, ProcessClientHello) { @@ -73,7 +77,9 @@ 2 * kInitialStreamFlowControlWindowForTest); client_config.SetInitialSessionFlowControlWindowToSend( 2 * kInitialSessionFlowControlWindowForTest); - client_config.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer); + if (!FLAGS_quic_reloadable_flag_quic_no_socket_receive_buffer) { + client_config.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer); + } client_config.SetForceHolBlocking(); QuicTagVector copt; copt.push_back(kTBBR); @@ -109,7 +115,10 @@ 2 * kInitialStreamFlowControlWindowForTest); EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(), 2 * kInitialSessionFlowControlWindowForTest); - EXPECT_EQ(config_.ReceivedSocketReceiveBuffer(), kDefaultSocketReceiveBuffer); + if (!FLAGS_quic_reloadable_flag_quic_no_socket_receive_buffer) { + EXPECT_EQ(config_.ReceivedSocketReceiveBuffer(), + kDefaultSocketReceiveBuffer); + } } TEST_F(QuicConfigTest, ProcessServerHello) { @@ -129,7 +138,9 @@ 2 * kInitialStreamFlowControlWindowForTest); server_config.SetInitialSessionFlowControlWindowToSend( 2 * kInitialSessionFlowControlWindowForTest); - server_config.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer); + if (!FLAGS_quic_reloadable_flag_quic_no_socket_receive_buffer) { + server_config.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer); + } server_config.SetAlternateServerAddressToSend(kTestServerAddress); CryptoHandshakeMessage msg; server_config.ToHandshakeMessage(&msg); @@ -147,7 +158,10 @@ 2 * kInitialStreamFlowControlWindowForTest); EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(), 2 * kInitialSessionFlowControlWindowForTest); - EXPECT_EQ(config_.ReceivedSocketReceiveBuffer(), kDefaultSocketReceiveBuffer); + if (!FLAGS_quic_reloadable_flag_quic_no_socket_receive_buffer) { + EXPECT_EQ(config_.ReceivedSocketReceiveBuffer(), + kDefaultSocketReceiveBuffer); + } EXPECT_TRUE(config_.HasReceivedAlternateServerAddress()); EXPECT_EQ(kTestServerAddress, config_.ReceivedAlternateServerAddress()); }
diff --git a/net/quic/core/quic_connection.cc b/net/quic/core/quic_connection.cc index 04b0d20f..97e689d 100644 --- a/net/quic/core/quic_connection.cc +++ b/net/quic/core/quic_connection.cc
@@ -259,7 +259,6 @@ largest_received_packet_size_(0), goaway_sent_(false), goaway_received_(false), - multipath_enabled_(false), write_error_occured_(false), no_stop_waiting_frames_(false) { QUIC_DLOG(INFO) << ENDPOINT @@ -307,10 +306,6 @@ idle_timeout_connection_close_behavior_ = ConnectionCloseBehavior::SILENT_CLOSE; } - if (FLAGS_quic_reloadable_flag_quic_enable_multipath && - config.MultipathEnabled()) { - multipath_enabled_ = true; - } } else { SetNetworkTimeouts(config.max_time_before_crypto_handshake(), config.max_idle_time_before_crypto_handshake()); @@ -909,16 +904,6 @@ return connected_; } -bool QuicConnection::OnPathCloseFrame(const QuicPathCloseFrame& frame) { - DCHECK(connected_); - if (debug_visitor_ != nullptr) { - debug_visitor_->OnPathCloseFrame(frame); - } - QUIC_DLOG(INFO) << ENDPOINT - << "PATH_CLOSE_FRAME received for path: " << frame.path_id; - return connected_; -} - void QuicConnection::OnPacketComplete() { // Don't do anything if this packet closed the connection. if (!connected_) { @@ -1314,7 +1299,7 @@ // Multipath is not enabled, but a packet with multipath flag on is // received. - if (!multipath_enabled_ && header.public_header.multipath_flag) { + if (header.public_header.multipath_flag) { const string error_details = "Received a packet with multipath flag but multipath is not enabled."; QUIC_BUG << error_details;
diff --git a/net/quic/core/quic_connection.h b/net/quic/core/quic_connection.h index d04d970..e5bf4ca 100644 --- a/net/quic/core/quic_connection.h +++ b/net/quic/core/quic_connection.h
@@ -229,9 +229,6 @@ // Called when a BlockedFrame has been parsed. virtual void OnBlockedFrame(const QuicBlockedFrame& frame) {} - // Called when a PathCloseFrame has been parsed. - virtual void OnPathCloseFrame(const QuicPathCloseFrame& frame) {} - // Called when a public reset packet has been received. virtual void OnPublicResetPacket(const QuicPublicResetPacket& packet) {} @@ -445,7 +442,6 @@ bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override; bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override; bool OnBlockedFrame(const QuicBlockedFrame& frame) override; - bool OnPathCloseFrame(const QuicPathCloseFrame& frame) override; void OnPacketComplete() override; // QuicConnectionCloseDelegateInterface @@ -1079,9 +1075,6 @@ // Whether a GoAway has been received. bool goaway_received_; - // If true, multipath is enabled for this connection. - bool multipath_enabled_; - // Indicates whether a write error is encountered currently. This is used to // avoid infinite write errors. bool write_error_occured_;
diff --git a/net/quic/core/quic_connection_test.cc b/net/quic/core/quic_connection_test.cc index b567e4a7..51e9f28f 100644 --- a/net/quic/core/quic_connection_test.cc +++ b/net/quic/core/quic_connection_test.cc
@@ -929,10 +929,6 @@ ProcessFramePacket(QuicFrame(frame)); } - void ProcessPathClosePacket(QuicPathCloseFrame* frame) { - ProcessFramePacket(QuicFrame(frame)); - } - bool IsMissing(QuicPacketNumber number) { return IsAwaitingPacket(*outgoing_ack(), number, 0); } @@ -4847,8 +4843,6 @@ } TEST_P(QuicConnectionTest, Pacing) { - // static_cast here does not work if using multipath_sent_packet_manager. - FLAGS_quic_reloadable_flag_quic_enable_multipath = false; TestConnection server(connection_id_, kSelfAddress, helper_.get(), alarm_factory_.get(), writer_.get(), Perspective::IS_SERVER, version()); @@ -4979,32 +4973,6 @@ EXPECT_FALSE(connection_.connected()); } -TEST_P(QuicConnectionTest, EnableMultipathNegotiation) { - // Test multipath negotiation during crypto handshake. Multipath is enabled - // when both endpoints enable multipath. - FLAGS_quic_reloadable_flag_quic_enable_multipath = true; - EXPECT_TRUE(connection_.connected()); - EXPECT_FALSE(QuicConnectionPeer::IsMultipathEnabled(&connection_)); - EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); - QuicConfig config; - // Enable multipath on server side. - config.SetMultipathEnabled(true); - - // Create a handshake message enables multipath. - CryptoHandshakeMessage msg; - string error_details; - QuicConfig client_config; - // Enable multipath on client side. - client_config.SetMultipathEnabled(true); - client_config.ToHandshakeMessage(&msg); - const QuicErrorCode error = - config.ProcessPeerHello(msg, CLIENT, &error_details); - EXPECT_EQ(QUIC_NO_ERROR, error); - - connection_.SetFromConfig(config); - EXPECT_TRUE(QuicConnectionPeer::IsMultipathEnabled(&connection_)); -} - TEST_P(QuicConnectionTest, OnPathDegrading) { QuicByteCount packet_size; const size_t kMinTimeoutsBeforePathDegrading = 2;
diff --git a/net/quic/core/quic_constants.h b/net/quic/core/quic_constants.h index 8560e90..9cf0e6c 100644 --- a/net/quic/core/quic_constants.h +++ b/net/quic/core/quic_constants.h
@@ -171,11 +171,6 @@ ((UINT64_C(1) << kUFloat16MantissaEffectiveBits) - 1) << kUFloat16MaxExponent; -// Default path ID. -const QuicPathId kDefaultPathId = 0; -// Invalid path ID. -const QuicPathId kInvalidPathId = 0xff; - // kDiversificationNonceSize is the size, in bytes, of the nonce that a server // may set in the packet header to ensure that its INITIAL keys are not // duplicated.
diff --git a/net/quic/core/quic_error_codes.cc b/net/quic/core/quic_error_codes.cc index fa36096..ca87175 100644 --- a/net/quic/core/quic_error_codes.cc +++ b/net/quic/core/quic_error_codes.cc
@@ -94,6 +94,7 @@ RETURN_STRING_LITERAL(QUIC_PACKET_READ_ERROR); RETURN_STRING_LITERAL(QUIC_EMPTY_STREAM_FRAME_NO_FIN); RETURN_STRING_LITERAL(QUIC_INVALID_HEADERS_STREAM_DATA); + RETURN_STRING_LITERAL(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE); RETURN_STRING_LITERAL(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA); RETURN_STRING_LITERAL(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA); RETURN_STRING_LITERAL(QUIC_FLOW_CONTROL_INVALID_WINDOW);
diff --git a/net/quic/core/quic_error_codes.h b/net/quic/core/quic_error_codes.h index 05124be..38750a5 100644 --- a/net/quic/core/quic_error_codes.h +++ b/net/quic/core/quic_error_codes.h
@@ -153,6 +153,9 @@ QUIC_EMPTY_STREAM_FRAME_NO_FIN = 50, // We received invalid data on the headers stream. QUIC_INVALID_HEADERS_STREAM_DATA = 56, + // Invalid data on the headers stream received because of decompression + // failure. + QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE = 97, // The peer received too much data, violating flow control. QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA = 59, // The peer sent too much data, violating flow control. @@ -273,7 +276,7 @@ QUIC_TOO_MANY_SESSIONS_ON_SERVER = 96, // No error. Used as bound while iterating. - QUIC_LAST_ERROR = 97, + QUIC_LAST_ERROR = 98, }; // QuicErrorCodes is encoded as a single octet on-the-wire. static_assert(static_cast<int>(QUIC_LAST_ERROR) <=
diff --git a/net/quic/core/quic_flags_list.h b/net/quic/core/quic_flags_list.h index 65e5be39..25b97cec 100644 --- a/net/quic/core/quic_flags_list.h +++ b/net/quic/core/quic_flags_list.h
@@ -141,7 +141,7 @@ // When true, ensures the session's flow control window is always at least 1.5x // larger than the largest stream flow control window. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_flow_control_invariant, false) +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_flow_control_invariant, true) // If greater than zero, mean RTT variation is multiplied by the specified // factor and added to the congestion window limit. @@ -165,3 +165,9 @@ // Allows one self address change. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_allow_one_address_change, false) + +// If true, no longer send or process the SRBF value in QuicConfig. +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_no_socket_receive_buffer, false) + +// If true, multipath bit is not used in public flag. +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_remove_multipath_bit, false)
diff --git a/net/quic/core/quic_framer.cc b/net/quic/core/quic_framer.cc index 977fc2f..bacec50 100644 --- a/net/quic/core/quic_framer.cc +++ b/net/quic/core/quic_framer.cc
@@ -207,11 +207,6 @@ } // static -size_t QuicFramer::GetPathCloseFrameSize() { - return kQuicFrameTypeSize + kQuicPathIdSize; -} - -// static size_t QuicFramer::GetStreamIdSize(QuicStreamId stream_id) { // Sizes are 1 through 4 bytes. for (int i = 1; i <= 4; ++i) { @@ -398,12 +393,6 @@ return 0; } break; - case PATH_CLOSE_FRAME: - if (!AppendPathCloseFrame(*frame.path_close_frame, &writer)) { - QUIC_BUG << "AppendPathCloseFrame failed"; - return 0; - } - break; default: RaiseError(QUIC_INVALID_FRAME_DATA); QUIC_BUG << "QUIC_INVALID_FRAME_DATA"; @@ -784,7 +773,9 @@ (public_flags & PACKET_PUBLIC_FLAGS_VERSION) != 0; if (validate_flags_ && !public_header->version_flag && - public_flags > PACKET_PUBLIC_FLAGS_MAX) { + public_flags > (FLAGS_quic_reloadable_flag_quic_remove_multipath_bit + ? PACKET_PUBLIC_FLAGS_MAX_WITHOUT_MULTIPATH_FLAG + : PACKET_PUBLIC_FLAGS_MAX)) { set_detailed_error("Illegal public flags value."); return false; } @@ -825,7 +816,10 @@ // If not, this raises an error. last_version_tag_ = version_tag; QuicVersion version = QuicTagToQuicVersion(version_tag); - if (version == quic_version_ && public_flags > PACKET_PUBLIC_FLAGS_MAX) { + if (version == quic_version_ && + public_flags > (FLAGS_quic_reloadable_flag_quic_remove_multipath_bit + ? PACKET_PUBLIC_FLAGS_MAX_WITHOUT_MULTIPATH_FLAG + : PACKET_PUBLIC_FLAGS_MAX)) { set_detailed_error("Illegal public flags value."); return false; } @@ -1113,19 +1107,6 @@ } continue; } - case PATH_CLOSE_FRAME: { - QuicPathCloseFrame path_close_frame; - if (!ProcessPathCloseFrame(reader, &path_close_frame)) { - return RaiseError(QUIC_INVALID_PATH_CLOSE_DATA); - } - if (!visitor_->OnPathCloseFrame(path_close_frame)) { - QUIC_DVLOG(1) << ENDPOINT - << "Visitor asked to stop further processing."; - // Returning true since there was no parsing error. - return true; - } - continue; - } default: set_detailed_error("Illegal frame type."); @@ -1449,16 +1430,6 @@ return true; } -bool QuicFramer::ProcessPathCloseFrame(QuicDataReader* reader, - QuicPathCloseFrame* frame) { - if (!reader->ReadBytes(&frame->path_id, 1)) { - set_detailed_error("Unable to read path_id."); - return false; - } - - return true; -} - // static QuicStringPiece QuicFramer::GetAssociatedDataFromEncryptedPacket( QuicVersion version, @@ -1699,8 +1670,6 @@ return GetWindowUpdateFrameSize(); case BLOCKED_FRAME: return GetBlockedFrameSize(); - case PATH_CLOSE_FRAME: - return GetPathCloseFrameSize(); case PADDING_FRAME: DCHECK(false); return 0; @@ -2134,15 +2103,6 @@ return true; } -bool QuicFramer::AppendPathCloseFrame(const QuicPathCloseFrame& frame, - QuicDataWriter* writer) { - uint8_t path_id = static_cast<uint8_t>(frame.path_id); - if (!writer->WriteUInt8(path_id)) { - return false; - } - return true; -} - bool QuicFramer::RaiseError(QuicErrorCode error) { QUIC_DLOG(INFO) << ENDPOINT << "Error: " << QuicErrorCodeToString(error) << " detail: " << detailed_error_;
diff --git a/net/quic/core/quic_framer.h b/net/quic/core/quic_framer.h index 16d4340..2ca8ea1 100644 --- a/net/quic/core/quic_framer.h +++ b/net/quic/core/quic_framer.h
@@ -134,9 +134,6 @@ // Called when a BlockedFrame has been parsed. virtual bool OnBlockedFrame(const QuicBlockedFrame& frame) = 0; - // Called when a PathCloseFrame has been parsed. - virtual bool OnPathCloseFrame(const QuicPathCloseFrame& frame) = 0; - // Called when a packet has been completely processed. virtual void OnPacketComplete() = 0; }; @@ -211,8 +208,6 @@ static size_t GetWindowUpdateFrameSize(); // Size in bytes of all Blocked frame fields. static size_t GetBlockedFrameSize(); - // Size in bytes of all PathClose frame fields. - static size_t GetPathCloseFrameSize(); // Size in bytes required to serialize the stream id. static size_t GetStreamIdSize(QuicStreamId stream_id); // Size in bytes required to serialize the stream offset. @@ -391,7 +386,6 @@ bool ProcessWindowUpdateFrame(QuicDataReader* reader, QuicWindowUpdateFrame* frame); bool ProcessBlockedFrame(QuicDataReader* reader, QuicBlockedFrame* frame); - bool ProcessPathCloseFrame(QuicDataReader* reader, QuicPathCloseFrame* frame); bool DecryptPayload(QuicDataReader* encrypted_reader, const QuicPacketHeader& header, @@ -466,8 +460,6 @@ QuicDataWriter* writer); bool AppendBlockedFrame(const QuicBlockedFrame& frame, QuicDataWriter* writer); - bool AppendPathCloseFrame(const QuicPathCloseFrame& frame, - QuicDataWriter* writer); bool RaiseError(QuicErrorCode error);
diff --git a/net/quic/core/quic_framer_test.cc b/net/quic/core/quic_framer_test.cc index ea6f06c0..6115ab6 100644 --- a/net/quic/core/quic_framer_test.cc +++ b/net/quic/core/quic_framer_test.cc
@@ -57,13 +57,6 @@ return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize; } -// Index into the path id offset in the header (if present). -size_t GetPathIdOffset(QuicConnectionIdLength connection_id_length, - bool include_version) { - return kConnectionIdOffset + connection_id_length + - (include_version ? kQuicVersionSize : 0); -} - // Index into the packet number offset in the header. size_t GetPacketNumberOffset(QuicConnectionIdLength connection_id_length, bool include_version) { @@ -75,23 +68,6 @@ return GetPacketNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version); } -// Index into the private flags offset in the data packet header. -size_t GetPrivateFlagsOffset(QuicConnectionIdLength connection_id_length, - bool include_version) { - return GetPacketNumberOffset(connection_id_length, include_version) + - PACKET_6BYTE_PACKET_NUMBER; -} - -size_t GetPrivateFlagsOffset(bool include_version) { - return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version); -} - -size_t GetPrivateFlagsOffset(bool include_version, - QuicPacketNumberLength packet_number_length) { - return GetPacketNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version) + - packet_number_length; -} - // Index into the message tag of the public reset packet. // Public resets always have full connection_ids. const size_t kPublicResetPacketMessageTagOffset = @@ -129,7 +105,6 @@ QuicStringPiece GetNoncePrefix() const override { return QuicStringPiece(); } QuicVersion version_; - Perspective perspective_; QuicPacketNumber packet_number_; string associated_data_; string plaintext_; @@ -168,7 +143,6 @@ // Use a distinct value starting with 0xFFFFFF, which is never used by TLS. uint32_t cipher_id() const override { return 0xFFFFFFF2; } QuicVersion version_; - Perspective perspective_; QuicPacketNumber packet_number_; string associated_data_; string ciphertext_; @@ -288,11 +262,6 @@ return true; } - bool OnPathCloseFrame(const QuicPathCloseFrame& frame) override { - path_close_frame_ = frame; - return true; - } - // Counters from the visitor_ callbacks. int error_count_; int version_mismatch_; @@ -316,7 +285,6 @@ QuicGoAwayFrame goaway_frame_; QuicWindowUpdateFrame window_update_frame_; QuicBlockedFrame blocked_frame_; - QuicPathCloseFrame path_close_frame_; std::vector<std::unique_ptr<string>> stream_data_; }; @@ -941,7 +909,8 @@ // clang-format off unsigned char packet[] = { // public flags: includes nonce flag - 0x7C, + static_cast<unsigned char>( + FLAGS_quic_reloadable_flag_quic_remove_multipath_bit ? 0x3C : 0x7C), // connection_id 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, // nonce @@ -971,7 +940,8 @@ // clang-format off unsigned char packet[] = { // public flags (8 byte connection_id, version flag and an unknown flag) - 0x79, + static_cast<unsigned char>( + FLAGS_quic_reloadable_flag_quic_remove_multipath_bit ? 0x39 : 0x79), // connection_id 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, @@ -3568,7 +3538,7 @@ QuicVersionVector versions; versions.push_back(framer_.version()); std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( - 42, false, false, false, kTestQuicStreamId, kTestString, + 42, false, false, kTestQuicStreamId, kTestString, PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, &versions)); MockFramerVisitor visitor;
diff --git a/net/quic/core/quic_packet_creator.h b/net/quic/core/quic_packet_creator.h index a80c3cd..68b70d4 100644 --- a/net/quic/core/quic_packet_creator.h +++ b/net/quic/core/quic_packet_creator.h
@@ -3,9 +3,7 @@ // found in the LICENSE file. // // Accumulates frames for the next packet until more frames no longer fit or -// it's time to create a packet from them. If multipath enabled, only creates -// packets on one path at the same time. Currently, next packet number is -// tracked per-path. +// it's time to create a packet from them. #ifndef NET_QUIC_CORE_QUIC_PACKET_CREATOR_H_ #define NET_QUIC_CORE_QUIC_PACKET_CREATOR_H_
diff --git a/net/quic/core/quic_packets.h b/net/quic/core/quic_packets.h index 05bd01c..474b121 100644 --- a/net/quic/core/quic_packets.h +++ b/net/quic/core/quic_packets.h
@@ -64,6 +64,8 @@ // public flags. QuicConnectionId connection_id; QuicConnectionIdLength connection_id_length; + // TODO(fayang): Remove multipath_flag when deprecating + // gfe2_reloadable_flag_quic_remove_multipath_bit. bool multipath_flag; bool reset_flag; bool version_flag;
diff --git a/net/quic/core/quic_server_session_base_test.cc b/net/quic/core/quic_server_session_base_test.cc index 34c6aff..7673552 100644 --- a/net/quic/core/quic_server_session_base_test.cc +++ b/net/quic/core/quic_server_session_base_test.cc
@@ -409,8 +409,6 @@ // and we don't have any other data to write. // Client has sent kBWRE connection option to trigger bandwidth resumption. - // Disable this flag because if connection uses multipath sent packet manager, - // static_cast here does not work. QuicTagVector copt; copt.push_back(kBWRE); QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt); @@ -613,8 +611,8 @@ chlo.SetVector(kCOPT, QuicTagVector{kSREJ}); std::vector<QuicVersion> packet_version_list = {version}; std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( - 1, true, false, false, 1, - chlo.GetSerialized().AsStringPiece().as_string(), + 1, true, false, 1, + string(chlo.GetSerialized().AsStringPiece().as_string()), PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, &packet_version_list)); @@ -625,7 +623,7 @@ // Set the current packet QuicConnectionPeer::SetCurrentPacket(session_->connection(), - packet->AsStringPiece()); + packet->AsStringPiece().as_string()); // Yes, this is horrible. But it's the easiest way to trigger the behavior we // need to exercise.
diff --git a/net/quic/core/quic_spdy_session.cc b/net/quic/core/quic_spdy_session.cc index 4c14b615..61d16c90 100644 --- a/net/quic/core/quic_spdy_session.cc +++ b/net/quic/core/quic_spdy_session.cc
@@ -124,7 +124,8 @@ if (session_->OnStreamFrameData(stream_id, data, len)) { return; } - CloseConnection("SPDY DATA frame received."); + CloseConnection("SPDY DATA frame received.", + QUIC_INVALID_HEADERS_STREAM_DATA); } void OnStreamEnd(SpdyStreamId stream_id) override { @@ -133,13 +134,23 @@ } void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { - CloseConnection("SPDY frame padding received."); + CloseConnection("SPDY frame padding received.", + QUIC_INVALID_HEADERS_STREAM_DATA); } void OnError(SpdyFramer* framer) override { - CloseConnection(QuicStrCat( - "SPDY framing error: ", - SpdyFramer::SpdyFramerErrorToString(framer->spdy_framer_error()))); + QuicErrorCode code = QUIC_INVALID_HEADERS_STREAM_DATA; + SpdyFramer::SpdyFramerError error = framer->spdy_framer_error(); + switch (error) { + case SpdyFramer::SpdyFramerError::SPDY_DECOMPRESS_FAILURE: + code = QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE; + break; + default: + break; + } + CloseConnection(QuicStrCat("SPDY framing error: ", + SpdyFramer::SpdyFramerErrorToString(error)), + code); } void OnDataFrameHeader(SpdyStreamId stream_id, @@ -148,16 +159,19 @@ if (session_->OnDataFrameHeader(stream_id, length, fin)) { return; } - CloseConnection("SPDY DATA frame received."); + CloseConnection("SPDY DATA frame received.", + QUIC_INVALID_HEADERS_STREAM_DATA); } void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override { - CloseConnection("SPDY RST_STREAM frame received."); + CloseConnection("SPDY RST_STREAM frame received.", + QUIC_INVALID_HEADERS_STREAM_DATA); } void OnSetting(SpdySettingsIds id, uint32_t value) override { if (!FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame) { - CloseConnection("SPDY SETTINGS frame received."); + CloseConnection("SPDY SETTINGS frame received.", + QUIC_INVALID_HEADERS_STREAM_DATA); return; } switch (id) { @@ -170,14 +184,16 @@ // See rfc7540, Section 6.5.2. if (value > 1) { CloseConnection( - QuicStrCat("Invalid value for SETTINGS_ENABLE_PUSH: ", value)); + QuicStrCat("Invalid value for SETTINGS_ENABLE_PUSH: ", value), + QUIC_INVALID_HEADERS_STREAM_DATA); return; } session_->UpdateEnableServerPush(value > 0); break; } else { CloseConnection( - QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id)); + QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id), + QUIC_INVALID_HEADERS_STREAM_DATA); } break; // TODO(fayang): Need to support SETTINGS_MAX_HEADER_LIST_SIZE when @@ -188,29 +204,34 @@ } default: CloseConnection( - QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id)); + QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id), + QUIC_INVALID_HEADERS_STREAM_DATA); } } void OnSettingsAck() override { if (!FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame) { - CloseConnection("SPDY SETTINGS frame received."); + CloseConnection("SPDY SETTINGS frame received.", + QUIC_INVALID_HEADERS_STREAM_DATA); } } void OnSettingsEnd() override { if (!FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame) { - CloseConnection("SPDY SETTINGS frame received."); + CloseConnection("SPDY SETTINGS frame received.", + QUIC_INVALID_HEADERS_STREAM_DATA); } } void OnPing(SpdyPingId unique_id, bool is_ack) override { - CloseConnection("SPDY PING frame received."); + CloseConnection("SPDY PING frame received.", + QUIC_INVALID_HEADERS_STREAM_DATA); } void OnGoAway(SpdyStreamId last_accepted_stream_id, SpdyErrorCode error_code) override { - CloseConnection("SPDY GOAWAY frame received."); + CloseConnection("SPDY GOAWAY frame received.", + QUIC_INVALID_HEADERS_STREAM_DATA); } void OnHeaders(SpdyStreamId stream_id, @@ -232,14 +253,16 @@ } void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override { - CloseConnection("SPDY WINDOW_UPDATE frame received."); + CloseConnection("SPDY WINDOW_UPDATE frame received.", + QUIC_INVALID_HEADERS_STREAM_DATA); } void OnPushPromise(SpdyStreamId stream_id, SpdyStreamId promised_stream_id, bool end) override { if (!session_->supports_push_promise()) { - CloseConnection("PUSH_PROMISE not supported."); + CloseConnection("PUSH_PROMISE not supported.", + QUIC_INVALID_HEADERS_STREAM_DATA); return; } if (!session_->IsConnected()) { @@ -254,11 +277,13 @@ SpdyStreamId parent_id, int weight, bool exclusive) override { - CloseConnection("SPDY PRIORITY frame received."); + CloseConnection("SPDY PRIORITY frame received.", + QUIC_INVALID_HEADERS_STREAM_DATA); } bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override { - CloseConnection("Unknown frame type received."); + CloseConnection("Unknown frame type received.", + QUIC_INVALID_HEADERS_STREAM_DATA); return false; } @@ -290,10 +315,9 @@ } private: - void CloseConnection(const string& details) { + void CloseConnection(const string& details, QuicErrorCode code) { if (session_->IsConnected()) { - session_->CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA, - details); + session_->CloseConnectionWithDetails(code, details); } }
diff --git a/net/quic/core/quic_spdy_stream.cc b/net/quic/core/quic_spdy_stream.cc index 5d98d186..cbbd96d 100644 --- a/net/quic/core/quic_spdy_stream.cc +++ b/net/quic/core/quic_spdy_stream.cc
@@ -45,17 +45,6 @@ } } -void QuicSpdyStream::StopReading() { - if (!fin_received() && !rst_received() && write_side_closed() && - !rst_sent()) { - DCHECK(fin_sent()); - // Tell the peer to stop sending further data. - QUIC_DVLOG(1) << ENDPOINT << "Send QUIC_STREAM_NO_ERROR on stream " << id(); - Reset(QUIC_STREAM_NO_ERROR); - } - QuicStream::StopReading(); -} - size_t QuicSpdyStream::WriteHeaders( SpdyHeaderBlock header_block, bool fin,
diff --git a/net/quic/core/quic_spdy_stream.h b/net/quic/core/quic_spdy_stream.h index d92d3f9..247af4d 100644 --- a/net/quic/core/quic_spdy_stream.h +++ b/net/quic/core/quic_spdy_stream.h
@@ -66,8 +66,6 @@ QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session); ~QuicSpdyStream() override; - void StopReading() override; - // QuicStream implementation void OnClose() override;
diff --git a/net/quic/core/quic_transmission_info.h b/net/quic/core/quic_transmission_info.h index 6529f4e..1dee816 100644 --- a/net/quic/core/quic_transmission_info.h +++ b/net/quic/core/quic_transmission_info.h
@@ -58,6 +58,11 @@ // The largest_acked in the ack frame, if the packet contains an ack. QuicPacketNumber largest_acked; }; +// TODO(ianswett): Add static_assert when size of this struct is reduced below +// 64 bytes. +// NOTE(vlovich): Existing static_assert removed because padding differences on +// 64-bit iOS resulted in an 88-byte struct that is greater than the 84-byte +// limit on other platforms. Removing per ianswett's request. } // namespace net
diff --git a/net/quic/core/quic_types.h b/net/quic/core/quic_types.h index 30fefd2..fc665f3f 100644 --- a/net/quic/core/quic_types.h +++ b/net/quic/core/quic_types.h
@@ -16,7 +16,6 @@ namespace net { -typedef uint8_t QuicPathId; typedef uint16_t QuicPacketLength; typedef uint32_t QuicHeaderId; typedef uint32_t QuicStreamId; @@ -122,7 +121,6 @@ BLOCKED_FRAME = 5, STOP_WAITING_FRAME = 6, PING_FRAME = 7, - PATH_CLOSE_FRAME = 8, // STREAM and ACK frames are special frames. They are encoded differently on // the wire and their values do not need to be stable. @@ -184,6 +182,8 @@ PACKET_PUBLIC_FLAGS_4BYTE_PACKET = PACKET_FLAGS_4BYTE_PACKET << 4, PACKET_PUBLIC_FLAGS_6BYTE_PACKET = PACKET_FLAGS_6BYTE_PACKET << 4, + // TODO(fayang): Remove PACKET_PUBLIC_FLAGS_MULTIPATH when deprecating + // gfe2_reloadable_flag_quic_remove_multipath_bit. // Bit 6: Does the packet header contain a path id? PACKET_PUBLIC_FLAGS_MULTIPATH = 1 << 6, @@ -192,8 +192,14 @@ // Bit 7: indicates the presence of a second flags byte. PACKET_PUBLIC_FLAGS_TWO_OR_MORE_BYTES = 1 << 7, + // TODO(fayang): Remove PACKET_PUBLIC_FLAGS_MAX and rename + // PACKET_PUBLIC_FLAGS_MAX_WITHOUT_MULTIPATH_FLAG when deprecating + // gfe2_reloadable_flag_quic_remove_multipath_bit. // All bits set (bit 7 is not currently used): 01111111 PACKET_PUBLIC_FLAGS_MAX = (1 << 7) - 1, + + // All bits set (bits 6 and 7 are not currently used): 00111111 + PACKET_PUBLIC_FLAGS_MAX_WITHOUT_MULTIPATH_FLAG = (1 << 6) - 1, }; // The private flags are specified in one byte.
diff --git a/net/quic/test_tools/quic_connection_peer.cc b/net/quic/test_tools/quic_connection_peer.cc index 344013c..d96b9914 100644 --- a/net/quic/test_tools/quic_connection_peer.cc +++ b/net/quic/test_tools/quic_connection_peer.cc
@@ -104,11 +104,6 @@ } // static -bool QuicConnectionPeer::IsMultipathEnabled(QuicConnection* connection) { - return connection->multipath_enabled_; -} - -// static void QuicConnectionPeer::SwapCrypters(QuicConnection* connection, QuicFramer* framer) { QuicFramerPeer::SwapCrypters(framer, &connection->framer_);
diff --git a/net/quic/test_tools/quic_connection_peer.h b/net/quic/test_tools/quic_connection_peer.h index bea9972..81f4d1d 100644 --- a/net/quic/test_tools/quic_connection_peer.h +++ b/net/quic/test_tools/quic_connection_peer.h
@@ -66,8 +66,6 @@ static bool IsSilentCloseEnabled(QuicConnection* connection); - static bool IsMultipathEnabled(QuicConnection* connection); - static void SwapCrypters(QuicConnection* connection, QuicFramer* framer); static void SetCurrentPacket(QuicConnection* connection,
diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc index a6c1a91..adf9df17a 100644 --- a/net/quic/test_tools/quic_test_utils.cc +++ b/net/quic/test_tools/quic_test_utils.cc
@@ -221,10 +221,6 @@ return true; } -bool NoOpFramerVisitor::OnPathCloseFrame(const QuicPathCloseFrame& frame) { - return true; -} - MockQuicConnectionVisitor::MockQuicConnectionVisitor() {} MockQuicConnectionVisitor::~MockQuicConnectionVisitor() {} @@ -554,48 +550,44 @@ QuicEncryptedPacket* ConstructEncryptedPacket(QuicConnectionId connection_id, bool version_flag, - bool multipath_flag, bool reset_flag, QuicPacketNumber packet_number, const string& data) { return ConstructEncryptedPacket( - connection_id, version_flag, multipath_flag, reset_flag, packet_number, - data, PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER); + connection_id, version_flag, reset_flag, packet_number, data, + PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER); } QuicEncryptedPacket* ConstructEncryptedPacket( QuicConnectionId connection_id, bool version_flag, - bool multipath_flag, bool reset_flag, QuicPacketNumber packet_number, const string& data, QuicConnectionIdLength connection_id_length, QuicPacketNumberLength packet_number_length) { - return ConstructEncryptedPacket( - connection_id, version_flag, multipath_flag, reset_flag, packet_number, - data, connection_id_length, packet_number_length, nullptr); + return ConstructEncryptedPacket(connection_id, version_flag, reset_flag, + packet_number, data, connection_id_length, + packet_number_length, nullptr); } QuicEncryptedPacket* ConstructEncryptedPacket( QuicConnectionId connection_id, bool version_flag, - bool multipath_flag, bool reset_flag, QuicPacketNumber packet_number, const string& data, QuicConnectionIdLength connection_id_length, QuicPacketNumberLength packet_number_length, QuicVersionVector* versions) { - return ConstructEncryptedPacket(connection_id, version_flag, multipath_flag, - reset_flag, packet_number, data, - connection_id_length, packet_number_length, - versions, Perspective::IS_CLIENT); + return ConstructEncryptedPacket(connection_id, version_flag, reset_flag, + packet_number, data, connection_id_length, + packet_number_length, versions, + Perspective::IS_CLIENT); } QuicEncryptedPacket* ConstructEncryptedPacket( QuicConnectionId connection_id, bool version_flag, - bool multipath_flag, bool reset_flag, QuicPacketNumber packet_number, const string& data, @@ -607,7 +599,7 @@ header.public_header.connection_id = connection_id; header.public_header.connection_id_length = connection_id_length; header.public_header.version_flag = version_flag; - header.public_header.multipath_flag = multipath_flag; + header.public_header.multipath_flag = false; header.public_header.reset_flag = reset_flag; header.public_header.packet_number_length = packet_number_length; header.packet_number = packet_number;
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h index 5f153a2..a53d2fb 100644 --- a/net/quic/test_tools/quic_test_utils.h +++ b/net/quic/test_tools/quic_test_utils.h
@@ -70,7 +70,6 @@ QuicEncryptedPacket* ConstructEncryptedPacket( QuicConnectionId connection_id, bool version_flag, - bool multipath_flag, bool reset_flag, QuicPacketNumber packet_number, const std::string& data, @@ -86,7 +85,6 @@ QuicEncryptedPacket* ConstructEncryptedPacket( QuicConnectionId connection_id, bool version_flag, - bool multipath_flag, bool reset_flag, QuicPacketNumber packet_number, const std::string& data, @@ -98,7 +96,6 @@ QuicEncryptedPacket* ConstructEncryptedPacket( QuicConnectionId connection_id, bool version_flag, - bool multipath_flag, bool reset_flag, QuicPacketNumber packet_number, const std::string& data, @@ -110,7 +107,6 @@ // |versions| == nullptr. QuicEncryptedPacket* ConstructEncryptedPacket(QuicConnectionId connection_id, bool version_flag, - bool multipath_flag, bool reset_flag, QuicPacketNumber packet_number, const std::string& data); @@ -247,7 +243,6 @@ MOCK_METHOD1(OnGoAwayFrame, bool(const QuicGoAwayFrame& frame)); MOCK_METHOD1(OnWindowUpdateFrame, bool(const QuicWindowUpdateFrame& frame)); MOCK_METHOD1(OnBlockedFrame, bool(const QuicBlockedFrame& frame)); - MOCK_METHOD1(OnPathCloseFrame, bool(const QuicPathCloseFrame& frame)); MOCK_METHOD0(OnPacketComplete, void()); private: @@ -279,7 +274,6 @@ bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override; bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override; bool OnBlockedFrame(const QuicBlockedFrame& frame) override; - bool OnPathCloseFrame(const QuicPathCloseFrame& frame) override; void OnPacketComplete() override {} private:
diff --git a/net/quic/test_tools/simple_quic_framer.cc b/net/quic/test_tools/simple_quic_framer.cc index 18b449cf..734b1dc 100644 --- a/net/quic/test_tools/simple_quic_framer.cc +++ b/net/quic/test_tools/simple_quic_framer.cc
@@ -106,11 +106,6 @@ return true; } - bool OnPathCloseFrame(const QuicPathCloseFrame& frame) override { - path_close_frames_.push_back(frame); - return true; - } - void OnPacketComplete() override {} const QuicPacketHeader& header() const { return header_; } @@ -151,7 +146,6 @@ std::vector<QuicConnectionCloseFrame> connection_close_frames_; std::vector<QuicWindowUpdateFrame> window_update_frames_; std::vector<QuicBlockedFrame> blocked_frames_; - std::vector<QuicPathCloseFrame> path_close_frames_; std::vector<std::unique_ptr<string>> stream_data_; DISALLOW_COPY_AND_ASSIGN(SimpleFramerVisitor);
diff --git a/net/tools/quic/chlo_extractor.cc b/net/tools/quic/chlo_extractor.cc index 56a40573..0235f72 100644 --- a/net/tools/quic/chlo_extractor.cc +++ b/net/tools/quic/chlo_extractor.cc
@@ -45,7 +45,6 @@ bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override; bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override; bool OnBlockedFrame(const QuicBlockedFrame& frame) override; - bool OnPathCloseFrame(const QuicPathCloseFrame& frame) override; bool OnPaddingFrame(const QuicPaddingFrame& frame) override; void OnPacketComplete() override {} @@ -136,10 +135,6 @@ return true; } -bool ChloFramerVisitor::OnPathCloseFrame(const QuicPathCloseFrame& frame) { - return true; -} - bool ChloFramerVisitor::OnPaddingFrame(const QuicPaddingFrame& frame) { return true; }
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc index 9a7ca65..4b4b0c5 100644 --- a/net/tools/quic/end_to_end_test.cc +++ b/net/tools/quic/end_to_end_test.cc
@@ -1322,9 +1322,6 @@ TEST_P(EndToEndTest, NegotiateCongestionControl) { FLAGS_quic_reloadable_flag_quic_allow_new_bbr = true; - // Disable this flag because if connection uses multipath sent packet manager, - // static_cast here does not work. - FLAGS_quic_reloadable_flag_quic_enable_multipath = false; ASSERT_TRUE(Initialize()); EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed()); @@ -2205,7 +2202,7 @@ std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( client_->client()->session()->connection()->connection_id(), false, false, - false, 1, "At least 20 characters.", PACKET_8BYTE_CONNECTION_ID, + 1, "At least 20 characters.", PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER)); // Damage the encrypted data. string damaged_packet(packet->data(), packet->length()); @@ -3009,6 +3006,21 @@ EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer)); } +TEST_P(EndToEndTest, WayTooLongRequestHeaders) { + ASSERT_TRUE(Initialize()); + SpdyHeaderBlock headers; + headers[":method"] = "GET"; + headers[":path"] = "/foo"; + headers[":scheme"] = "https"; + headers[":authority"] = server_hostname_; + headers["key"] = string(64 * 1024, 'a'); + + client_->SendMessage(headers, ""); + client_->WaitForResponse(); + EXPECT_EQ(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE, + client_->connection_error()); +} + class EndToEndBufferedPacketsTest : public EndToEndTest { public: void CreateClientWithWriter() override {
diff --git a/net/tools/quic/quic_client_session_test.cc b/net/tools/quic/quic_client_session_test.cc index 1ed9bd9b..1909450c 100644 --- a/net/tools/quic/quic_client_session_test.cc +++ b/net/tools/quic/quic_client_session_test.cc
@@ -267,9 +267,8 @@ // Verify that a non-decryptable packet doesn't close the connection. QuicConnectionId connection_id = session_->connection()->connection_id(); std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( - connection_id, false, false, false, 100, "data", - PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, nullptr, - Perspective::IS_SERVER)); + connection_id, false, false, 100, "data", PACKET_8BYTE_CONNECTION_ID, + PACKET_6BYTE_PACKET_NUMBER, nullptr, Perspective::IS_SERVER)); std::unique_ptr<QuicReceivedPacket> received( ConstructReceivedPacket(*packet, QuicTime::Zero())); // Change the last byte of the encrypted data.
diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc index 801e1f2..303a597a 100644 --- a/net/tools/quic/quic_dispatcher.cc +++ b/net/tools/quic/quic_dispatcher.cc
@@ -626,11 +626,6 @@ return false; } -bool QuicDispatcher::OnPathCloseFrame(const QuicPathCloseFrame& frame) { - DCHECK(false); - return false; -} - void QuicDispatcher::OnPacketComplete() { DCHECK(false); }
diff --git a/net/tools/quic/quic_dispatcher.h b/net/tools/quic/quic_dispatcher.h index 266e3e4..50d754f 100644 --- a/net/tools/quic/quic_dispatcher.h +++ b/net/tools/quic/quic_dispatcher.h
@@ -141,7 +141,6 @@ bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override; bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override; bool OnBlockedFrame(const QuicBlockedFrame& frame) override; - bool OnPathCloseFrame(const QuicPathCloseFrame& frame) override; void OnPacketComplete() override; // QuicBufferedPacketStore::VisitorInterface implementation.
diff --git a/net/tools/quic/quic_dispatcher_test.cc b/net/tools/quic/quic_dispatcher_test.cc index 6fcc2db..621890ab 100644 --- a/net/tools/quic/quic_dispatcher_test.cc +++ b/net/tools/quic/quic_dispatcher_test.cc
@@ -208,11 +208,9 @@ void ProcessPacket(QuicSocketAddress client_address, QuicConnectionId connection_id, bool has_version_flag, - bool has_multipath_flag, const string& data) { - ProcessPacket(client_address, connection_id, has_version_flag, - has_multipath_flag, data, PACKET_8BYTE_CONNECTION_ID, - PACKET_6BYTE_PACKET_NUMBER); + ProcessPacket(client_address, connection_id, has_version_flag, data, + PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER); } // Process a packet with a default path id, and packet number 1, @@ -220,20 +218,17 @@ void ProcessPacket(QuicSocketAddress client_address, QuicConnectionId connection_id, bool has_version_flag, - bool has_multipath_flag, const string& data, QuicConnectionIdLength connection_id_length, QuicPacketNumberLength packet_number_length) { - ProcessPacket(client_address, connection_id, has_version_flag, - has_multipath_flag, data, connection_id_length, - packet_number_length, 1); + ProcessPacket(client_address, connection_id, has_version_flag, data, + connection_id_length, packet_number_length, 1); } // Process a packet using the first supported version. void ProcessPacket(QuicSocketAddress client_address, QuicConnectionId connection_id, bool has_version_flag, - bool has_multipath_flag, const string& data, QuicConnectionIdLength connection_id_length, QuicPacketNumberLength packet_number_length, @@ -254,7 +249,7 @@ QuicPacketNumber packet_number) { QuicVersionVector versions(SupportedVersions(version)); std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( - connection_id, has_version_flag, false, false, packet_number, data, + connection_id, has_version_flag, false, packet_number, data, connection_id_length, packet_number_length, &versions)); std::unique_ptr<QuicReceivedPacket> received_packet( ConstructReceivedPacket(*packet, helper_.GetClock()->Now())); @@ -277,7 +272,8 @@ const QuicEncryptedPacket& packet) { EXPECT_EQ(data_connection_map_[conn_id].front().length(), packet.AsStringPiece().length()); - EXPECT_EQ(data_connection_map_[conn_id].front(), packet.AsStringPiece()); + EXPECT_EQ(data_connection_map_[conn_id].front(), + packet.AsStringPiece().as_string()); data_connection_map_[conn_id].pop_front(); } @@ -348,7 +344,7 @@ ProcessUdpPacket(_, _, _)) .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); - ProcessPacket(client_address, 1, true, false, SerializeCHLO()); + ProcessPacket(client_address, 1, true, SerializeCHLO()); EXPECT_EQ(client_address, dispatcher_->current_client_address()); EXPECT_EQ(server_address_, dispatcher_->current_server_address()); @@ -361,14 +357,14 @@ ProcessUdpPacket(_, _, _)) .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 2)))); - ProcessPacket(client_address, 2, true, false, SerializeCHLO()); + ProcessPacket(client_address, 2, true, SerializeCHLO()); EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), ProcessUdpPacket(_, _, _)) .Times(1) .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); - ProcessPacket(client_address, 1, false, false, "data"); + ProcessPacket(client_address, 1, false, "data"); } TEST_F(QuicDispatcherTest, StatelessVersionNegotiation) { @@ -394,7 +390,7 @@ .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); - ProcessPacket(client_address, 1, true, false, SerializeCHLO()); + ProcessPacket(client_address, 1, true, SerializeCHLO()); EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); @@ -418,7 +414,7 @@ .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); - ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); + ProcessPacket(client_address, connection_id, true, SerializeCHLO()); // Close the connection by sending public reset packet. QuicPublicResetPacket packet; @@ -452,7 +448,7 @@ .Times(1); EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _)) .Times(0); - ProcessPacket(client_address, connection_id, true, false, "data"); + ProcessPacket(client_address, connection_id, true, "data"); } TEST_F(QuicDispatcherTest, NoVersionPacketToTimeWaitListManager) { @@ -468,7 +464,7 @@ .Times(1); EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _)) .Times(1); - ProcessPacket(client_address, connection_id, false, false, SerializeCHLO()); + ProcessPacket(client_address, connection_id, false, SerializeCHLO()); } TEST_F(QuicDispatcherTest, ProcessPacketWithZeroPort) { @@ -482,7 +478,7 @@ EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0); EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _)) .Times(0); - ProcessPacket(client_address, 1, true, false, SerializeCHLO()); + ProcessPacket(client_address, 1, true, SerializeCHLO()); } TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) { @@ -501,7 +497,7 @@ &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); // A packet whose packet number is the largest that is allowed to start a // connection. - ProcessPacket(client_address, connection_id, true, false, SerializeCHLO(), + ProcessPacket(client_address, connection_id, true, SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, QuicDispatcher::kMaxReasonableInitialPacketNumber); EXPECT_EQ(client_address, dispatcher_->current_client_address()); @@ -523,7 +519,7 @@ .Times(1); // A packet whose packet number is one to large to be allowed to start a // connection. - ProcessPacket(client_address, connection_id, true, false, SerializeCHLO(), + ProcessPacket(client_address, connection_id, true, SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, QuicDispatcher::kMaxReasonableInitialPacketNumber + 1); } @@ -762,7 +758,7 @@ Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, base::Unretained(this), connection_id)))); // Process the first packet for the connection. - ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); + ProcessPacket(client_address, connection_id, true, SerializeCHLO()); if (ExpectStatelessReject()) { // If this is a stateless reject, the crypto stream will close the // connection. @@ -789,7 +785,7 @@ Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, base::Unretained(this), connection_id)))); } - ProcessPacket(client_address, connection_id, true, false, "data"); + ProcessPacket(client_address, connection_id, true, "data"); } TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) { @@ -822,7 +818,7 @@ {"VER\0", "Q025"}}, kClientHelloMinimumSize); - ProcessPacket(client_address, connection_id, true, false, + ProcessPacket(client_address, connection_id, true, client_hello.GetSerialized().AsStringPiece().as_string()); if (GetParam().enable_stateless_rejects_via_flag) { @@ -838,8 +834,7 @@ const QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1); const QuicConnectionId connection_id = 1; - ProcessPacket(client_address, connection_id, true, false, - "NOT DATA FOR A CHLO"); + ProcessPacket(client_address, connection_id, true, "NOT DATA FOR A CHLO"); // Process the first packet for the connection. CryptoHandshakeMessage client_hello = @@ -867,7 +862,7 @@ Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, base::Unretained(this), connection_id)))) .RetiresOnSaturation(); - ProcessPacket(client_address, connection_id, true, false, + ProcessPacket(client_address, connection_id, true, client_hello.GetSerialized().AsStringPiece().as_string()); EXPECT_FALSE( time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); @@ -891,7 +886,7 @@ .Times(0); EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _)) .Times(0); - ProcessPacket(client_address, connection_id, true, false, "data", + ProcessPacket(client_address, connection_id, true, "data", PACKET_0BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER); } @@ -935,7 +930,7 @@ ProcessUdpPacket(_, _, _)) .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); - ProcessPacket(client_address, 1, true, false, SerializeCHLO()); + ProcessPacket(client_address, 1, true, SerializeCHLO()); EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) .WillOnce(testing::Return(CreateSession( @@ -946,7 +941,7 @@ ProcessUdpPacket(_, _, _)) .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 2)))); - ProcessPacket(client_address, 2, true, false, SerializeCHLO()); + ProcessPacket(client_address, 2, true, SerializeCHLO()); blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get()); } @@ -1195,7 +1190,7 @@ EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id)) .Times(1); for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) { - ProcessPacket(client_address, conn_id, true, false, + ProcessPacket(client_address, conn_id, true, QuicStrCat("data packet ", i + 1), PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, /*packet_number=*/i + 1); } @@ -1220,7 +1215,7 @@ .WillRepeatedly(testing::WithArg<2>( Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, base::Unretained(this), conn_id)))); - ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); + ProcessPacket(client_address, conn_id, true, SerializeFullCHLO()); } TEST_P(BufferedPacketStoreTest, @@ -1248,7 +1243,7 @@ ShouldCreateOrBufferPacketForConnection(conn_id)); } } - ProcessPacket(client_address, conn_id, true, false, + ProcessPacket(client_address, conn_id, true, QuicStrCat("data packet on connection ", i), PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, /*packet_number=*/2); @@ -1299,7 +1294,7 @@ .WillRepeatedly(testing::WithArg<2>( Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, base::Unretained(this), conn_id)))); - ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); + ProcessPacket(client_address, conn_id, true, SerializeFullCHLO()); } } @@ -1313,7 +1308,7 @@ dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, &mock_alarm_factory_, &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); - ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); + ProcessPacket(client_address, conn_id, true, SerializeFullCHLO()); } // Tests that a retransmitted CHLO arrives after a connection for the @@ -1323,9 +1318,9 @@ QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1); server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5); QuicConnectionId conn_id = 1; - ProcessPacket(client_address, conn_id, true, false, - QuicStrCat("data packet ", 2), PACKET_8BYTE_CONNECTION_ID, - PACKET_6BYTE_PACKET_NUMBER, /*packet_number=*/2); + ProcessPacket(client_address, conn_id, true, QuicStrCat("data packet ", 2), + PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, + /*packet_number=*/2); // When CHLO arrives, a new session should be created, and all packets // buffered should be delivered to the session. @@ -1341,9 +1336,9 @@ .WillRepeatedly(testing::WithArg<2>( Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, base::Unretained(this), conn_id)))); - ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); + ProcessPacket(client_address, conn_id, true, SerializeFullCHLO()); - ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); + ProcessPacket(client_address, conn_id, true, SerializeFullCHLO()); } // Tests that expiration of a connection add connection id to time wait list. @@ -1357,9 +1352,9 @@ QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1); server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5); QuicConnectionId conn_id = 1; - ProcessPacket(client_address, conn_id, true, false, - QuicStrCat("data packet ", 2), PACKET_8BYTE_CONNECTION_ID, - PACKET_6BYTE_PACKET_NUMBER, /*packet_number=*/2); + ProcessPacket(client_address, conn_id, true, QuicStrCat("data packet ", 2), + PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, + /*packet_number=*/2); mock_helper_.AdvanceTime( QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs)); @@ -1371,7 +1366,7 @@ // list. ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id)); EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _)); - ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); + ProcessPacket(client_address, conn_id, true, SerializeFullCHLO()); } TEST_P(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) { @@ -1410,7 +1405,7 @@ Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, base::Unretained(this), conn_id)))); } - ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); + ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO()); if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore && conn_id > kMaxNumSessionsToCreate) { EXPECT_TRUE(store->HasChloForConnection(conn_id)); @@ -1469,12 +1464,11 @@ Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, base::Unretained(this), conn_id)))); } - ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); + ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO()); } // Retransmit CHLO on last connection should be dropped. QuicConnectionId last_connection = kMaxNumSessionsToCreate + 1; - ProcessPacket(client_addr_, last_connection, true, false, - SerializeFullCHLO()); + ProcessPacket(client_addr_, last_connection, true, SerializeFullCHLO()); size_t packets_buffered = 2; if (!FLAGS_quic_reloadable_flag_quic_buffer_packets_after_chlo) { @@ -1516,14 +1510,14 @@ Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, base::Unretained(this), conn_id)))); } - ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); + ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO()); } // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The // last one should be dropped. for (QuicPacketNumber packet_number = 2; packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) { - ProcessPacket(client_addr_, last_connection_id, true, false, "data packet"); + ProcessPacket(client_addr_, last_connection_id, true, "data packet"); } // Reset counter and process buffered CHLO. @@ -1551,7 +1545,7 @@ QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get()); QuicConnectionId conn_id = 1; - ProcessPacket(client_addr_, conn_id, true, false, "data packet", + ProcessPacket(client_addr_, conn_id, true, "data packet", PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, /*packet_number=*/1); // Fill packet buffer to full with CHLOs on other connections. Need to feed @@ -1573,13 +1567,12 @@ Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, base::Unretained(this), conn_id)))); } - ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); + ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO()); } EXPECT_FALSE(store->HasChloForConnection(/*connection_id=*/1)); // CHLO on connection 1 should still be buffered. - ProcessPacket(client_addr_, /*connection_id=*/1, true, false, - SerializeFullCHLO()); + ProcessPacket(client_addr_, /*connection_id=*/1, true, SerializeFullCHLO()); EXPECT_TRUE(store->HasChloForConnection(/*connection_id=*/1)); } @@ -1702,7 +1695,7 @@ } // Send a CHLO that the StatelessRejector will accept. - ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); + ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO()); ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); check.Call(1); @@ -1713,7 +1706,7 @@ check.Call(2); // Verify that a data packet gets processed immediately. - ProcessPacket(client_addr_, conn_id, true, false, "My name is Data"); + ProcessPacket(client_addr_, conn_id, true, "My name is Data"); } // Test a simple situation of connections which the StatelessRejector will @@ -1740,7 +1733,7 @@ } // Send a CHLO that the StatelessRejector will reject. - ProcessPacket(client_addr_, conn_id, true, false, SerializeCHLO()); + ProcessPacket(client_addr_, conn_id, true, SerializeCHLO()); ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); // Complete the ProofSource::GetProof call and verify that the connection and @@ -1751,7 +1744,7 @@ // Verify that a data packet is passed to the time wait list manager. check.Call(2); - ProcessPacket(client_addr_, conn_id, true, false, "My name is Data"); + ProcessPacket(client_addr_, conn_id, true, "My name is Data"); } // Test a situation with multiple interleaved connections which the @@ -1801,11 +1794,11 @@ } // Send a CHLO that the StatelessRejector will accept. - ProcessPacket(client_addr_, conn_id_1, true, false, SerializeFullCHLO()); + ProcessPacket(client_addr_, conn_id_1, true, SerializeFullCHLO()); ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); // Send another CHLO that the StatelessRejector will accept. - ProcessPacket(client_addr_, conn_id_2, true, false, SerializeFullCHLO()); + ProcessPacket(client_addr_, conn_id_2, true, SerializeFullCHLO()); ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2); // Complete the second ProofSource::GetProof call and verify that a session is @@ -1816,12 +1809,12 @@ // Verify that a data packet on that connection gets processed immediately. check.Call(2); - ProcessPacket(client_addr_, conn_id_2, true, false, "My name is Data"); + ProcessPacket(client_addr_, conn_id_2, true, "My name is Data"); // Verify that a data packet on the other connection does not get processed // yet. check.Call(3); - ProcessPacket(client_addr_, conn_id_1, true, false, "My name is Data"); + ProcessPacket(client_addr_, conn_id_1, true, "My name is Data"); EXPECT_TRUE(store->HasBufferedPackets(conn_id_1)); EXPECT_FALSE(store->HasBufferedPackets(conn_id_2)); @@ -1870,11 +1863,11 @@ } // Send a CHLO that the StatelessRejector will reject. - ProcessPacket(client_addr_, conn_id_1, true, false, SerializeCHLO()); + ProcessPacket(client_addr_, conn_id_1, true, SerializeCHLO()); ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); // Send another CHLO that the StatelessRejector will reject. - ProcessPacket(client_addr_, conn_id_2, true, false, SerializeCHLO()); + ProcessPacket(client_addr_, conn_id_2, true, SerializeCHLO()); ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2); // Complete the second ProofSource::GetProof call and verify that the @@ -1886,11 +1879,11 @@ // Verify that a data packet on that connection gets processed immediately by // the time wait manager. check.Call(2); - ProcessPacket(client_addr_, conn_id_2, true, false, "My name is Data"); + ProcessPacket(client_addr_, conn_id_2, true, "My name is Data"); // Verify that a data packet on the first connection gets buffered. check.Call(3); - ProcessPacket(client_addr_, conn_id_1, true, false, "My name is Data"); + ProcessPacket(client_addr_, conn_id_1, true, "My name is Data"); EXPECT_TRUE(store->HasBufferedPackets(conn_id_1)); EXPECT_FALSE(store->HasBufferedPackets(conn_id_2)); @@ -1929,13 +1922,13 @@ } // Send a CHLO that the StatelessRejector will reject. - ProcessPacket(client_addr_, conn_id_1, true, false, SerializeCHLO()); + ProcessPacket(client_addr_, conn_id_1, true, SerializeCHLO()); ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); EXPECT_FALSE(store->HasBufferedPackets(conn_id_1)); // Send an identical CHLO which should get buffered. check.Call(1); - ProcessPacket(client_addr_, conn_id_1, true, false, SerializeCHLO()); + ProcessPacket(client_addr_, conn_id_1, true, SerializeCHLO()); ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); EXPECT_TRUE(store->HasBufferedPackets(conn_id_1)); @@ -1971,13 +1964,13 @@ } // Send a CHLO that the StatelessRejector will accept. - ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); + ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO()); ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); EXPECT_FALSE(store->HasBufferedPackets(conn_id)); // Send a data packet that will get buffered check.Call(1); - ProcessPacket(client_addr_, conn_id, true, false, "My name is Data"); + ProcessPacket(client_addr_, conn_id, true, "My name is Data"); EXPECT_TRUE(store->HasBufferedPackets(conn_id)); // Pretend that enough time has gone by for the packets to get expired out of @@ -2029,13 +2022,13 @@ } // Send a CHLO that the StatelessRejector will accept. - ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); + ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO()); ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); EXPECT_FALSE(store->HasBufferedPackets(conn_id)); // Send a data packet that will get buffered check.Call(1); - ProcessPacket(client_addr_, conn_id, true, false, "My name is Data"); + ProcessPacket(client_addr_, conn_id, true, "My name is Data"); EXPECT_TRUE(store->HasBufferedPackets(conn_id)); // Pretend that enough time has gone by for the packets to get expired out of
diff --git a/net/tools/quic/quic_packet_printer_bin.cc b/net/tools/quic/quic_packet_printer_bin.cc index ccac643..aa26b479 100644 --- a/net/tools/quic/quic_packet_printer_bin.cc +++ b/net/tools/quic/quic_packet_printer_bin.cc
@@ -142,10 +142,6 @@ std::cerr << "OnBlockedFrame: " << frame; return true; } - bool OnPathCloseFrame(const QuicPathCloseFrame& frame) override { - std::cerr << "OnPathCloseFrame:" << frame; - return true; - } void OnPacketComplete() override { std::cerr << "OnPacketComplete\n"; } private:
diff --git a/net/tools/quic/quic_spdy_server_stream_base.cc b/net/tools/quic/quic_spdy_server_stream_base.cc index e8451689..f7af873 100644 --- a/net/tools/quic/quic_spdy_server_stream_base.cc +++ b/net/tools/quic/quic_spdy_server_stream_base.cc
@@ -20,11 +20,22 @@ // or RST. DCHECK(fin_sent()); // Tell the peer to stop sending further data. - QUIC_DVLOG(0) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id(); + QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id(); Reset(QUIC_STREAM_NO_ERROR); } QuicSpdyStream::CloseWriteSide(); } +void QuicSpdyServerStreamBase::StopReading() { + if (!fin_received() && !rst_received() && write_side_closed() && + !rst_sent()) { + DCHECK(fin_sent()); + // Tell the peer to stop sending further data. + QUIC_DVLOG(1) << " Server: Send QUIC_STREAM_NO_ERROR on stream " << id(); + Reset(QUIC_STREAM_NO_ERROR); + } + QuicSpdyStream::StopReading(); +} + } // namespace net
diff --git a/net/tools/quic/quic_spdy_server_stream_base.h b/net/tools/quic/quic_spdy_server_stream_base.h index 880642a7..46462a1 100644 --- a/net/tools/quic/quic_spdy_server_stream_base.h +++ b/net/tools/quic/quic_spdy_server_stream_base.h
@@ -16,6 +16,7 @@ // Override the base class to send QUIC_STREAM_NO_ERROR to the peer // when the stream has not received all the data. void CloseWriteSide() override; + void StopReading() override; private: DISALLOW_COPY_AND_ASSIGN(QuicSpdyServerStreamBase);
diff --git a/net/tools/quic/quic_time_wait_list_manager_test.cc b/net/tools/quic/quic_time_wait_list_manager_test.cc index 78fb04d..0ff4f8d 100644 --- a/net/tools/quic/quic_time_wait_list_manager_test.cc +++ b/net/tools/quic/quic_time_wait_list_manager_test.cc
@@ -125,7 +125,7 @@ QuicConnectionId connection_id, QuicPacketNumber packet_number) { return net::test::ConstructEncryptedPacket(connection_id, false, false, - false, packet_number, "data"); + packet_number, "data"); } QuicFlagSaver flags_; // Save/restore all QUIC flag values.
diff --git a/printing/BUILD.gn b/printing/BUILD.gn index 8883c758..e9f5d5cb 100644 --- a/printing/BUILD.gn +++ b/printing/BUILD.gn
@@ -189,6 +189,8 @@ "backend/cups_deleters.h", "backend/cups_ipp_util.cc", "backend/cups_ipp_util.h", + "backend/cups_jobs.cc", + "backend/cups_jobs.h", "backend/cups_printer.cc", "backend/cups_printer.h", "backend/print_backend_cups_ipp.cc",
diff --git a/printing/backend/cups_connection.cc b/printing/backend/cups_connection.cc index 2b0f8c8..867e0dc 100644 --- a/printing/backend/cups_connection.cc +++ b/printing/backend/cups_connection.cc
@@ -4,18 +4,31 @@ #include "printing/backend/cups_connection.h" +#include <map> +#include <set> #include <string> #include <utility> #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" +#include "printing/backend/cups_jobs.h" namespace printing { namespace { -const int kTimeoutMs = 3000; +constexpr int kTimeoutMs = 3000; + +// The number of jobs we'll retrieve for a queue. We expect a user to queue at +// most 10 jobs per printer. If they queue more, they won't receive updates for +// the 11th job until one finishes. +constexpr int kProcessingJobsLimit = 10; + +// The number of completed jobs that are retrieved. We only need one update for +// a completed job to confirm its final status. We could retrieve one but we +// retrieve the last 3 in case that many finished between queries. +constexpr int kCompletedJobsLimit = 3; class DestinationEnumerator { public: @@ -44,42 +57,6 @@ DISALLOW_COPY_AND_ASSIGN(DestinationEnumerator); }; -CupsJob createCupsJob(int job_id, - base::StringPiece job_title, - base::StringPiece printer_id, - ipp_jstate_t state) { - CupsJob::JobState converted_state = CupsJob::UNKNOWN; - switch (state) { - case IPP_JOB_ABORTED: - converted_state = CupsJob::ABORTED; - break; - case IPP_JOB_CANCELLED: - converted_state = CupsJob::CANCELED; - break; - case IPP_JOB_COMPLETED: - converted_state = CupsJob::COMPLETED; - break; - case IPP_JOB_HELD: - converted_state = CupsJob::HELD; - break; - case IPP_JOB_PENDING: - converted_state = CupsJob::PENDING; - break; - case IPP_JOB_PROCESSING: - converted_state = CupsJob::PROCESSING; - break; - case IPP_JOB_STOPPED: - converted_state = CupsJob::STOPPED; - break; - default: - NOTREACHED(); - break; - } - - return {job_id, job_title.as_string(), printer_id.as_string(), - converted_state}; -} - } // namespace CupsConnection::CupsConnection(const GURL& print_server_url, @@ -162,24 +139,41 @@ std::unique_ptr<cups_dinfo_t, DestInfoDeleter>(info)); } -std::vector<CupsJob> CupsConnection::GetJobs() { - cups_job_t* jobs; - int num_jobs = cupsGetJobs2(cups_http_.get(), // http connection - &jobs, // out param - nullptr, // all printers - 0, // all users - CUPS_WHICHJOBS_ALL); - - const JobsDeleter deleter(num_jobs); - std::unique_ptr<cups_job_t, const JobsDeleter&> scoped_jobs(jobs, deleter); - - std::vector<CupsJob> job_copies; - for (int i = 0; i < num_jobs; i++) { - job_copies.push_back( - createCupsJob(jobs[i].id, jobs[i].title, jobs[i].dest, jobs[i].state)); +bool CupsConnection::GetJobs(const std::vector<std::string>& printer_ids, + std::vector<QueueStatus>* queues) { + DCHECK(queues); + if (!Connect()) { + LOG(ERROR) << "Could not establish connection to CUPS"; + return false; } - return job_copies; + std::vector<QueueStatus> temp_queues; + + for (const std::string& id : printer_ids) { + temp_queues.emplace_back(); + QueueStatus* queue_status = &temp_queues.back(); + + if (!GetPrinterStatus(cups_http_.get(), id, + &queue_status->printer_status)) { + LOG(WARNING) << "Could not retrieve printer status for " << id; + return false; + } + + if (!GetCupsJobs(cups_http_.get(), id, kCompletedJobsLimit, COMPLETED, + &queue_status->jobs)) { + LOG(WARNING) << "Could not get completed jobs for " << id; + return false; + } + + if (!GetCupsJobs(cups_http_.get(), id, kProcessingJobsLimit, PROCESSING, + &queue_status->jobs)) { + LOG(WARNING) << "Could not get in progress jobs for " << id; + return false; + } + } + queues->insert(queues->end(), temp_queues.begin(), temp_queues.end()); + + return true; } std::string CupsConnection::server_name() const {
diff --git a/printing/backend/cups_connection.h b/printing/backend/cups_connection.h index fe8a7a2..0f0475e4 100644 --- a/printing/backend/cups_connection.h +++ b/printing/backend/cups_connection.h
@@ -14,29 +14,17 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "printing/backend/cups_deleters.h" +#include "printing/backend/cups_jobs.h" #include "printing/backend/cups_printer.h" #include "printing/printing_export.h" #include "url/gurl.h" namespace printing { -// Represents a print job sent to the queue. -struct PRINTING_EXPORT CupsJob { - enum JobState { - UNKNOWN, - PENDING, - HELD, - COMPLETED, - PROCESSING, - STOPPED, - CANCELED, - ABORTED - }; - - int id; - std::string title; - std::string printer_id; - JobState state; +// Represents the status of a printer queue. +struct PRINTING_EXPORT QueueStatus { + PrinterStatus printer_status; + std::vector<CupsJob> jobs; }; // Represents a connection to a CUPS server. @@ -56,8 +44,12 @@ // Returns a printer for |printer_name| from the connected server. std::unique_ptr<CupsPrinter> GetPrinter(const std::string& printer_name); - // Returns a list of print jobs from all connected printers. - std::vector<CupsJob> GetJobs(); + // Queries CUPS for printer queue status for |printer_ids|. Populates |jobs| + // with said information with one QueueStatus per printer_id. Returns true if + // all the queries were successful. In the event of failure, |jobs| will be + // unchanged. + bool GetJobs(const std::vector<std::string>& printer_ids, + std::vector<QueueStatus>* jobs); std::string server_name() const;
diff --git a/printing/backend/cups_ipp_util.h b/printing/backend/cups_ipp_util.h index 670a9e3..2c4765e 100644 --- a/printing/backend/cups_ipp_util.h +++ b/printing/backend/cups_ipp_util.h
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Methods for parsing IPP Printer attributes. + #ifndef PRINTING_BACKEND_CUPS_IPP_UTIL_H_ #define PRINTING_BACKEND_CUPS_IPP_UTIL_H_
diff --git a/printing/backend/cups_jobs.cc b/printing/backend/cups_jobs.cc new file mode 100644 index 0000000..8d8640e --- /dev/null +++ b/printing/backend/cups_jobs.cc
@@ -0,0 +1,396 @@ +// Copyright 2017 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 "printing/backend/cups_jobs.h" + +#include <cups/ipp.h> + +#include <array> +#include <map> +#include <memory> + +#include "base/logging.h" +#include "base/strings/string_piece.h" +#include "base/strings/stringprintf.h" + +namespace printing { +namespace { + +using PReason = PrinterStatus::PrinterReason::Reason; +using PSeverity = PrinterStatus::PrinterReason::Severity; + +// printer attributes +const char kPrinterUri[] = "printer-uri"; +const char kPrinterState[] = "printer-state"; +const char kPrinterStateReasons[] = "printer-state-reasons"; +const char kPrinterStateMessage[] = "printer-state-message"; + +// job attributes +const char kJobUri[] = "job-uri"; +const char kJobId[] = "job-id"; +const char kJobState[] = "job-state"; +const char kJobStateReasons[] = "job-state-reasons"; +const char kJobStateMessage[] = "job-state-message"; +const char kJobImpressionsCompleted[] = "job-impressions-completed"; +const char kTimeAtProcessing[] = "time-at-processing"; + +// request parameters +const char kRequestedAttributes[] = "requested-attributes"; +const char kWhichJobs[] = "which-jobs"; +const char kLimit[] = "limit"; + +// request values +const char kCompleted[] = "completed"; +const char kNotCompleted[] = "not-completed"; + +// printer state severities +const char kSeverityReport[] = "report"; +const char kSeverityWarn[] = "warning"; +const char kSeverityError[] = "error"; + +// printer state reason values +const char kNone[] = "none"; +const char kMediaNeeded[] = "media-needed"; +const char kMediaJam[] = "media-jam"; +const char kMovingToPaused[] = "moving-to-paused"; +const char kPaused[] = "paused"; +const char kShutdown[] = "shutdown"; +const char kConnectingToDevice[] = "connecting-to-device"; +const char kTimedOut[] = "timed-out"; +const char kStopping[] = "stopping"; +const char kStoppedPartly[] = "stopped-partly"; +const char kTonerLow[] = "toner-low"; +const char kTonerEmpty[] = "toner-empty"; +const char kSpoolAreaFull[] = "spool-area-full"; +const char kCoverOpen[] = "cover-open"; +const char kInterlockOpen[] = "interlock-open"; +const char kDoorOpen[] = "door-open"; +const char kInputTrayMissing[] = "input-tray-missing"; +const char kMediaLow[] = "media-low"; +const char kMediaEmpty[] = "media-empty"; +const char kOutputTrayMissing[] = "output-tray-missing"; +const char kOutputAreaAlmostFull[] = "output-area-almost-full"; +const char kOutputAreaFull[] = "output-area-full"; +const char kMarkerSupplyLow[] = "marker-supply-low"; +const char kMarkerSupplyEmpty[] = "marker-supply-empty"; +const char kMarkerWasteAlmostFull[] = "marker-waste-almost-full"; +const char kMarkerWasteFull[] = "marker-waste-full"; +const char kFuserOverTemp[] = "fuser-over-temp"; +const char kFuserUnderTemp[] = "fuser-under-temp"; +const char kOpcNearEol[] = "opc-near-eol"; +const char kOpcLifeOver[] = "opc-life-over"; +const char kDeveloperLow[] = "developer-low"; +const char kDeveloperEmpty[] = "developer-empty"; +const char kInterpreterResourceUnavailable[] = + "interpreter-resource-unavailable"; + +constexpr std::array<const char* const, 3> kPrinterAttributes = { + kPrinterState, kPrinterStateReasons, kPrinterStateMessage}; + +std::unique_ptr<ipp_t, void (*)(ipp_t*)> WrapIpp(ipp_t* ipp) { + return std::unique_ptr<ipp_t, void (*)(ipp_t*)>(ipp, &ippDelete); +} + +// Converts an IPP attribute |attr| to the appropriate JobState enum. +CupsJob::JobState ToJobState(ipp_attribute_t* attr) { + DCHECK_EQ(IPP_TAG_ENUM, ippGetValueTag(attr)); + int state = ippGetInteger(attr, 0); + switch (state) { + case IPP_JOB_ABORTED: + return CupsJob::ABORTED; + case IPP_JOB_CANCELLED: + return CupsJob::CANCELED; + case IPP_JOB_COMPLETED: + return CupsJob::COMPLETED; + case IPP_JOB_HELD: + return CupsJob::HELD; + case IPP_JOB_PENDING: + return CupsJob::PENDING; + case IPP_JOB_PROCESSING: + return CupsJob::PROCESSING; + case IPP_JOB_STOPPED: + return CupsJob::STOPPED; + default: + NOTREACHED() << "Unidentifed state " << state; + break; + } + + return CupsJob::UNKNOWN; +} + +// Returns a lookup map from strings to PrinterReason::Reason. +const std::map<base::StringPiece, PReason>& GetLabelToReason() { + static const std::map<base::StringPiece, PReason> kLabelToReason = + std::map<base::StringPiece, PReason>{ + {kNone, PReason::NONE}, + {kMediaNeeded, PReason::MEDIA_NEEDED}, + {kMediaJam, PReason::MEDIA_JAM}, + {kMovingToPaused, PReason::MOVING_TO_PAUSED}, + {kPaused, PReason::PAUSED}, + {kShutdown, PReason::SHUTDOWN}, + {kConnectingToDevice, PReason::CONNECTING_TO_DEVICE}, + {kTimedOut, PReason::TIMED_OUT}, + {kStopping, PReason::STOPPING}, + {kStoppedPartly, PReason::STOPPED_PARTLY}, + {kTonerLow, PReason::TONER_LOW}, + {kTonerEmpty, PReason::TONER_EMPTY}, + {kSpoolAreaFull, PReason::SPOOL_AREA_FULL}, + {kCoverOpen, PReason::COVER_OPEN}, + {kInterlockOpen, PReason::INTERLOCK_OPEN}, + {kDoorOpen, PReason::DOOR_OPEN}, + {kInputTrayMissing, PReason::INPUT_TRAY_MISSING}, + {kMediaLow, PReason::MEDIA_LOW}, + {kMediaEmpty, PReason::MEDIA_EMPTY}, + {kOutputTrayMissing, PReason::OUTPUT_TRAY_MISSING}, + {kOutputAreaAlmostFull, PReason::OUTPUT_AREA_ALMOST_FULL}, + {kOutputAreaFull, PReason::OUTPUT_AREA_FULL}, + {kMarkerSupplyLow, PReason::MARKER_SUPPLY_LOW}, + {kMarkerSupplyEmpty, PReason::MARKER_SUPPLY_EMPTY}, + {kMarkerWasteAlmostFull, PReason::MARKER_WASTE_ALMOST_FULL}, + {kMarkerWasteFull, PReason::MARKER_WASTE_FULL}, + {kFuserOverTemp, PReason::FUSER_OVER_TEMP}, + {kFuserUnderTemp, PReason::FUSER_UNDER_TEMP}, + {kOpcNearEol, PReason::OPC_NEAR_EOL}, + {kOpcLifeOver, PReason::OPC_LIFE_OVER}, + {kDeveloperLow, PReason::DEVELOPER_LOW}, + {kDeveloperEmpty, PReason::DEVELOPER_EMPTY}, + {kInterpreterResourceUnavailable, + PReason::INTERPRETER_RESOURCE_UNAVAILABLE}, + }; + return kLabelToReason; +} + +// Returns the Reason cooresponding to the string |reason|. Returns +// UNKOWN_REASON if the string is not recognized. +PrinterStatus::PrinterReason::Reason ToReason(base::StringPiece reason) { + const auto& enum_map = GetLabelToReason(); + const auto& entry = enum_map.find(reason); + return entry != enum_map.end() ? entry->second : PReason::UNKNOWN_REASON; +} + +// Returns the Severity cooresponding to |severity|. Returns UNKNOWN_SEVERITY +// if the strin gis not recognized. +PSeverity ToSeverity(base::StringPiece severity) { + if (severity == kSeverityError) + return PSeverity::ERROR; + + if (severity == kSeverityWarn) + return PSeverity::WARNING; + + if (severity == kSeverityReport) + return PSeverity::REPORT; + + return PSeverity::UNKNOWN_SEVERITY; +} + +// Parses the |reason| string into a PrinterReason. Splits the string based on +// the last '-' to determine severity. If a recognized severity is not +// included, severity is assumed to be ERROR per RFC2911. +PrinterStatus::PrinterReason ToPrinterReason(base::StringPiece reason) { + PrinterStatus::PrinterReason parsed; + + if (reason == kNone) { + parsed.reason = PReason::NONE; + parsed.severity = PSeverity::UNKNOWN_SEVERITY; + return parsed; + } + + size_t last_dash = reason.rfind('-'); + auto severity = PSeverity::UNKNOWN_SEVERITY; + if (last_dash != base::StringPiece::npos) { + // try to parse the last part of the string as the severity. + severity = ToSeverity(reason.substr(last_dash + 1)); + } + + if (severity == PSeverity::UNKNOWN_SEVERITY) { + // Severity is unknown. No severity in the reason. + // Per spec, if there is no severity, severity is error. + parsed.severity = PSeverity::ERROR; + parsed.reason = ToReason(reason); + } else { + parsed.severity = severity; + // reason is the beginning of the string + parsed.reason = ToReason(reason.substr(0, last_dash)); + } + + return parsed; +} + +// Populates |collection| with the collection of strings in |attr|. +void ParseCollection(ipp_attribute_t* attr, + std::vector<std::string>* collection) { + int count = ippGetCount(attr); + for (int i = 0; i < count; i++) { + base::StringPiece value = ippGetString(attr, i, nullptr); + collection->push_back(value.as_string()); + } +} + +// Parse a field for the CupsJob |job| from IPP attribute |attr| using the +// attribute name |name|. +void ParseField(ipp_attribute_t* attr, base::StringPiece name, CupsJob* job) { + DCHECK(!name.empty()); + if (name == kJobId) { + job->id = ippGetInteger(attr, 0); + } else if (name == kJobImpressionsCompleted) { + job->current_pages = ippGetInteger(attr, 0); + } else if (name == kJobState) { + job->state = ToJobState(attr); + } else if (name == kJobStateReasons) { + ParseCollection(attr, &(job->state_reasons)); + } else if (name == kJobStateMessage) { + job->state_message = ippGetString(attr, 0, nullptr); + } else if (name == kTimeAtProcessing) { + job->processing_started = ippGetInteger(attr, 0); + } +} + +// Returns a new CupsJob allocated in |jobs| with |printer_id| populated. +CupsJob* NewJob(const std::string& printer_id, std::vector<CupsJob>* jobs) { + jobs->emplace_back(); + CupsJob* job = &jobs->back(); + job->printer_id = printer_id; + return job; +} + +void ParseJobs(ipp_t* response, + const std::string& printer_id, + ipp_attribute_t* starting_attr, + std::vector<CupsJob>* jobs) { + // We know this is a non-empty job section. Start parsing fields for at least + // one job. + CupsJob* current_job = NewJob(printer_id, jobs); + for (ipp_attribute_t* attr = starting_attr; attr != nullptr; + attr = ippNextAttribute(response)) { + base::StringPiece attribute_name = ippGetName(attr); + // Separators indicate a new job. Separators have empty names. + if (attribute_name.empty()) { + current_job = NewJob(printer_id, jobs); + continue; + } + + // Continue to populate the job fileds. + ParseField(attr, attribute_name, current_job); + } +} + +// Returns the uri for printer with |id| as served by CUPS. Assumes that |id| +// is a valid CUPS printer name and performs no error checking or escaping. +std::string PrinterUriFromName(const std::string& id) { + return base::StringPrintf("ipp://localhost/printers/%s", id.c_str()); +} + +} // namespace + +void ParseJobsResponse(ipp_t* response, + const std::string& printer_id, + std::vector<CupsJob>* jobs) { + // Advance the position in the response to the jobs section. + ipp_attribute_t* attr = ippFirstAttribute(response); + while (attr != nullptr && ippGetGroupTag(attr) != IPP_TAG_JOB) { + attr = ippNextAttribute(response); + } + + if (attr != nullptr) { + ParseJobs(response, printer_id, attr, jobs); + } +} + +void ParsePrinterStatus(ipp_t* response, PrinterStatus* printer_status) { + for (ipp_attribute_t* attr = ippFirstAttribute(response); attr != nullptr; + attr = ippNextAttribute(response)) { + base::StringPiece name = ippGetName(attr); + if (name.empty()) { + continue; + } + + if (name == kPrinterState) { + DCHECK_EQ(IPP_TAG_ENUM, ippGetValueTag(attr)); + printer_status->state = static_cast<ipp_pstate_t>(ippGetInteger(attr, 0)); + } else if (name == kPrinterStateReasons) { + std::vector<std::string> reason_strings; + ParseCollection(attr, &reason_strings); + for (const std::string& reason : reason_strings) { + printer_status->reasons.push_back(ToPrinterReason(reason)); + } + } else if (name == kPrinterStateMessage) { + printer_status->message = ippGetString(attr, 0, nullptr); + } + } +} + +bool GetPrinterStatus(http_t* http, + const std::string& printer_id, + PrinterStatus* printer_status) { + DCHECK(http); + + auto request = WrapIpp(ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES)); + + const std::string printer_uri = PrinterUriFromName(printer_id); + ippAddString(request.get(), IPP_TAG_OPERATION, IPP_TAG_URI, kPrinterUri, + nullptr, printer_uri.data()); + + ippAddStrings(request.get(), IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + kRequestedAttributes, kPrinterAttributes.size(), nullptr, + kPrinterAttributes.data()); + + auto response = + WrapIpp(cupsDoRequest(http, request.release(), printer_uri.c_str())); + + if (ippGetStatusCode(response.get()) != IPP_STATUS_OK) + return false; + + ParsePrinterStatus(response.get(), printer_status); + + return true; +} + +bool GetCupsJobs(http_t* http, + const std::string& printer_id, + int limit, + JobCompletionState which, + std::vector<CupsJob>* jobs) { + DCHECK(http); + + auto request = WrapIpp(ippNewRequest(IPP_OP_GET_JOBS)); + const std::string printer_uri = PrinterUriFromName(printer_id); + ippAddString(request.get(), IPP_TAG_OPERATION, IPP_TAG_URI, kPrinterUri, + nullptr, printer_uri.data()); + ippAddInteger(request.get(), IPP_TAG_OPERATION, IPP_TAG_INTEGER, kLimit, + limit); + + std::vector<const char*> job_attributes = { + kJobUri, kJobId, kJobState, + kJobStateReasons, kJobStateMessage, kJobImpressionsCompleted, + kTimeAtProcessing}; + + ippAddStrings(request.get(), IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + kRequestedAttributes, job_attributes.size(), nullptr, + job_attributes.data()); + + ippAddString(request.get(), IPP_TAG_OPERATION, IPP_TAG_KEYWORD, kWhichJobs, + nullptr, which == COMPLETED ? kCompleted : kNotCompleted); + + if (ippValidateAttributes(request.get()) != 1) { + LOG(WARNING) << "Could not validate ipp request: " << cupsLastErrorString(); + return false; + } + + // cupsDoRequest will delete the request. + auto response = + WrapIpp(cupsDoRequest(http, request.release(), printer_uri.c_str())); + + ipp_status_t status = ippGetStatusCode(response.get()); + + if (status != IPP_OK) { + LOG(WARNING) << "IPP Error: " << cupsLastErrorString(); + return false; + } + + ParseJobsResponse(response.get(), printer_id, jobs); + + return true; +} + +} // namespace printing
diff --git a/printing/backend/cups_jobs.h b/printing/backend/cups_jobs.h new file mode 100644 index 0000000..12c2d51 --- /dev/null +++ b/printing/backend/cups_jobs.h
@@ -0,0 +1,139 @@ +// Copyright 2017 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. + +// Implementations of IPP requests for printer queue information. + +#ifndef PRINTING_BACKEND_CUPS_JOBS_H_ +#define PRINTING_BACKEND_CUPS_JOBS_H_ + +#include <cups/cups.h> + +#include <string> +#include <vector> + +#include "printing/printing_export.h" + +namespace printing { + +// Represents a print job sent to the queue. +struct PRINTING_EXPORT CupsJob { + // Corresponds to job-state from RFC2911. + enum JobState { + UNKNOWN, + PENDING, // waiting to be processed + HELD, // the job has not begun printing and will not without intervention + COMPLETED, + PROCESSING, // job is being sent to the printer/printed + STOPPED, // job was being processed and has now stopped + CANCELED, // either the spooler or a user canclled the job + ABORTED // an error occurred causing the printer to give up + }; + + // job id + int id = -1; + // printer name in CUPS + std::string printer_id; + JobState state = UNKNOWN; + // the last page printed + int current_pages = -1; + // detail for the job state + std::vector<std::string> state_reasons; + // human readable message explaining the state + std::string state_message; + // most recent timestamp where the job entered PROCESSING + int processing_started = 0; +}; + +// Represents the status of a printer containing the properties printer-state, +// printer-state-reasons, and printer-state-message. +struct PrinterStatus { + struct PrinterReason { + // Standardized reasons from RFC2911. + enum Reason { + UNKNOWN_REASON, + NONE, + MEDIA_NEEDED, + MEDIA_JAM, + MOVING_TO_PAUSED, + PAUSED, + SHUTDOWN, + CONNECTING_TO_DEVICE, + TIMED_OUT, + STOPPING, + STOPPED_PARTLY, + TONER_LOW, + TONER_EMPTY, + SPOOL_AREA_FULL, + COVER_OPEN, + INTERLOCK_OPEN, + DOOR_OPEN, + INPUT_TRAY_MISSING, + MEDIA_LOW, + MEDIA_EMPTY, + OUTPUT_TRAY_MISSING, + OUTPUT_AREA_ALMOST_FULL, + OUTPUT_AREA_FULL, + MARKER_SUPPLY_LOW, + MARKER_SUPPLY_EMPTY, + MARKER_WASTE_ALMOST_FULL, + MARKER_WASTE_FULL, + FUSER_OVER_TEMP, + FUSER_UNDER_TEMP, + OPC_NEAR_EOL, + OPC_LIFE_OVER, + DEVELOPER_LOW, + DEVELOPER_EMPTY, + INTERPRETER_RESOURCE_UNAVAILABLE + }; + + // Severity of the state-reason. + enum Severity { UNKNOWN_SEVERITY, REPORT, WARNING, ERROR }; + + Reason reason; + Severity severity; + }; + + // printer-state + ipp_pstate_t state; + // printer-state-reasons + std::vector<PrinterReason> reasons; + // printer-state-message + std::string message; +}; + +// Specifies classes of jobs. +enum JobCompletionState { + COMPLETED, // only completed jobs + PROCESSING // only jobs that are being processed +}; + +// Extracts structured job information from the |response| for |printer_id|. +// Extracted jobs are added to |jobs|. +void ParseJobsResponse(ipp_t* response, + const std::string& printer_id, + std::vector<CupsJob>* jobs); + +// Attempts to extract a PrinterStatus object out of |response|. +void ParsePrinterStatus(ipp_t* response, PrinterStatus* printer_status); + +// Attempts to retrieve printer status using connection |http| for |printer_id|. +// Returns true if succcssful and updates the fields in |printer_status| as +// appropriate. Returns false if the request failed. +bool GetPrinterStatus(http_t* http, + const std::string& printer_id, + PrinterStatus* printer_status); + +// Attempts to retrieve job information using connection |http| for the printer +// named |printer_id|. Retrieves at most |limit| jobs. If |completed| then +// completed jobs are retrieved. Otherwise, jobs that are currently in progress +// are retrieved. Results are added to |jobs| if the operation was successful. +bool GetCupsJobs(http_t* http, + const std::string& printer_id, + int limit, + JobCompletionState completed, + std::vector<CupsJob>* jobs); + +} // namespace printing + +#endif // PRINTING_BACKEND_CUPS_JOBS_H_
diff --git a/rlz/OWNERS b/rlz/OWNERS index a66406d..66f24eb 100644 --- a/rlz/OWNERS +++ b/rlz/OWNERS
@@ -1,2 +1,4 @@ rogerta@chromium.org thakis@chromium.org + +# COMPONENT: Internals>Core
diff --git a/services/ui/ws/drag_controller.cc b/services/ui/ws/drag_controller.cc index 714b37a..eec033c2 100644 --- a/services/ui/ws/drag_controller.cc +++ b/services/ui/ws/drag_controller.cc
@@ -75,6 +75,8 @@ bool DragController::DispatchPointerEvent(const ui::PointerEvent& event, ServerWindow* current_target) { + DVLOG(2) << "DragController dispatching pointer event at " + << event.location().ToString(); uint32_t event_flags = event.flags() & (ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN); @@ -83,11 +85,15 @@ if (waiting_for_final_drop_response_) { // If we're waiting on a target window to respond to the final drag drop // call, don't process any more pointer events. + DVLOG(1) << "Ignoring event because we're waiting for final drop response"; return false; } - if (event.pointer_details().id != drag_pointer_id_) + if (event.pointer_details().id != drag_pointer_id_) { + DVLOG(1) << "Ignoring event from different pointer " + << event.pointer_details().id; return false; + } // If |current_target| doesn't accept drags, walk its hierarchy up until we // find one that does (or set to nullptr at the top of the tree). @@ -119,6 +125,10 @@ } SetCurrentTargetWindow(current_target); + } else if (event.type() != ET_POINTER_UP) { + DVLOG(1) << "Performing no action for pointer event at " + << screen_position.ToString() + << "! current_target=" << current_target; } if (event.type() == ET_POINTER_UP) { @@ -143,6 +153,8 @@ void DragController::MessageDragCompleted(bool success, DropEffect action_taken) { + DVLOG(1) << "Drag Completed: success=" << success + << ", action_taken=" << action_taken; for (DragTargetConnection* connection : called_on_drag_mime_types_) connection->PerformOnDragDropDone(); called_on_drag_mime_types_.clear(); @@ -212,6 +224,8 @@ OperationType type, uint32_t event_flags, const gfx::Point& screen_position) { + DVLOG(2) << "Queueing operation " << ToString(type) << " to " << window; + // If this window doesn't have the mime data, send it. DragTargetConnection* connection = source_->GetDragTargetForWindow(window); if (connection != source_connection_ && @@ -329,5 +343,23 @@ } } +// static +std::string DragController::ToString(OperationType type) { + switch (type) { + case OperationType::NONE: + return "NONE"; + case OperationType::ENTER: + return "ENTER"; + case OperationType::OVER: + return "OVER"; + case OperationType::LEAVE: + return "LEAVE"; + case OperationType::DROP: + return "DROP"; + } + NOTREACHED(); + return std::string(); +} + } // namespace ws } // namespace ui
diff --git a/services/ui/ws/drag_controller.h b/services/ui/ws/drag_controller.h index cb40282..edbc11a 100644 --- a/services/ui/ws/drag_controller.h +++ b/services/ui/ws/drag_controller.h
@@ -111,6 +111,8 @@ // ServerWindowObserver: void OnWindowDestroying(ServerWindow* window) override; + static std::string ToString(OperationType type); + // Our owner. DragSource* source_;
diff --git a/services/ui/ws/window_tree.cc b/services/ui/ws/window_tree.cc index 9dedaed..8602975 100644 --- a/services/ui/ws/window_tree.cc +++ b/services/ui/ws/window_tree.cc
@@ -1765,7 +1765,8 @@ // We need to fail this move loop change, otherwise the client will just be // waiting for |change_id|. DVLOG(1) << "PerformDragDrop failed (access denied)."; - OnChangeCompleted(change_id, false); + client()->OnPerformDragDropCompleted(change_id, false, + mojom::kDropEffectNone); return; } @@ -1773,7 +1774,8 @@ if (!display_root) { // The window isn't parented. There's nothing to do. DVLOG(1) << "PerformDragDrop failed (window unparented)."; - OnChangeCompleted(change_id, false); + client()->OnPerformDragDropCompleted(change_id, false, + mojom::kDropEffectNone); return; } @@ -1781,7 +1783,8 @@ // Either the window manager is servicing a window drag or we're servicing // a drag and drop operation. We can't start a second drag. DVLOG(1) << "PerformDragDrop failed (already performing a drag)."; - OnChangeCompleted(change_id, false); + client()->OnPerformDragDropCompleted(change_id, false, + mojom::kDropEffectNone); return; }
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index f90ea4c4..2e1e08b 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -2482,6 +2482,175 @@ } ] }, + "Cast Audio Linux": { + "gtest_tests": [ + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "base_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "cacheinvalidation_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "capture_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "cast_alsa_cma_backend_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "cast_base_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "cast_crash_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "cast_media_unittests" + }, + { + "args": [ + "--enable-local-file-accesses", + "--ozone-platform=cast", + "--no-sandbox", + "--test-launcher-jobs=1" + ], + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "cast_shell_browsertests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "cast_shell_unittests" + }, + { + "args": [ + "--test-launcher-filter-file=src/testing/buildbot/filters/cast-linux.content_browsertests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "content_browsertests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "content_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "crypto_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "gpu_ipc_service_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "gpu_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "ipc_tests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "jingle_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "media_blink_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "media_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "midi_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "net_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "ppapi_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "sandbox_linux_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "sql_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "storage_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "ui_base_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "url_unittests" + } + ] + }, "Cast Linux": { "gtest_tests": [ {
diff --git a/testing/buildbot/chromium.swarm.json b/testing/buildbot/chromium.swarm.json new file mode 100644 index 0000000..70f448cd --- /dev/null +++ b/testing/buildbot/chromium.swarm.json
@@ -0,0 +1,345 @@ +{ + "Android N5 Swarm": { + "gtest_tests": [ + { + "override_compile_targets": [ + "android_webview_test_apk" + ], + "override_isolate_target": "android_webview_test_apk", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "KTU84P", + "device_type": "hammerhead" + } + ] + }, + "test": "android_webview_test_apk" + }, + { + "override_isolate_target": "base_unittests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "KTU84P", + "device_type": "hammerhead" + } + ] + }, + "test": "base_unittests" + }, + { + "override_compile_targets": [ + "chrome_public_test_apk" + ], + "override_isolate_target": "chrome_public_test_apk", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "KTU84P", + "device_type": "hammerhead" + } + ] + }, + "test": "chrome_public_test_apk" + }, + { + "override_isolate_target": "content_browsertests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "KTU84P", + "device_type": "hammerhead" + } + ] + }, + "test": "content_browsertests" + }, + { + "override_isolate_target": "content_unittests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "KTU84P", + "device_type": "hammerhead" + } + ] + }, + "test": "content_unittests" + }, + { + "override_isolate_target": "net_unittests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "KTU84P", + "device_type": "hammerhead" + } + ] + }, + "test": "net_unittests" + }, + { + "override_isolate_target": "unit_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "KTU84P", + "device_type": "hammerhead" + } + ] + }, + "test": "unit_tests" + } + ] + }, + "Android N5X Swarm": { + "gtest_tests": [ + { + "override_compile_targets": [ + "android_webview_test_apk" + ], + "override_isolate_target": "android_webview_test_apk", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ] + }, + "test": "android_webview_test_apk" + }, + { + "override_isolate_target": "base_unittests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ] + }, + "test": "base_unittests" + }, + { + "override_compile_targets": [ + "chrome_public_test_apk" + ], + "override_isolate_target": "chrome_public_test_apk", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ] + }, + "test": "chrome_public_test_apk" + }, + { + "override_isolate_target": "content_browsertests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ] + }, + "test": "content_browsertests" + }, + { + "override_isolate_target": "content_unittests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ] + }, + "test": "content_unittests" + }, + { + "override_isolate_target": "net_unittests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ] + }, + "test": "net_unittests" + }, + { + "override_isolate_target": "unit_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ] + }, + "test": "unit_tests" + } + ] + }, + "Linux Swarm": { + "gtest_tests": [ + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "base_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "shards": 2 + }, + "test": "browser_tests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "content_browsertests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "content_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "interactive_ui_tests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "net_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "unit_tests" + } + ] + }, + "Mac Swarm": { + "gtest_tests": [ + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "base_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "shards": 2 + }, + "test": "browser_tests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "content_browsertests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "content_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "interactive_ui_tests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "net_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "unit_tests" + } + ] + }, + "Windows Swarm": { + "gtest_tests": [ + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "base_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "shards": 2 + }, + "test": "browser_tests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "content_browsertests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "content_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "interactive_ui_tests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "net_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "unit_tests" + } + ] + } +}
diff --git a/testing/buildbot/filters/mash.browser_tests.filter b/testing/buildbot/filters/mash.browser_tests.filter index d0e92b9..5916eae 100644 --- a/testing/buildbot/filters/mash.browser_tests.filter +++ b/testing/buildbot/filters/mash.browser_tests.filter
@@ -1 +1,2 @@ +BrowserTest.NoTitle BrowserTest.Title
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index fcf9ec73..9fe9789 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -132,29 +132,13 @@ ], "experiments": [ { - "name": "LastUsedDateAndExpDate_Experiment", + "name": "LastUsedDateAndExpDate_IncreaseDropdownItemHeight_Experiment", "params": { + "dropdown_item_height": "56", "show_expiration_date": "true" }, "enable_features": [ - "AutofillCreditCardLastUsedDateDisplay" - ] - } - ] - } - ], - "AutofillCreditCardPopup": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "IncreaseDropdownItemHeight", - "params": { - "dropdown_item_height": "56" - }, - "enable_features": [ + "AutofillCreditCardLastUsedDateDisplay", "AutofillCreditCardPopupLayout" ] }
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 index 05e1d0d..18a7e68 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -619,7 +619,6 @@ Bug(none) fast/forms/select/listbox-appearance-basic.html [ Failure ] Bug(none) fast/forms/select/menulist-appearance-basic.html [ Failure ] Bug(none) fast/forms/select/menulist-appearance-rtl.html [ Failure ] -Bug(none) fast/forms/select-popup/popup-menu-appearance-zoom110.html [ Crash ] Bug(none) fast/forms/text/input-appearance-selection.html [ Failure ] Bug(none) fast/forms/text/input-readonly-autoscroll.html [ Failure ] Bug(none) fast/forms/text/input-table.html [ Failure ] @@ -1651,3 +1650,18 @@ Bug(none) virtual/threaded/compositing/visibility/visibility-simple-video-layer.html [ Failure ] Bug(none) virtual/threaded/compositing/webgl/webgl-reflection.html [ Failure ] Bug(none) virtual/threaded/printing/ [ Skip ] + +Bug(700530) fast/css/background-clip-values.html [ Failure ] +Bug(700530) fast/borders/outline-negative-start.html [ Failure ] +Bug(700530) svg/text/small-fonts-in-html5.html [ Failure ] +Bug(700530) compositing/overflow/paint-neg-z-order-descendants-into-scrolling-contents-layer.html [ Failure ] +Bug(700530) fast/multicol/tall-content-in-inner-with-fixed-height.html [ Failure ] +Bug(700530) svg/custom/pattern-rotate.svg [ Failure ] +Bug(700530) fast/forms/date/date-appearance-basic.html [ Failure ] +Bug(700530) fast/forms/text/input-placeholder-paint-order.html [ Failure ] +Bug(700530) fast/forms/select-popup/popup-menu-appearance-zoom110.html [ Crash Failure ] +Bug(700530) svg/W3C-SVG-1.1/animate-elem-05-t.svg [ Failure ] +Bug(700530) svg/custom/use-referencing-nonexisting-symbol.svg [ Failure ] +Bug(700530) svg/custom/invalid-css.svg [ Failure ] +Bug(700530) fast/forms/textarea/textarea-placeholder-paint-order.html [ Failure ] +Bug(700530) fast/box-shadow/box-shadow-clipped-slices.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index e158a280..98a0246 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1,5 +1,5 @@ # Intentional failures to test the layout test system. -Bug(intentional) [ Android Linux Win Mac10.10 Mac10.11 Retina ] harness-tests/crash.html [ Crash ] +Bug(intentional) [ Android Linux Win Mac10.10 Mac10.11 Retina Mac10.12 ] harness-tests/crash.html [ Crash ] crbug.com/644303 [ Mac10.9 ] harness-tests/crash.html [ Crash Timeout ] Bug(intentional) harness-tests/timeout.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/editing/pasteboard/onpaste-text-html-types.html b/third_party/WebKit/LayoutTests/editing/pasteboard/onpaste-text-html-types.html index 8dd357f..3b74ce48 100644 --- a/third_party/WebKit/LayoutTests/editing/pasteboard/onpaste-text-html-types.html +++ b/third_party/WebKit/LayoutTests/editing/pasteboard/onpaste-text-html-types.html
@@ -1,5 +1,4 @@ -<body onpaste="paste(event)"> -<div id="test">This test verifies that we can get types from the clipboard +<div id="test" onpaste="paste(event)">This test verifies that we can get types from the clipboard during an onpaste event. This test requires DRT.</div> <div id="results">FAIL</div> @@ -25,4 +24,3 @@ runDumpAsTextEditingTest(false); </script> -</body>
diff --git a/third_party/WebKit/Source/core/editing/BUILD.gn b/third_party/WebKit/Source/core/editing/BUILD.gn index 2f7d82e..417c089 100644 --- a/third_party/WebKit/Source/core/editing/BUILD.gn +++ b/third_party/WebKit/Source/core/editing/BUILD.gn
@@ -226,7 +226,6 @@ source_set("unit_tests") { testonly = true sources = [ - "ClipboardEventFlowTest.cpp", "CompositionUnderlineTest.cpp", "EditingCommandTest.cpp", "EditingStrategyTest.cpp",
diff --git a/third_party/WebKit/Source/core/editing/ClipboardEventFlowTest.cpp b/third_party/WebKit/Source/core/editing/ClipboardEventFlowTest.cpp deleted file mode 100644 index c04a974..0000000 --- a/third_party/WebKit/Source/core/editing/ClipboardEventFlowTest.cpp +++ /dev/null
@@ -1,149 +0,0 @@ -// Copyright 2017 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 "core/dom/Document.h" -#include "core/editing/EditingTestBase.h" -#include "core/editing/FrameSelection.h" -#include "core/editing/Position.h" -#include "core/editing/SelectionTemplate.h" -#include "core/events/EventListener.h" -#include "core/frame/LocalFrame.h" -#include "core/frame/Settings.h" -#include "core/html/HTMLBodyElement.h" -#include "core/html/HTMLButtonElement.h" -#include "core/html/HTMLDivElement.h" -#include "core/html/HTMLHtmlElement.h" -#include "core/layout/LayoutObject.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace blink { - -namespace { -class MockEventListener : public EventListener { - public: - MockEventListener() : EventListener(EventListener::CPPEventListenerType) {} - - bool operator==(const EventListener& other) const final { - return this == &other; - } - - MOCK_METHOD2(handleEvent, void(ExecutionContext*, Event*)); -}; -} // namespace - -class ClipboardEventFlowTest : public EditingTestBase { - private: - void makeDocumentEmpty() { - while (document().firstChild()) - document().removeChild(document().firstChild()); - } - - void setElementText(Element& element, const std::string& text) { - element.setInnerHTML(String::fromUTF8(text.c_str()), ASSERT_NO_EXCEPTION); - updateAllLifecyclePhases(); - } - - void setElementTextAndSelectIt(Element& element, - const std::string& text, - bool selectionEditable) { - setElementText(element, text); - - frame().selection().setSelection( - SelectionInDOMTree::Builder() - .collapse(Position(element.firstChild(), 0)) - .extend(Position(element.firstChild(), text.size())) - .build()); - - element.setAttribute(HTMLNames::contenteditableAttr, - selectionEditable ? "true" : "false"); - } - - protected: - void clipboardEventTargetDependsOnSelectionEditabilityTest( - const char* command, - bool selectionEditable) { - using testing::_; - - auto* html = HTMLHtmlElement::create(document()); - auto* body = HTMLBodyElement::create(document()); - auto* focusableElement = HTMLButtonElement::create(document()); - auto* elementWithSelection = HTMLDivElement::create(document()); - - auto* eventListenerInstalledOnFocusedElement = new MockEventListener; - auto* eventListenerInstalledOnElementWithSelection = new MockEventListener; - - focusableElement->addEventListener(command, - eventListenerInstalledOnFocusedElement); - elementWithSelection->addEventListener( - command, eventListenerInstalledOnElementWithSelection); - - makeDocumentEmpty(); - document().setDesignMode("on"); - - body->appendChild(focusableElement); - body->appendChild(elementWithSelection); - html->appendChild(body); - document().appendChild(html); - - focusableElement->focus(); - - setElementTextAndSelectIt(*elementWithSelection, "some dummy text", - selectionEditable); - - // allow |document.execCommand| to access clipboard - frame().settings()->setJavaScriptCanAccessClipboard(true); - - // test expectations - EXPECT_CALL(*eventListenerInstalledOnFocusedElement, handleEvent(_, _)) - .Times(selectionEditable ? 0 : 1); - - EXPECT_CALL(*eventListenerInstalledOnElementWithSelection, - handleEvent(_, _)) - .Times(selectionEditable ? 1 : 0); - - // execute command - NonThrowableExceptionState exceptionState; - document().execCommand(command, false, "", exceptionState); - } -}; - -TEST_F(ClipboardEventFlowTest, - copySetsClipboardEventTargetToActiveElementWhenSelectionIsNotEditable) { - clipboardEventTargetDependsOnSelectionEditabilityTest("copy", false); -} - -TEST_F( - ClipboardEventFlowTest, - copySetsClipboardEventTargetToElementWithSelectionWhenSelectionIsEditable) { - clipboardEventTargetDependsOnSelectionEditabilityTest("copy", true); -} - -TEST_F(ClipboardEventFlowTest, - cutSetsClipboardEventTargetToActiveElementWhenSelectionIsNotEditable) { - clipboardEventTargetDependsOnSelectionEditabilityTest("cut", false); -} - -TEST_F( - ClipboardEventFlowTest, - cutSetsClipboardEventTargetToElementWithSelectionWhenSelectionIsEditable) { - clipboardEventTargetDependsOnSelectionEditabilityTest("cut", true); -} - -TEST_F(ClipboardEventFlowTest, - pasteSetsClipboardEventTargetToActiveElementWhenSelectionIsNotEditable) { - // allow |document.execCommand| to execute 'paste' command - frame().settings()->setDOMPasteAllowed(true); - - clipboardEventTargetDependsOnSelectionEditabilityTest("paste", false); -} - -TEST_F( - ClipboardEventFlowTest, - pasteSetsClipboardEventTargetToElementWithSelectionWhenSelectionIsEditable) { - // allow |document.execCommand| to execute 'paste' - frame().settings()->setDOMPasteAllowed(true); - - clipboardEventTargetDependsOnSelectionEditabilityTest("paste", true); -} -} // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/Editor.cpp b/third_party/WebKit/Source/core/editing/Editor.cpp index e4e310ba..5bfbf7d 100644 --- a/third_party/WebKit/Source/core/editing/Editor.cpp +++ b/third_party/WebKit/Source/core/editing/Editor.cpp
@@ -772,9 +772,7 @@ } Element* Editor::findEventTargetFrom(const VisibleSelection& selection) const { - Element* target = selection.hasEditableStyle() - ? associatedElementOf(selection.start()) - : frame().document()->activeElement(); + Element* target = associatedElementOf(selection.start()); if (!target) target = frame().document()->body();
diff --git a/third_party/WebKit/Source/core/editing/EphemeralRangeTest.cpp b/third_party/WebKit/Source/core/editing/EphemeralRangeTest.cpp index 4e84da53..85a6ae2 100644 --- a/third_party/WebKit/Source/core/editing/EphemeralRangeTest.cpp +++ b/third_party/WebKit/Source/core/editing/EphemeralRangeTest.cpp
@@ -51,20 +51,25 @@ // Tests that |EphemeralRange::nodes()| will traverse the whole range exactly as // |for (Node* n = firstNode(); n != pastLastNode(); n = Traversal::next(*n))| // does. -TEST_F(EphemeralRangeTest, rangeTraversal) { +TEST_F(EphemeralRangeTest, rangeTraversalDOM) { const char* bodyContent = - "<p id='host'><b id='one'></b><b id='two'>22</b></p>"; + "<p id='host'>" + "<b id='zero'>0</b>" + "<b id='one'>1</b>" + "<b id='two'>22</b>" + "<span id='three'>333</span>" + "</p>"; setBodyContent(bodyContent); const std::string expectedNodes( - "[BODY][P id=\"host\"][B id=\"one\"][B id=\"two\"][#text \"22\"]"); + "[BODY][P id=\"host\"][B id=\"zero\"][#text \"0\"][B id=\"one\"][#text " + "\"1\"][B id=\"two\"][#text \"22\"][SPAN id=\"three\"][#text \"333\"]"); // Check two ways to traverse. EXPECT_EQ(expectedNodes, traverseRange<>(getBodyRange())); EXPECT_EQ(traverseRange<>(getBodyRange()), traverseRange(EphemeralRange(getBodyRange()))); - // The same with FlatTree traversing. EXPECT_EQ(expectedNodes, traverseRange<FlatTreeTraversal>(getBodyRange())); EXPECT_EQ(traverseRange<FlatTreeTraversal>(getBodyRange()), traverseRange(EphemeralRangeInFlatTree(getBodyRange()))); @@ -73,65 +78,96 @@ // Tests that |inRange| helper will traverse the whole range with shadow DOM. TEST_F(EphemeralRangeTest, rangeShadowTraversal) { const char* bodyContent = - "<p id='host'><b id='one'></b><input type='text' value='some'></p>"; + "<b id='zero'>0</b>" + "<p id='host'>" + "<b id='one'>1</b>" + "<b id='two'>22</b>" + "<b id='three'>333</b>" + "</p>" + "<b id='four'>4444</b>"; + const char* shadowContent = + "<p id='five'>55555</p>" + "<content select=#two></content>" + "<content select=#one></content>" + "<span id='six'>666666</span>" + "<p id='seven'>7777777</p>"; setBodyContent(bodyContent); + setShadowContent(shadowContent, "host"); - EXPECT_EQ("[BODY][P id=\"host\"][B id=\"one\"][INPUT]", - traverseRange<>(getBodyRange())); - EXPECT_EQ(traverseRange<>(getBodyRange()), - traverseRange(EphemeralRange(getBodyRange()))); + const std::string expectedNodes( + "[BODY][B id=\"zero\"][#text \"0\"][P id=\"host\"][P id=\"five\"][#text " + "\"55555\"][B id=\"two\"][#text \"22\"][B id=\"one\"][#text \"1\"][SPAN " + "id=\"six\"][#text \"666666\"][P id=\"seven\"][#text \"7777777\"][B " + "id=\"four\"][#text \"4444\"]"); - // In this case FlatTree traverse should differs from DOM tree traverse. - EXPECT_EQ( - "[BODY][P id=\"host\"][B id=\"one\"][INPUT][DIV id=\"inner-editor\" " - "(editable)][#text \"some\"]", - traverseRange<FlatTreeTraversal>(getBodyRange())); + EXPECT_EQ(expectedNodes, traverseRange<FlatTreeTraversal>(getBodyRange())); EXPECT_EQ(traverseRange<FlatTreeTraversal>(getBodyRange()), traverseRange(EphemeralRangeInFlatTree(getBodyRange()))); + // Node 'three' should not appear in FlatTreeTraversal. + EXPECT_EQ(expectedNodes.find("three") == std::string::npos, true); } // Limit a range and check that it will be traversed correctly. -TEST_F(EphemeralRangeTest, rangeTraversalLimited) { +TEST_F(EphemeralRangeTest, rangeTraversalLimitedDOM) { const char* bodyContent = - "<p id='host'><b id='one'></b><input type='text' value='some'><span " - "id='two'></p>"; + "<p id='host'>" + "<b id='zero'>0</b>" + "<b id='one'>1</b>" + "<b id='two'>22</b>" + "<span id='three'>333</span>" + "</p>"; setBodyContent(bodyContent); - // Get a limited range from <body> to <b> nodes. Range* untilB = getBodyRange(); untilB->setEnd(document().getElementById("one"), 0, IGNORE_EXCEPTION_FOR_TESTING); - EXPECT_EQ("[BODY][P id=\"host\"][B id=\"one\"]", traverseRange<>(untilB)); - + EXPECT_EQ("[BODY][P id=\"host\"][B id=\"zero\"][#text \"0\"][B id=\"one\"]", + traverseRange<>(untilB)); EXPECT_EQ(traverseRange<>(untilB), traverseRange(EphemeralRange(untilB))); - EXPECT_EQ("[BODY][P id=\"host\"][B id=\"one\"]", - traverseRange<FlatTreeTraversal>(untilB)); - EXPECT_EQ(traverseRange<FlatTreeTraversal>(untilB), - traverseRange(EphemeralRangeInFlatTree(untilB))); - - // Get a limited range from <b> to <span> nodes. Range* fromBToSpan = getBodyRange(); fromBToSpan->setStart(document().getElementById("one"), 0, IGNORE_EXCEPTION_FOR_TESTING); - fromBToSpan->setEnd(document().getElementById("two"), 0, + fromBToSpan->setEnd(document().getElementById("three"), 0, IGNORE_EXCEPTION_FOR_TESTING); - - EXPECT_EQ("[B id=\"one\"][INPUT][SPAN id=\"two\"]", + EXPECT_EQ("[#text \"1\"][B id=\"two\"][#text \"22\"][SPAN id=\"three\"]", traverseRange<>(fromBToSpan)); EXPECT_EQ(traverseRange<>(fromBToSpan), traverseRange(EphemeralRange(fromBToSpan))); +} - EXPECT_EQ( - "[B id=\"one\"][INPUT][DIV id=\"inner-editor\" (editable)][#text " - "\"some\"][SPAN id=\"two\"]", - traverseRange<FlatTreeTraversal>(fromBToSpan)); - EXPECT_EQ(traverseRange<FlatTreeTraversal>(fromBToSpan), - traverseRange(EphemeralRangeInFlatTree(fromBToSpan))); +TEST_F(EphemeralRangeTest, rangeTraversalLimitedFlatTree) { + const char* bodyContent = + "<b id='zero'>0</b>" + "<p id='host'>" + "<b id='one'>1</b>" + "<b id='two'>22</b>" + "</p>" + "<b id='three'>333</b>"; + const char* shadowContent = + "<p id='four'>4444</p>" + "<content select=#two></content>" + "<content select=#one></content>" + "<span id='five'>55555</span>" + "<p id='six'>666666</p>"; + setBodyContent(bodyContent); + ShadowRoot* shadowRoot = setShadowContent(shadowContent, "host"); + + const PositionInFlatTree startPosition(document().getElementById("one"), 0); + const PositionInFlatTree limitPosition(shadowRoot->getElementById("five"), 0); + const PositionInFlatTree endPosition(shadowRoot->getElementById("six"), 0); + const EphemeralRangeInFlatTree fromBToSpan(startPosition, limitPosition); + EXPECT_EQ("[#text \"1\"][SPAN id=\"five\"]", traverseRange(fromBToSpan)); + + const EphemeralRangeInFlatTree fromSpanToEnd(limitPosition, endPosition); + EXPECT_EQ("[#text \"55555\"][P id=\"six\"]", traverseRange(fromSpanToEnd)); } TEST_F(EphemeralRangeTest, traversalEmptyRanges) { - const char* bodyContent = "<p id='host'><b id='one'></b></p>"; + const char* bodyContent = + "<p id='host'>" + "<b id='one'>1</b>" + "</p>"; setBodyContent(bodyContent); // Expect no iterations in loop for an empty EphemeralRange.
diff --git a/third_party/WebKit/Source/core/html/HTMLButtonElement.h b/third_party/WebKit/Source/core/html/HTMLButtonElement.h index eea1848e..83576c4 100644 --- a/third_party/WebKit/Source/core/html/HTMLButtonElement.h +++ b/third_party/WebKit/Source/core/html/HTMLButtonElement.h
@@ -24,12 +24,11 @@ #ifndef HTMLButtonElement_h #define HTMLButtonElement_h -#include "core/CoreExport.h" #include "core/html/HTMLFormControlElement.h" namespace blink { -class CORE_EXPORT HTMLButtonElement final : public HTMLFormControlElement { +class HTMLButtonElement final : public HTMLFormControlElement { DEFINE_WRAPPERTYPEINFO(); public:
diff --git a/third_party/WebKit/Source/core/html/parser/PreloadRequest.cpp b/third_party/WebKit/Source/core/html/parser/PreloadRequest.cpp index aefdfa3..0d585a93 100644 --- a/third_party/WebKit/Source/core/html/parser/PreloadRequest.cpp +++ b/third_party/WebKit/Source/core/html/parser/PreloadRequest.cpp
@@ -41,8 +41,8 @@ ResourceRequest resourceRequest(url); resourceRequest.setHTTPReferrer(SecurityPolicy::generateReferrer( m_referrerPolicy, url, document->outgoingReferrer())); - ResourceFetcher::determineRequestContext(resourceRequest, m_resourceType, - false); + resourceRequest.setRequestContext( + ResourceFetcher::determineRequestContext(m_resourceType, false)); FetchRequest request(resourceRequest, initiatorInfo);
diff --git a/third_party/WebKit/Source/core/loader/LinkLoader.cpp b/third_party/WebKit/Source/core/loader/LinkLoader.cpp index c3b8f1e..e1ba30d 100644 --- a/third_party/WebKit/Source/core/loader/LinkLoader.cpp +++ b/third_party/WebKit/Source/core/loader/LinkLoader.cpp
@@ -321,8 +321,8 @@ return nullptr; } ResourceRequest resourceRequest(document.completeURL(href)); - ResourceFetcher::determineRequestContext(resourceRequest, - resourceType.value(), false); + resourceRequest.setRequestContext( + ResourceFetcher::determineRequestContext(resourceType.value(), false)); if (referrerPolicy != ReferrerPolicyDefault) { resourceRequest.setHTTPReferrer(SecurityPolicy::generateReferrer(
diff --git a/third_party/WebKit/Source/core/loader/resource/CSSStyleSheetResource.cpp b/third_party/WebKit/Source/core/loader/resource/CSSStyleSheetResource.cpp index 63df50a..ccecd6dc 100644 --- a/third_party/WebKit/Source/core/loader/resource/CSSStyleSheetResource.cpp +++ b/third_party/WebKit/Source/core/loader/resource/CSSStyleSheetResource.cpp
@@ -41,8 +41,7 @@ ResourceFetcher* fetcher) { DCHECK_EQ(request.resourceRequest().frameType(), WebURLRequest::FrameTypeNone); - request.mutableResourceRequest().setRequestContext( - WebURLRequest::RequestContextStyle); + request.setRequestContext(WebURLRequest::RequestContextStyle); CSSStyleSheetResource* resource = toCSSStyleSheetResource( fetcher->requestResource(request, CSSStyleSheetResourceFactory())); // TODO(kouhei): Dedupe this logic w/ ScriptResource::fetch
diff --git a/third_party/WebKit/Source/core/loader/resource/DocumentResource.cpp b/third_party/WebKit/Source/core/loader/resource/DocumentResource.cpp index 3ab496f..c6c8718 100644 --- a/third_party/WebKit/Source/core/loader/resource/DocumentResource.cpp +++ b/third_party/WebKit/Source/core/loader/resource/DocumentResource.cpp
@@ -34,8 +34,7 @@ ResourceFetcher* fetcher) { DCHECK_EQ(request.resourceRequest().frameType(), WebURLRequest::FrameTypeNone); - request.mutableResourceRequest().setRequestContext( - WebURLRequest::RequestContextImage); + request.setRequestContext(WebURLRequest::RequestContextImage); return toDocumentResource( fetcher->requestResource(request, SVGDocumentResourceFactory())); }
diff --git a/third_party/WebKit/Source/core/loader/resource/FontResource.cpp b/third_party/WebKit/Source/core/loader/resource/FontResource.cpp index 1488e55..28fc133 100644 --- a/third_party/WebKit/Source/core/loader/resource/FontResource.cpp +++ b/third_party/WebKit/Source/core/loader/resource/FontResource.cpp
@@ -77,8 +77,7 @@ ResourceFetcher* fetcher) { DCHECK_EQ(request.resourceRequest().frameType(), WebURLRequest::FrameTypeNone); - request.mutableResourceRequest().setRequestContext( - WebURLRequest::RequestContextFont); + request.setRequestContext(WebURLRequest::RequestContextFont); return toFontResource( fetcher->requestResource(request, FontResourceFactory())); }
diff --git a/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp b/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp index 65c4270a..c915425 100644 --- a/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp +++ b/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp
@@ -151,8 +151,7 @@ ResourceFetcher* fetcher) { if (request.resourceRequest().requestContext() == WebURLRequest::RequestContextUnspecified) { - request.mutableResourceRequest().setRequestContext( - WebURLRequest::RequestContextImage); + request.setRequestContext(WebURLRequest::RequestContextImage); } if (fetcher->context().pageDismissalEventBeingDispatched()) { KURL requestURL = request.resourceRequest().url();
diff --git a/third_party/WebKit/Source/core/loader/resource/LinkFetchResource.cpp b/third_party/WebKit/Source/core/loader/resource/LinkFetchResource.cpp index 71518b8..4f11cf3 100644 --- a/third_party/WebKit/Source/core/loader/resource/LinkFetchResource.cpp +++ b/third_party/WebKit/Source/core/loader/resource/LinkFetchResource.cpp
@@ -15,7 +15,7 @@ DCHECK_EQ(type, LinkPrefetch); DCHECK_EQ(request.resourceRequest().frameType(), WebURLRequest::FrameTypeNone); - fetcher->determineRequestContext(request.mutableResourceRequest(), type); + request.setRequestContext(fetcher->determineRequestContext(type)); return fetcher->requestResource(request, LinkResourceFactory(type)); }
diff --git a/third_party/WebKit/Source/core/loader/resource/ScriptResource.cpp b/third_party/WebKit/Source/core/loader/resource/ScriptResource.cpp index d3be9db..b4ba5ecd 100644 --- a/third_party/WebKit/Source/core/loader/resource/ScriptResource.cpp +++ b/third_party/WebKit/Source/core/loader/resource/ScriptResource.cpp
@@ -41,8 +41,7 @@ ResourceFetcher* fetcher) { DCHECK_EQ(request.resourceRequest().frameType(), WebURLRequest::FrameTypeNone); - request.mutableResourceRequest().setRequestContext( - WebURLRequest::RequestContextScript); + request.setRequestContext(WebURLRequest::RequestContextScript); ScriptResource* resource = toScriptResource( fetcher->requestResource(request, ScriptResourceFactory())); if (resource && !request.integrityMetadata().isEmpty())
diff --git a/third_party/WebKit/Source/core/loader/resource/XSLStyleSheetResource.cpp b/third_party/WebKit/Source/core/loader/resource/XSLStyleSheetResource.cpp index ca116558..e099c793 100644 --- a/third_party/WebKit/Source/core/loader/resource/XSLStyleSheetResource.cpp +++ b/third_party/WebKit/Source/core/loader/resource/XSLStyleSheetResource.cpp
@@ -35,7 +35,7 @@ namespace blink { -static void applyXSLRequestProperties(ResourceRequest& request) { +static void applyXSLRequestProperties(FetchRequest& request) { request.setRequestContext(WebURLRequest::RequestContextXSLT); // TODO(japhet): Accept: headers can be set manually on XHRs from script, in // the browser process, and... here. The browser process can't tell the @@ -45,13 +45,13 @@ DEFINE_STATIC_LOCAL(const AtomicString, acceptXSLT, ("text/xml, application/xml, application/xhtml+xml, " "text/xsl, application/rss+xml, application/atom+xml")); - request.setHTTPAccept(acceptXSLT); + request.mutableResourceRequest().setHTTPAccept(acceptXSLT); } XSLStyleSheetResource* XSLStyleSheetResource::fetchSynchronously( FetchRequest& request, ResourceFetcher* fetcher) { - applyXSLRequestProperties(request.mutableResourceRequest()); + applyXSLRequestProperties(request); request.makeSynchronous(); XSLStyleSheetResource* resource = toXSLStyleSheetResource( fetcher->requestResource(request, XSLStyleSheetResourceFactory())); @@ -63,7 +63,7 @@ XSLStyleSheetResource* XSLStyleSheetResource::fetch(FetchRequest& request, ResourceFetcher* fetcher) { DCHECK(RuntimeEnabledFeatures::xsltEnabled()); - applyXSLRequestProperties(request.mutableResourceRequest()); + applyXSLRequestProperties(request); return toXSLStyleSheetResource( fetcher->requestResource(request, XSLStyleSheetResourceFactory())); }
diff --git a/third_party/WebKit/Source/platform/audio/AudioDestination.cpp b/third_party/WebKit/Source/platform/audio/AudioDestination.cpp index 81e00726..691ffb1 100644 --- a/third_party/WebKit/Source/platform/audio/AudioDestination.cpp +++ b/third_party/WebKit/Source/platform/audio/AudioDestination.cpp
@@ -70,7 +70,14 @@ false)), m_renderBus(AudioBus::create(numberOfOutputChannels, AudioUtilities::kRenderQuantumFrames)), + m_fifo( + WTF::wrapUnique(new PushPullFIFO(numberOfOutputChannels, kFIFOSize))), m_framesElapsed(0) { + m_callbackBufferSize = hardwareBufferSize(); + if (!checkBufferSize()) { + NOTREACHED(); + } + // Create WebAudioDevice. blink::WebAudioDevice is designed to support the // local input (e.g. loopback from OS audio system), but Chromium's media // renderer does not support it currently. Thus, we use zero for the number @@ -79,15 +86,6 @@ 0, numberOfOutputChannels, latencyHint, this, String(), std::move(securityOrigin))); DCHECK(m_webAudioDevice); - - m_callbackBufferSize = m_webAudioDevice->framesPerBuffer(); - - if (!checkBufferSize()) { - NOTREACHED(); - } - - // Create a FIFO. - m_fifo = WTF::wrapUnique(new PushPullFIFO(numberOfOutputChannels, kFIFOSize)); } AudioDestination::~AudioDestination() { @@ -102,6 +100,12 @@ CHECK_EQ(destinationData.size(), m_numberOfOutputChannels); CHECK_EQ(numberOfFrames, m_callbackBufferSize); + // Note that this method is called by AudioDeviceThread. If FIFO is not ready, + // or the requested render size is greater than FIFO size return here. + // (crbug.com/692423) + if (!m_fifo || m_fifo->length() < numberOfFrames) + return; + m_framesElapsed -= std::min(m_framesElapsed, priorFramesSkipped); double outputPosition = m_framesElapsed / static_cast<double>(m_webAudioDevice->sampleRate()) -
diff --git a/third_party/WebKit/Source/platform/loader/fetch/FetchRequest.h b/third_party/WebKit/Source/platform/loader/fetch/FetchRequest.h index 44f7213d7..7389bfc 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/FetchRequest.h +++ b/third_party/WebKit/Source/platform/loader/fetch/FetchRequest.h
@@ -81,6 +81,10 @@ const ResourceRequest& resourceRequest() const { return m_resourceRequest; } const KURL& url() const { return m_resourceRequest.url(); } + void setRequestContext(WebURLRequest::RequestContext context) { + m_resourceRequest.setRequestContext(context); + } + const String& charset() const { return m_charset; } void setCharset(const String& charset) { m_charset = charset; }
diff --git a/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp b/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp index c8111072..9ed1cee 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp
@@ -46,8 +46,7 @@ ResourceFetcher* fetcher) { DCHECK_EQ(request.resourceRequest().frameType(), WebURLRequest::FrameTypeNone); - request.mutableResourceRequest().setRequestContext( - WebURLRequest::RequestContextImport); + request.setRequestContext(WebURLRequest::RequestContextImport); return toRawResource(fetcher->requestResource( request, RawResourceFactory(Resource::ImportResource))); } @@ -101,8 +100,7 @@ ResourceFetcher* fetcher) { DCHECK_EQ(request.resourceRequest().frameType(), WebURLRequest::FrameTypeNone); - request.mutableResourceRequest().setRequestContext( - WebURLRequest::RequestContextTrack); + request.setRequestContext(WebURLRequest::RequestContextTrack); return toRawResource(fetcher->requestResource( request, RawResourceFactory(Resource::TextTrack))); }
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp index 9e62580..a5eae6c5 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp
@@ -208,9 +208,9 @@ info->setFinalResponse(resource->response()); } -static WebURLRequest::RequestContext requestContextFromType( - bool isMainFrame, - Resource::Type type) { +WebURLRequest::RequestContext ResourceFetcher::determineRequestContext( + Resource::Type type, + bool isMainFrame) { switch (type) { case Resource::MainResource: if (!isMainFrame) @@ -639,17 +639,9 @@ context().addResourceTiming(*timingInfo); } -void ResourceFetcher::determineRequestContext(ResourceRequest& request, - Resource::Type type, - bool isMainFrame) { - WebURLRequest::RequestContext requestContext = - requestContextFromType(isMainFrame, type); - request.setRequestContext(requestContext); -} - -void ResourceFetcher::determineRequestContext(ResourceRequest& request, - Resource::Type type) { - determineRequestContext(request, type, context().isMainFrame()); +WebURLRequest::RequestContext ResourceFetcher::determineRequestContext( + Resource::Type type) const { + return determineRequestContext(type, context().isMainFrame()); } void ResourceFetcher::initializeResourceRequest( @@ -661,7 +653,7 @@ context().resourceRequestCachePolicy(request, type, defer)); } if (request.requestContext() == WebURLRequest::RequestContextUnspecified) - determineRequestContext(request, type); + request.setRequestContext(determineRequestContext(type)); if (type == Resource::LinkPrefetch) request.setHTTPHeaderField(HTTPNames::Purpose, "prefetch");
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.h b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.h index 2d33a4d..59ef02a 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.h +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.h
@@ -131,10 +131,10 @@ String getCacheIdentifier() const; - static void determineRequestContext(ResourceRequest&, - Resource::Type, - bool isMainFrame); - void determineRequestContext(ResourceRequest&, Resource::Type); + WARN_UNUSED_RESULT static WebURLRequest::RequestContext + determineRequestContext(Resource::Type, bool isMainFrame); + WARN_UNUSED_RESULT WebURLRequest::RequestContext determineRequestContext( + Resource::Type) const; void updateAllImageResourcePriorities();
diff --git a/third_party/WebKit/Source/platform/loader/testing/MockResource.cpp b/third_party/WebKit/Source/platform/loader/testing/MockResource.cpp index ac4532c..6ac5161 100644 --- a/third_party/WebKit/Source/platform/loader/testing/MockResource.cpp +++ b/third_party/WebKit/Source/platform/loader/testing/MockResource.cpp
@@ -28,8 +28,7 @@ // static MockResource* MockResource::fetch(FetchRequest& request, ResourceFetcher* fetcher) { - request.mutableResourceRequest().setRequestContext( - WebURLRequest::RequestContextSubresource); + request.setRequestContext(WebURLRequest::RequestContextSubresource); Resource* resource = fetcher->requestResource(request, MockResourceFactory()); return static_cast<MockResource*>(resource); }
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp index 1afe4abd..ffc437e4 100644 --- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -8246,8 +8246,7 @@ static Resource* fetchManifest(Document* document, const KURL& url) { FetchRequest fetchRequest = FetchRequest(ResourceRequest(url), FetchInitiatorInfo()); - fetchRequest.mutableResourceRequest().setRequestContext( - WebURLRequest::RequestContextManifest); + fetchRequest.setRequestContext(WebURLRequest::RequestContextManifest); return RawResource::fetchSynchronously(fetchRequest, document->fetcher()); }
diff --git a/tools/chrome_proxy/webdriver/smoke.py b/tools/chrome_proxy/webdriver/smoke.py index 1da694c3..78aba30b 100644 --- a/tools/chrome_proxy/webdriver/smoke.py +++ b/tools/chrome_proxy/webdriver/smoke.py
@@ -33,6 +33,16 @@ self.assertEqual(2, len(responses)) for response in responses: self.assertHasChromeProxyViaHeader(response) + + # Ensure Chrome uses DataSaver in normal mode. + def testCheckPageWithNormalMode(self): + with TestDriver() as t: + t.AddChromeArg('--enable-spdy-proxy-auth') + t.LoadURL('http://check.googlezip.net/test.html') + responses = t.GetHTTPResponses() + self.assertNotEqual(0, len(responses)) + for response in responses: + self.assertHasChromeProxyViaHeader(response) # Ensure pageload metric pingback with DataSaver. def testPingback(self):
diff --git a/tools/gn/bootstrap/bootstrap.py b/tools/gn/bootstrap/bootstrap.py index 38cfb11..75e2eb4cc 100755 --- a/tools/gn/bootstrap/bootstrap.py +++ b/tools/gn/bootstrap/bootstrap.py
@@ -384,6 +384,7 @@ 'base/base_paths.cc', 'base/base_switches.cc', 'base/build_time.cc', + 'base/callback_helpers.cc', 'base/callback_internal.cc', 'base/command_line.cc', 'base/debug/activity_tracker.cc', @@ -605,6 +606,7 @@ 'base/allocator/allocator_shim.cc', 'base/allocator/allocator_shim_default_dispatch_to_glibc.cc', 'base/memory/shared_memory_posix.cc', + 'base/memory/shared_memory_tracker.cc', 'base/nix/xdg_util.cc', 'base/process/internal_linux.cc', 'base/process/memory_linux.cc',
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index a74172d..63c1e6a 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -266,6 +266,7 @@ 'Android Tests': 'android_release_bot_minimal_symbols', 'Cast Android (dbg)': 'android_cast_debug_static_bot', 'Cast Linux': 'cast_release_bot', + 'Cast Audio Linux': 'cast_audio_release_bot', 'Linux Builder (dbg)': 'debug_bot', 'Linux Builder (dbg)(32)': 'debug_bot_x86', 'Linux Builder': 'release_bot', @@ -343,7 +344,8 @@ }, 'chromium.swarm': { - 'Android Swarm': 'android_without_codecs_release_bot_minimal_symbols', + 'Android N5 Swarm': 'android_release_bot_minimal_symbols', + 'Android N5X Swarm': 'android_release_bot_minimal_symbols_arm64', 'Linux Swarm': 'release_bot', 'Mac Swarm': 'release_bot_mac_strip', 'Windows Swarm': 'release_bot_x86', @@ -538,6 +540,7 @@ 'Chromium Linux Codesearch Builder': 'codesearch', 'ChromiumOS Codesearch Builder': 'codesearch', 'cast_shell_linux': 'cast_release_trybot', + 'cast_shell_audio_linux': 'cast_audio_release_trybot', 'chromeos_amd64-generic_chromium_compile_only_ng': 'cros_chrome_sdk', 'chromeos_daisy_chromium_compile_only_ng': 'cros_chrome_sdk', 'chromeos_x86-generic_chromium_compile_only_ng': 'cros_chrome_sdk', @@ -981,6 +984,14 @@ 'cast', 'release_trybot', ], + 'cast_audio_release_bot': [ + 'cast', 'cast_audio', 'release_bot', + ], + + 'cast_audio_release_trybot': [ + 'cast', 'cast_audio', 'release_trybot', + ], + 'cfi_full_cfi_diag_release_static': [ 'cfi_full', 'cfi_diag', 'release', 'static', ], @@ -1577,6 +1588,10 @@ 'gn_args': 'is_chromecast=true', }, + 'cast_audio': { + 'gn_args': 'is_cast_audio_only=true enable_webrtc=false' + }, + 'cfi': { 'gn_args': 'is_cfi=true', },
diff --git a/tools/valgrind/asan/third_party/asan_symbolize.py b/tools/valgrind/asan/third_party/asan_symbolize.py index 59fceaaed..1a56e44 100755 --- a/tools/valgrind/asan/third_party/asan_symbolize.py +++ b/tools/valgrind/asan/third_party/asan_symbolize.py
@@ -23,6 +23,8 @@ binary_name_filter = None fix_filename_patterns = None logfile = sys.stdin +allow_system_symbolizer = True +force_system_symbolizer = False # FIXME: merge the code that calls fix_filename(). def fix_filename(file_name): @@ -36,6 +38,10 @@ def sysroot_path_filter(binary_name): return sysroot_path + binary_name +def is_valid_arch(s): + return s in ["i386", "x86_64", "x86_64h", "arm", "armv6", "armv7", "armv7s", + "armv7k", "arm64", "powerpc64", "powerpc64le", "s390x", "s390"] + def guess_arch(addr): # Guess which arch we're running. 10 = len('0x') + 8 hex digits. if len(addr) > 10: @@ -76,17 +82,19 @@ cmd = [self.symbolizer_path, '--use-symbol-table=true', '--demangle=%s' % demangle, - '--functions=short', + '--functions=linkage', '--inlining=true', '--default-arch=%s' % self.default_arch] if self.system == 'Darwin': for hint in self.dsym_hints: cmd.append('--dsym-hint=%s' % hint) if DEBUG: - print ' '.join(cmd) + print(' '.join(cmd)) try: result = subprocess.Popen(cmd, stdin=subprocess.PIPE, - stdout=subprocess.PIPE) + stdout=subprocess.PIPE, + bufsize=0, + universal_newlines=True) except OSError: result = None return result @@ -99,8 +107,8 @@ try: symbolizer_input = '"%s" %s' % (binary, offset) if DEBUG: - print symbolizer_input - print >> self.pipe.stdin, symbolizer_input + print(symbolizer_input) + self.pipe.stdin.write("%s\n" % symbolizer_input) while True: function_name = self.pipe.stdout.readline().rstrip() if not function_name: @@ -134,34 +142,44 @@ super(Addr2LineSymbolizer, self).__init__() self.binary = binary self.pipe = self.open_addr2line() + self.output_terminator = -1 def open_addr2line(self): addr2line_tool = 'addr2line' if binutils_prefix: addr2line_tool = binutils_prefix + addr2line_tool - cmd = [addr2line_tool, '-f'] + cmd = [addr2line_tool, '-fi'] if demangle: cmd += ['--demangle'] cmd += ['-e', self.binary] if DEBUG: - print ' '.join(cmd) + print(' '.join(cmd)) return subprocess.Popen(cmd, - stdin=subprocess.PIPE, stdout=subprocess.PIPE) + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + bufsize=0, + universal_newlines=True) def symbolize(self, addr, binary, offset): """Overrides Symbolizer.symbolize.""" if self.binary != binary: return None + lines = [] try: - print >> self.pipe.stdin, offset - function_name = self.pipe.stdout.readline().rstrip() - file_name = self.pipe.stdout.readline().rstrip() + self.pipe.stdin.write("%s\n" % offset) + self.pipe.stdin.write("%s\n" % self.output_terminator) + is_first_frame = True + while True: + function_name = self.pipe.stdout.readline().rstrip() + file_name = self.pipe.stdout.readline().rstrip() + if is_first_frame: + is_first_frame = False + elif function_name in ['', '??']: + assert file_name == function_name + break + lines.append((function_name, file_name)); except Exception: - function_name = '' - file_name = '' - file_name = fix_filename(file_name) - return ['%s in %s %s' % (addr, function_name, file_name)] - + lines.append(('??', '??:0')) + return ['%s in %s %s' % (addr, function, fix_filename(file)) for (function, file) in lines] class UnbufferedLineConverter(object): """ @@ -197,15 +215,15 @@ class DarwinSymbolizer(Symbolizer): - def __init__(self, addr, binary): + def __init__(self, addr, binary, arch): super(DarwinSymbolizer, self).__init__() self.binary = binary - self.arch = guess_arch(addr) + self.arch = arch self.open_atos() def open_atos(self): if DEBUG: - print 'atos -o %s -arch %s' % (self.binary, self.arch) + print('atos -o %s -arch %s' % (self.binary, self.arch)) cmdline = ['atos', '-o', self.binary, '-arch', self.arch] self.atos = UnbufferedLineConverter(cmdline, close_stderr=True) @@ -220,7 +238,7 @@ # foo(type1, type2) (in object.name) (filename.cc:80) match = re.match('^(.*) \(in (.*)\) \((.*:\d*)\)$', atos_line) if DEBUG: - print 'atos_line: ', atos_line + print('atos_line: ', atos_line) if match: function_name = match.group(1) function_name = re.sub('\(.*?\)', '', function_name) @@ -259,10 +277,10 @@ return None -def SystemSymbolizerFactory(system, addr, binary): +def SystemSymbolizerFactory(system, addr, binary, arch): if system == 'Darwin': - return DarwinSymbolizer(addr, binary) - elif system == 'Linux': + return DarwinSymbolizer(addr, binary, arch) + elif system == 'Linux' or system == 'FreeBSD': return Addr2LineSymbolizer(binary) @@ -334,7 +352,7 @@ function_name, file_name, line_no = res result = ['%s in %s %s:%d' % ( addr, function_name, file_name, line_no)] - print result + print(result) return result else: return None @@ -360,7 +378,7 @@ self.frame_no = 0 self.process_line = self.process_line_posix - def symbolize_address(self, addr, binary, offset): + def symbolize_address(self, addr, binary, offset, arch): # On non-Darwin (i.e. on platforms without .dSYM debug info) always use # a single symbolizer binary. # On Darwin, if the dsym hint producer is present: @@ -372,29 +390,35 @@ # if so, reuse |last_llvm_symbolizer| which has the full set of hints; # 3. otherwise create a new symbolizer and pass all currently known # .dSYM hints to it. - if not binary in self.llvm_symbolizers: - use_new_symbolizer = True - if self.system == 'Darwin' and self.dsym_hint_producer: - dsym_hints_for_binary = set(self.dsym_hint_producer(binary)) - use_new_symbolizer = bool(dsym_hints_for_binary - self.dsym_hints) - self.dsym_hints |= dsym_hints_for_binary - if self.last_llvm_symbolizer and not use_new_symbolizer: + result = None + if not force_system_symbolizer: + if not binary in self.llvm_symbolizers: + use_new_symbolizer = True + if self.system == 'Darwin' and self.dsym_hint_producer: + dsym_hints_for_binary = set(self.dsym_hint_producer(binary)) + use_new_symbolizer = bool(dsym_hints_for_binary - self.dsym_hints) + self.dsym_hints |= dsym_hints_for_binary + if self.last_llvm_symbolizer and not use_new_symbolizer: + self.llvm_symbolizers[binary] = self.last_llvm_symbolizer + else: + self.last_llvm_symbolizer = LLVMSymbolizerFactory( + self.system, arch, self.dsym_hints) self.llvm_symbolizers[binary] = self.last_llvm_symbolizer - else: - self.last_llvm_symbolizer = LLVMSymbolizerFactory( - self.system, guess_arch(addr), self.dsym_hints) - self.llvm_symbolizers[binary] = self.last_llvm_symbolizer - # Use the chain of symbolizers: - # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos - # (fall back to next symbolizer if the previous one fails). - if not binary in symbolizers: - symbolizers[binary] = ChainSymbolizer( - [BreakpadSymbolizerFactory(binary), self.llvm_symbolizers[binary]]) - result = symbolizers[binary].symbolize(addr, binary, offset) + # Use the chain of symbolizers: + # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos + # (fall back to next symbolizer if the previous one fails). + if not binary in symbolizers: + symbolizers[binary] = ChainSymbolizer( + [BreakpadSymbolizerFactory(binary), self.llvm_symbolizers[binary]]) + result = symbolizers[binary].symbolize(addr, binary, offset) + else: + symbolizers[binary] = ChainSymbolizer([]) if result is None: + if not allow_system_symbolizer: + raise Exception('Failed to launch or use llvm-symbolizer.') # Initialize system symbolizer only if other symbolizers failed. symbolizers[binary].append_symbolizer( - SystemSymbolizerFactory(self.system, addr, binary)) + SystemSymbolizerFactory(self.system, addr, binary, arch)) result = symbolizers[binary].symbolize(addr, binary, offset) # The system symbolizer must produce some result. assert result @@ -414,7 +438,7 @@ self.frame_no = 0 for line in logfile: processed = self.process_line(line) - print '\n'.join(processed) + print('\n'.join(processed)) def process_line_echo(self, line): return [line.rstrip()] @@ -428,18 +452,28 @@ if not match: return [self.current_line] if DEBUG: - print line + print(line) _, frameno_str, addr, binary, offset = match.groups() + arch = "" + # Arch can be embedded in the filename, e.g.: "libabc.dylib:x86_64h" + colon_pos = binary.rfind(":") + if colon_pos != -1: + maybe_arch = binary[colon_pos+1:] + if is_valid_arch(maybe_arch): + arch = maybe_arch + binary = binary[0:colon_pos] + if arch == "": + arch = guess_arch(addr) if frameno_str == '0': # Assume that frame #0 is the first frame of new stack trace. self.frame_no = 0 original_binary = binary if self.binary_name_filter: binary = self.binary_name_filter(binary) - symbolized_line = self.symbolize_address(addr, binary, offset) + symbolized_line = self.symbolize_address(addr, binary, offset, arch) if not symbolized_line: if original_binary != binary: - symbolized_line = self.symbolize_address(addr, binary, offset) + symbolized_line = self.symbolize_address(addr, binary, offset, arch) return self.get_symbolized_lines(symbolized_line) @@ -461,6 +495,8 @@ parser.add_argument('-l','--logfile', default=sys.stdin, type=argparse.FileType('r'), help='set log file name to parse, default is stdin') + parser.add_argument('--force-system-symbolizer', action='store_true', + help='don\'t use llvm-symbolizer') args = parser.parse_args() if args.path_to_cut: fix_filename_patterns = args.path_to_cut @@ -475,5 +511,9 @@ logfile = args.logfile else: logfile = sys.stdin + if args.force_system_symbolizer: + force_system_symbolizer = True + if force_system_symbolizer: + assert(allow_system_symbolizer) loop = SymbolizationLoop(binary_name_filter) loop.process_logfile()
diff --git a/ui/aura/env.cc b/ui/aura/env.cc index c422716..1799a59 100644 --- a/ui/aura/env.cc +++ b/ui/aura/env.cc
@@ -13,6 +13,7 @@ #include "ui/aura/env_observer.h" #include "ui/aura/input_state_lookup.h" #include "ui/aura/mus/mus_types.h" +#include "ui/aura/mus/os_exchange_data_provider_mus.h" #include "ui/aura/mus/window_port_mus.h" #include "ui/aura/mus/window_tree_client.h" #include "ui/aura/window.h" @@ -75,6 +76,9 @@ // Env, public: Env::~Env() { + if (RunningInsideMus()) + ui::OSExchangeDataProviderFactory::SetFactory(nullptr); + for (EnvObserver& observer : observers_) observer.OnWillDestroyEnv(); DCHECK_EQ(this, lazy_tls_ptr.Pointer()->Get()); @@ -192,8 +196,11 @@ } void Env::Init() { - if (RunningInsideMus()) + if (RunningInsideMus()) { + ui::OSExchangeDataProviderFactory::SetFactory(this); return; + } + #if defined(USE_OZONE) // The ozone platform can provide its own event source. So initialize the // platform before creating the default event source. If running inside mus @@ -243,4 +250,8 @@ return NULL; } +std::unique_ptr<ui::OSExchangeData::Provider> Env::BuildProvider() { + return base::MakeUnique<aura::OSExchangeDataProviderMus>(); +} + } // namespace aura
diff --git a/ui/aura/env.h b/ui/aura/env.h index f843ca0..b6b1b2c 100644 --- a/ui/aura/env.h +++ b/ui/aura/env.h
@@ -11,6 +11,7 @@ #include "base/observer_list.h" #include "base/supports_user_data.h" #include "ui/aura/aura_export.h" +#include "ui/base/dragdrop/os_exchange_data_provider_factory.h" #include "ui/events/event_handler.h" #include "ui/events/event_target.h" #include "ui/gfx/geometry/point.h" @@ -39,7 +40,9 @@ class WindowTreeHost; // A singleton object that tracks general state within Aura. -class AURA_EXPORT Env : public ui::EventTarget, public base::SupportsUserData { +class AURA_EXPORT Env : public ui::EventTarget, + public ui::OSExchangeDataProviderFactory::Factory, + public base::SupportsUserData { public: enum class Mode { // Classic aura. @@ -138,6 +141,9 @@ std::unique_ptr<ui::EventTargetIterator> GetChildIterator() const override; ui::EventTargeter* GetEventTargeter() override; + // Overridden from ui::OSExchangeDataProviderFactory::Factory: + std::unique_ptr<ui::OSExchangeData::Provider> BuildProvider() override; + // This is not const for tests, which may share Env across tests and so needs // to reset the value. Mode mode_;
diff --git a/ui/aura/mus/drag_drop_controller_mus.cc b/ui/aura/mus/drag_drop_controller_mus.cc index a82841c8..ccb364dd 100644 --- a/ui/aura/mus/drag_drop_controller_mus.cc +++ b/ui/aura/mus/drag_drop_controller_mus.cc
@@ -137,23 +137,25 @@ // we start showing an image representation of the drag under he cursor. base::RunLoop run_loop; - WindowMus* source_window_mus = WindowMus::Get(source_window); + WindowMus* root_window_mus = WindowMus::Get(root_window); const uint32_t change_id = - drag_drop_controller_host_->CreateChangeIdForDrag(source_window_mus); - CurrentDragState current_drag_state = {source_window_mus->server_id(), + drag_drop_controller_host_->CreateChangeIdForDrag(root_window_mus); + CurrentDragState current_drag_state = {root_window_mus->server_id(), change_id, ui::mojom::kDropEffectNone, data, run_loop.QuitClosure()}; base::AutoReset<CurrentDragState*> resetter(¤t_drag_state_, ¤t_drag_state); - std::map<std::string, std::vector<uint8_t>> drag_data = - static_cast<const aura::OSExchangeDataProviderMus&>(data.provider()) - .GetData(); - window_tree_->PerformDragDrop(change_id, source_window_mus->server_id(), - mojo::MapToUnorderedMap(drag_data), - drag_operations); base::MessageLoop* loop = base::MessageLoop::current(); base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop); + + std::map<std::string, std::vector<uint8_t>> drag_data = + static_cast<const aura::OSExchangeDataProviderMus&>(data.provider()) + .GetData(); + window_tree_->PerformDragDrop(change_id, root_window_mus->server_id(), + mojo::MapToUnorderedMap(drag_data), + drag_operations); + run_loop.Run(); return current_drag_state.completed_action;
diff --git a/ui/aura/mus/window_port_mus.cc b/ui/aura/mus/window_port_mus.cc index e59ccba7..fc09504 100644 --- a/ui/aura/mus/window_port_mus.cc +++ b/ui/aura/mus/window_port_mus.cc
@@ -71,6 +71,10 @@ window_tree_client_->SetEventTargetingPolicy(this, policy); } +void WindowPortMus::SetCanAcceptDrops(bool can_accept_drops) { + window_tree_client_->SetCanAcceptDrops(this, can_accept_drops); +} + void WindowPortMus::Embed( ui::mojom::WindowTreeClientPtr client, uint32_t flags,
diff --git a/ui/aura/mus/window_port_mus.h b/ui/aura/mus/window_port_mus.h index 6677505f..c1f6e35 100644 --- a/ui/aura/mus/window_port_mus.h +++ b/ui/aura/mus/window_port_mus.h
@@ -59,6 +59,9 @@ // Sets the EventTargetingPolicy, default is TARGET_AND_DESCENDANTS. void SetEventTargetingPolicy(ui::mojom::EventTargetingPolicy policy); + // Sets whether this window can accept drops, defaults to false. + void SetCanAcceptDrops(bool can_accept_drops); + // Embeds a new client in this Window. See WindowTreeClient::Embed() for // details on arguments. void Embed(ui::mojom::WindowTreeClientPtr client,
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc index 3574d7186..82f54f0 100644 --- a/ui/aura/mus/window_tree_client.cc +++ b/ui/aura/mus/window_tree_client.cc
@@ -826,9 +826,10 @@ test_observers_.RemoveObserver(observer); } -void WindowTreeClient::SetCanAcceptDrops(Id window_id, bool can_accept_drops) { +void WindowTreeClient::SetCanAcceptDrops(WindowMus* window, + bool can_accept_drops) { DCHECK(tree_); - tree_->SetCanAcceptDrops(window_id, can_accept_drops); + tree_->SetCanAcceptDrops(window->server_id(), can_accept_drops); } void WindowTreeClient::SetEventTargetingPolicy( @@ -1268,10 +1269,9 @@ void WindowTreeClient::OnPerformDragDropCompleted(uint32_t change_id, bool success, uint32_t action_taken) { - if (drag_drop_controller_->DoesChangeIdMatchDragChangeId(change_id)) { - OnChangeCompleted(change_id, success); + OnChangeCompleted(change_id, success); + if (drag_drop_controller_->DoesChangeIdMatchDragChangeId(change_id)) drag_drop_controller_->OnPerformDragDropCompleted(action_taken); - } } void WindowTreeClient::OnChangeCompleted(uint32_t change_id, bool success) {
diff --git a/ui/aura/mus/window_tree_client.h b/ui/aura/mus/window_tree_client.h index dade5871..6307371 100644 --- a/ui/aura/mus/window_tree_client.h +++ b/ui/aura/mus/window_tree_client.h
@@ -110,7 +110,7 @@ ClientSpecificId client_id() const { return client_id_; } void SetCanFocus(Window* window, bool can_focus); - void SetCanAcceptDrops(Id window_id, bool can_accept_drops); + void SetCanAcceptDrops(WindowMus* window, bool can_accept_drops); void SetEventTargetingPolicy(WindowMus* window, ui::mojom::EventTargetingPolicy policy); void SetPredefinedCursor(WindowMus* window,
diff --git a/ui/display/BUILD.gn b/ui/display/BUILD.gn index 3d71046..643971c 100644 --- a/ui/display/BUILD.gn +++ b/ui/display/BUILD.gn
@@ -22,8 +22,6 @@ "display_list.h", "display_observer.cc", "display_observer.h", - "display_snapshot_mojo.cc", - "display_snapshot_mojo.h", "display_switches.cc", "display_switches.h", "fake_display_delegate.cc",
diff --git a/ui/display/mojo/display_snapshot_mojo.typemap b/ui/display/mojo/display_snapshot_mojo.typemap index 5a831be..bd06b0fb 100644 --- a/ui/display/mojo/display_snapshot_mojo.typemap +++ b/ui/display/mojo/display_snapshot_mojo.typemap
@@ -3,7 +3,7 @@ # found in the LICENSE file. mojom = "//ui/display/mojo/display_snapshot_mojo.mojom" -public_headers = [ "//ui/display/display_snapshot_mojo.h" ] +public_headers = [ "//ui/display/types/display_snapshot_mojo.h" ] traits_headers = [ "//ui/display/mojo/display_snapshot_mojo_struct_traits.h" ] sources = [ "//ui/display/mojo/display_snapshot_mojo_struct_traits.cc",
diff --git a/ui/display/mojo/display_snapshot_mojo_struct_traits.h b/ui/display/mojo/display_snapshot_mojo_struct_traits.h index bf4f584..0ce011efe 100644 --- a/ui/display/mojo/display_snapshot_mojo_struct_traits.h +++ b/ui/display/mojo/display_snapshot_mojo_struct_traits.h
@@ -5,9 +5,9 @@ #ifndef UI_DISPLAY_MOJO_DISPLAY_SNAPSHOT_MOJO_STRUCT_TRAITS_H_ #define UI_DISPLAY_MOJO_DISPLAY_SNAPSHOT_MOJO_STRUCT_TRAITS_H_ -#include "ui/display/display_snapshot_mojo.h" #include "ui/display/mojo/display_snapshot_mojo.mojom.h" #include "ui/display/types/display_mode.h" +#include "ui/display/types/display_snapshot_mojo.h" namespace mojo {
diff --git a/ui/display/mojo/display_struct_traits_unittest.cc b/ui/display/mojo/display_struct_traits_unittest.cc index 119f768..e828ab7 100644 --- a/ui/display/mojo/display_struct_traits_unittest.cc +++ b/ui/display/mojo/display_struct_traits_unittest.cc
@@ -10,10 +10,10 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/display.h" #include "ui/display/display_layout.h" -#include "ui/display/display_snapshot_mojo.h" #include "ui/display/mojo/display_struct_traits_test.mojom.h" #include "ui/display/types/display_constants.h" #include "ui/display/types/display_mode.h" +#include "ui/display/types/display_snapshot_mojo.h" #include "ui/display/types/gamma_ramp_rgb_entry.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h"
diff --git a/ui/display/types/BUILD.gn b/ui/display/types/BUILD.gn index b4053c4..9cef99b 100644 --- a/ui/display/types/BUILD.gn +++ b/ui/display/types/BUILD.gn
@@ -10,6 +10,8 @@ "display_mode.h", "display_snapshot.cc", "display_snapshot.h", + "display_snapshot_mojo.cc", + "display_snapshot_mojo.h", "display_types_export.h", "fake_display_controller.h", "gamma_ramp_rgb_entry.h",
diff --git a/ui/display/display_snapshot_mojo.cc b/ui/display/types/display_snapshot_mojo.cc similarity index 97% rename from ui/display/display_snapshot_mojo.cc rename to ui/display/types/display_snapshot_mojo.cc index 53b1779..adee70dc 100644 --- a/ui/display/display_snapshot_mojo.cc +++ b/ui/display/types/display_snapshot_mojo.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/display/display_snapshot_mojo.h" +#include "ui/display/types/display_snapshot_mojo.h" #include "base/memory/ptr_util.h" #include "ui/display/types/display_constants.h"
diff --git a/ui/display/display_snapshot_mojo.h b/ui/display/types/display_snapshot_mojo.h similarity index 92% rename from ui/display/display_snapshot_mojo.h rename to ui/display/types/display_snapshot_mojo.h index fb669fe..1b0c50b 100644 --- a/ui/display/display_snapshot_mojo.h +++ b/ui/display/types/display_snapshot_mojo.h
@@ -8,13 +8,13 @@ #include <memory> #include "base/macros.h" -#include "ui/display/display_export.h" #include "ui/display/types/display_snapshot.h" +#include "ui/display/types/display_types_export.h" namespace display { // DisplaySnapshot implementation that can be used with Mojo IPC. -class DISPLAY_EXPORT DisplaySnapshotMojo : public DisplaySnapshot { +class DISPLAY_TYPES_EXPORT DisplaySnapshotMojo : public DisplaySnapshot { public: DisplaySnapshotMojo(int64_t display_id, const gfx::Point& origin,
diff --git a/ui/login/account_picker/screen_account_picker.js b/ui/login/account_picker/screen_account_picker.js index d66258e..572404d 100644 --- a/ui/login/account_picker/screen_account_picker.js +++ b/ui/login/account_picker/screen_account_picker.js
@@ -35,6 +35,8 @@ 'showBannerMessage', 'showUserPodCustomIcon', 'hideUserPodCustomIcon', + 'setUserPodFingerprintIcon', + 'removeUserPodFingerprintIcon', 'disablePinKeyboardForUser', 'setAuthType', 'setTouchViewState', @@ -419,6 +421,23 @@ }, /** + * Set a fingerprint icon in the user pod of |username|. + * @param {string} username Username of the selected user + * @param {number} state Fingerprint unlock state + */ + setUserPodFingerprintIcon: function(username, state) { + $('pod-row').setUserPodFingerprintIcon(username, state); + }, + + /** + * Removes the fingerprint icon in the user pod of |username|. + * @param {string} username Username of the selected user. + */ + removeUserPodFingerprintIcon: function(username) { + $('pod-row').removeUserPodFingerprintIcon(username); + }, + + /** * Sets the authentication type used to authenticate the user. * @param {string} username Username of selected user * @param {number} authType Authentication type, must be a valid value in
diff --git a/ui/login/account_picker/user_pod_row.css b/ui/login/account_picker/user_pod_row.css index 64e25f6e..8130e385 100644 --- a/ui/login/account_picker/user_pod_row.css +++ b/ui/login/account_picker/user_pod_row.css
@@ -415,6 +415,7 @@ display: none; } +.fingerprint-icon-container, .custom-icon-container { display: flex; flex: none; @@ -554,6 +555,42 @@ background-image: url(chrome://theme/IDR_KIOSK_APP_USER_POD_ICON); } +.fingerprint-icon-container.hidden { + display: none; +} + +.fingerprint-icon-container.default .fingerprint-icon-image { + background-image: url(../../webui/resources/images/fingerprint_default.svg); +} + +.fingerprint-icon-container.default:hover .fingerprint-icon-image { + background-image: url(../../webui/resources/images/fingerprint_signin.svg); +} + +.fingerprint-icon-container.signin .fingerprint-icon-image { + background-image: url(../../webui/resources/images/fingerprint_signin.svg); +} + +.fingerprint-icon-container.failed .fingerprint-icon-image { + background-image: url(../../webui/resources/images/fingerprint_failed.svg); +} + +.pod input[type='password'].hidden::-webkit-input-placeholder { + color: grey; +} + +.pod input[type='password'].default::-webkit-input-placeholder { + color: grey; +} + +.pod input[type='password'].signin::-webkit-input-placeholder { + color: var(--google-blue-500); +} + +.pod input[type='password'].failed::-webkit-input-placeholder { + color: var(--google-red-500); +} + .action-box-menu { display: none; z-index: 6;
diff --git a/ui/login/account_picker/user_pod_row.js b/ui/login/account_picker/user_pod_row.js index c52ccfa3..13a1c64 100644 --- a/ui/login/account_picker/user_pod_row.js +++ b/ui/login/account_picker/user_pod_row.js
@@ -125,6 +125,32 @@ 5: 'forceOfflinePassword' }; + /** + * Supported fingerprint unlock states. + * @enum {number} + * @const + */ + var FINGERPRINT_STATES = { + HIDDEN: 0, + DEFAULT: 1, + SIGNIN: 2, + FAILED: 3, + }; + + /** + * The fingerprint states to classes mapping. + * {@code state} properties indicate current fingerprint unlock state. + * {@code class} properties are CSS classes used to set the icons' background + * and password placeholder color. + * @const {Array<{type: !number, class: !string}>} + */ + var FINGERPRINT_STATES_MAPPING = [ + {state: FINGERPRINT_STATES.HIDDEN, class: 'hidden'}, + {state: FINGERPRINT_STATES.DEFAULT, class: 'default'}, + {state: FINGERPRINT_STATES.SIGNIN, class: 'signin'}, + {state: FINGERPRINT_STATES.FAILED, class: 'failed'} + ]; + // Focus and tab order are organized as follows: // // (1) all user pods have tab index 1 so they are traversed first; @@ -711,6 +737,13 @@ */ userClickAuthAllowed_: false, + /** + * Whether the user has recently authenticated with fingerprint. + * @type {boolean} + * @private + */ + fingerprintAuthenticated_: false, + /** @override */ decorate: function() { this.tabIndex = UserPodTabOrder.POD_INPUT; @@ -750,6 +783,15 @@ this.actionBoxRemoveUserWarningButtonElement.addEventListener('keydown', this.handleRemoveUserConfirmationKeyDown_.bind(this)); + if (this.fingerprintIconElement) { + this.fingerprintIconElement.addEventListener( + 'mouseover', this.handleFingerprintIconMouseOver_.bind(this)); + this.fingerprintIconElement.addEventListener( + 'mouseout', this.handleFingerprintIconMouseOut_.bind(this)); + this.fingerprintIconElement.addEventListener( + 'mousedown', stopEventPropagation); + } + var customIcon = this.customIconElement; customIcon.parentNode.replaceChild(new UserPodCustomIcon(), customIcon); }, @@ -1096,6 +1138,14 @@ }, /** + * Gets the fingerprint icon area. + * @type {!HTMLDivElement} + */ + get fingerprintIconElement() { + return this.querySelector('.fingerprint-icon-container'); + }, + + /** * Updates the user pod element. */ update: function() { @@ -1216,6 +1266,10 @@ this.userTypeIconAreaElement.hidden = false; }, + isFingerprintIconShown: function() { + return this.fingerprintIconElement && !this.fingerprintIconElement.hidden; + }, + /** * The user that this pod represents. * @type {!Object} @@ -1412,6 +1466,10 @@ this.classList.toggle('signing-in', true); chrome.send('attemptUnlock', [this.user.username]); } else if (this.isAuthTypePassword) { + if (this.fingerprintAuthenticated_) { + this.fingerprintAuthenticated_ = false; + return true; + } var pinValue = this.pinKeyboard ? this.pinKeyboard.value : ''; var password = this.passwordElement.value || pinValue; if (!password) @@ -1822,6 +1880,50 @@ }, /** + * Handles mouseover event on fingerprint icon. + * @param {Event} e MouseOver event. + */ + handleFingerprintIconMouseOver_: function(e) { + var bubbleContent = document.createElement('div'); + bubbleContent.textContent = + loadTimeData.getString('fingerprintIconMessage'); + this.passwordElement.placeholder = + loadTimeData.getString('fingerprintHint'); + + /** @const */ var BUBBLE_OFFSET = 25; + /** @const */ var BUBBLE_PADDING = -8; + var attachment = this.isPinShown() ? cr.ui.Bubble.Attachment.RIGHT : + cr.ui.Bubble.Attachment.BOTTOM; + var bubbleAnchor = this.getBubbleAnchorForFingerprintIcon_(); + $('bubble').showContentForElement( + bubbleAnchor, attachment, bubbleContent, BUBBLE_OFFSET, + BUBBLE_PADDING, true); + }, + + /** + * Handles mouseout event on fingerprint icon. + * @param {Event} e MouseOut event. + */ + handleFingerprintIconMouseOut_: function(e) { + var bubbleAnchor = this.getBubbleAnchorForFingerprintIcon_(); + $('bubble').hideForElement(bubbleAnchor); + this.passwordElement.placeholder = loadTimeData.getString( + this.isPinShown() ? 'pinKeyboardPlaceholderPinPassword' : + 'passwordHint'); + }, + + /** + * Returns bubble anchor of the fingerprint icon. + * @return {!HTMLElement} Anchor element of the bubble. + */ + getBubbleAnchorForFingerprintIcon_: function() { + var bubbleAnchor = this; + if (this.isPinShown()) + bubbleAnchor = (this.getElementsByClassName('auth-container'))[0]; + return bubbleAnchor; + }, + + /** * Handles a keydown event on remove user confirmation button. * @param {Event} e KeyDown event. */ @@ -1899,8 +2001,14 @@ * button color and state and hides the error popup bubble. */ updateInput_: function() { - if (this.submitButton) - this.submitButton.disabled = this.passwordElement.value.length <= 0; + if (this.submitButton) { + this.submitButton.disabled = this.passwordElement.value.length == 0; + if (this.isFingerprintIconShown()) { + this.submitButton.hidden = this.passwordElement.value.length == 0; + } else { + this.submitButton.hidden = false; + } + } this.showError = false; $('bubble').hide(); }, @@ -3001,6 +3109,9 @@ // immediatelly. pod.customIconElement.setTooltip( icon.tooltip || {text: '', autoshow: false}); + + // Hide fingerprint icon when custom icon is shown. + this.setUserPodFingerprintIcon(username, FINGERPRINT_STATES.HIDDEN); }, /** @@ -3037,6 +3148,100 @@ // TODO(tengs): Allow option for a fading transition. pod.customIconElement.hide(); + + // Show fingerprint icon if applicable. + this.setUserPodFingerprintIcon(username, FINGERPRINT_STATES.DEFAULT); + }, + + /** + * Set a fingerprint icon in the user pod of |username|. + * @param {string} username Username of the selected user + * @param {number} state Fingerprint unlock state + */ + setUserPodFingerprintIcon: function(username, state) { + var pod = this.getPodWithUsername_(username); + if (pod == null) { + console.error( + 'Unable to set user pod fingerprint icon: user pod not found.'); + return; + } + pod.fingerprintAuthenticated_ = false; + if (!pod.fingerprintIconElement) + return; + if (!pod.user.allowFingerprint || state == FINGERPRINT_STATES.HIDDEN || + !pod.customIconElement.hidden) { + pod.fingerprintIconElement.hidden = true; + pod.submitButton.hidden = false; + return; + } + + FINGERPRINT_STATES_MAPPING.forEach(function(icon) { + pod.fingerprintIconElement.classList.toggle( + icon.class, state == icon.state); + }); + pod.fingerprintIconElement.hidden = false; + pod.submitButton.hidden = pod.passwordElement.value.length == 0; + this.updatePasswordField_(pod, state); + if (state == FINGERPRINT_STATES.DEFAULT) + return; + + pod.fingerprintAuthenticated_ = true; + this.setActivatedPod(pod); + if (state == FINGERPRINT_STATES.FAILED) { + /** @const */ var RESET_ICON_TIMEOUT_MS = 500; + setTimeout( + this.resetIconAndPasswordField_.bind(this, pod), + RESET_ICON_TIMEOUT_MS); + } + }, + + /** + * Reset the fingerprint icon and password field. + * @param {UserPod} pod Pod to reset. + */ + resetIconAndPasswordField_: function(pod) { + if (!pod.fingerprintIconElement) + return; + this.setUserPodFingerprintIcon( + pod.user.username, FINGERPRINT_STATES.DEFAULT); + }, + + /** + * Remove the fingerprint icon in the user pod. + * @param {string} username Username of the selected user + */ + removeUserPodFingerprintIcon: function(username) { + var pod = this.getPodWithUsername_(username); + if (pod == null) { + console.error('No user pod found (when removing fingerprint icon).'); + return; + } + this.resetIconAndPasswordField_(pod); + if (pod.fingerprintIconElement) { + pod.fingerprintIconElement.parentNode.removeChild( + pod.fingerprintIconElement); + } + pod.submitButton.hidden = false; + }, + + /** + * Updates the password field in the user pod. + * @param {UserPod} pod Pod to update. + * @param {number} state Fingerprint unlock state + */ + updatePasswordField_: function(pod, state) { + FINGERPRINT_STATES_MAPPING.forEach(function(item) { + pod.passwordElement.classList.toggle(item.class, state == item.state); + }); + var placeholderStr = loadTimeData.getString( + pod.isPinShown() ? 'pinKeyboardPlaceholderPinPassword' : + 'passwordHint'); + if (state == FINGERPRINT_STATES.SIGNIN) { + placeholderStr = loadTimeData.getString('fingerprintSigningin'); + } else if (state == FINGERPRINT_STATES.FAILED) { + placeholderStr = loadTimeData.getString('fingerprintSigninFailed'); + } + pod.passwordElement.placeholder = placeholderStr; }, /** @@ -3308,6 +3513,8 @@ pod.isActionBoxMenuHovered = false; pod.classList.remove('focused'); pod.setPinVisibility(false); + this.setUserPodFingerprintIcon( + pod.user.username, FINGERPRINT_STATES.HIDDEN); // On Desktop, the faded style is not set correctly, so we should // manually fade out non-focused pods if there is a focused pod. if (pod.user.isDesktopUser && podToFocus) @@ -3347,6 +3554,8 @@ this.firstShown_ = false; this.lastFocusedPod_ = podToFocus; this.scrollFocusedPodIntoView(); + this.setUserPodFingerprintIcon( + podToFocus.user.username, FINGERPRINT_STATES.DEFAULT); } else { chrome.send('noPodFocused'); }
diff --git a/ui/login/account_picker/user_pod_template.html b/ui/login/account_picker/user_pod_template.html index d09d3cd..25948b4 100644 --- a/ui/login/account_picker/user_pod_template.html +++ b/ui/login/account_picker/user_pod_template.html
@@ -46,6 +46,12 @@ <div class="auth-container"> <!-- Password Authentication --> <div class="custom-icon-container" hidden></div> +<if expr="chromeos"> + <div class="fingerprint-icon-container" hidden + i18n-values="aria-label:fingerprintIconMessage"> + <div class="custom-icon fingerprint-icon-image"></div> + </div> +</if> <div class="password-entry-container"> <div class="password-container"> <input type="password" class="password"
diff --git a/ui/views/mus/desktop_window_tree_host_mus.cc b/ui/views/mus/desktop_window_tree_host_mus.cc index 6efc8ff..c991bfc5 100644 --- a/ui/views/mus/desktop_window_tree_host_mus.cc +++ b/ui/views/mus/desktop_window_tree_host_mus.cc
@@ -307,6 +307,8 @@ if (!params.accept_events) { aura::WindowPortMus::Get(window())->SetEventTargetingPolicy( ui::mojom::EventTargetingPolicy::NONE); + } else { + aura::WindowPortMus::Get(content_window)->SetCanAcceptDrops(true); } }
diff --git a/ui/views/mus/mus_client.cc b/ui/views/mus/mus_client.cc index cc3624b..d03fe330 100644 --- a/ui/views/mus/mus_client.cc +++ b/ui/views/mus/mus_client.cc
@@ -18,7 +18,6 @@ #include "ui/aura/env.h" #include "ui/aura/mus/capture_synchronizer.h" #include "ui/aura/mus/mus_context_factory.h" -#include "ui/aura/mus/os_exchange_data_provider_mus.h" #include "ui/aura/mus/property_converter.h" #include "ui/aura/mus/window_tree_client.h" #include "ui/aura/mus/window_tree_host_mus.h" @@ -112,8 +111,6 @@ clipboard->Init(connector); ui::Clipboard::SetClipboardForCurrentThread(std::move(clipboard)); - ui::OSExchangeDataProviderFactory::SetFactory(this); - ViewsDelegate::GetInstance()->set_native_widget_factory( base::Bind(&MusClient::CreateNativeWidget, base::Unretained(this))); } @@ -297,8 +294,4 @@ return nullptr; } -std::unique_ptr<OSExchangeData::Provider> MusClient::BuildProvider() { - return base::MakeUnique<aura::OSExchangeDataProviderMus>(); -} - } // namespace views
diff --git a/ui/views/mus/mus_client.h b/ui/views/mus/mus_client.h index 3e881c5d..829a049 100644 --- a/ui/views/mus/mus_client.h +++ b/ui/views/mus/mus_client.h
@@ -15,7 +15,6 @@ #include "services/service_manager/public/cpp/identity.h" #include "ui/aura/client/capture_client.h" #include "ui/aura/mus/window_tree_client_delegate.h" -#include "ui/base/dragdrop/os_exchange_data_provider_factory.h" #include "ui/views/mus/mus_export.h" #include "ui/views/mus/screen_mus_delegate.h" #include "ui/views/widget/widget.h" @@ -61,10 +60,8 @@ // MusClient establishes a connection to mus and sets up necessary state so that // aura and views target mus. This class is useful for typical clients, not the // WindowManager. Most clients don't create this directly, rather use AuraInit. -class VIEWS_MUS_EXPORT MusClient - : public aura::WindowTreeClientDelegate, - public ScreenMusDelegate, - public ui::OSExchangeDataProviderFactory::Factory { +class VIEWS_MUS_EXPORT MusClient : public aura::WindowTreeClientDelegate, + public ScreenMusDelegate { public: // Most clients should use AuraInit, which creates a MusClient. // |create_wm_state| indicates whether MusClient should create a wm::WMState. @@ -135,9 +132,6 @@ void OnWindowManagerFrameValuesChanged() override; aura::Window* GetWindowAtScreenPoint(const gfx::Point& point) override; - // ui:OSExchangeDataProviderFactory::Factory: - std::unique_ptr<OSExchangeData::Provider> BuildProvider() override; - static MusClient* instance_; service_manager::Identity identity_;
diff --git a/ui/webui/resources/images/fingerprint_default.svg b/ui/webui/resources/images/fingerprint_default.svg new file mode 100644 index 0000000..0be4db1 --- /dev/null +++ b/ui/webui/resources/images/fingerprint_default.svg
@@ -0,0 +1 @@ +<svg width="27" height="27" viewBox="0 0 27 27" xmlns="http://www.w3.org/2000/svg"><title>fingerprint_grey_1x</title><g fill="none" fill-rule="evenodd" opacity=".34"><path d="M20.036 5.03c-.09 0-.174-.024-.26-.063-2.153-1.114-4.026-1.592-6.265-1.592-2.232 0-4.336.534-6.265 1.586-.276.147-.613.052-.765-.224-.146-.275-.05-.613.225-.765 2.098-1.14 4.387-1.72 6.806-1.72 2.398 0 4.49.53 6.785 1.716.276.14.382.483.242.76-.1.19-.298.303-.5.303zM3.937 10.934c-.112 0-.224-.034-.326-.1-.252-.18-.314-.53-.134-.783C4.59 8.477 6.013 7.24 7.7 6.368c3.54-1.83 8.06-1.834 11.605-.012 1.682.867 3.1 2.093 4.22 3.656.18.254.123.602-.13.782-.254.18-.608.124-.788-.13-1.013-1.416-2.295-2.53-3.814-3.306-3.23-1.66-7.352-1.654-10.575.01-1.524.788-2.812 1.908-3.82 3.336-.112.152-.286.23-.46.23zm7.037 13.573c-.146 0-.287-.056-.4-.17-.972-.983-1.5-1.607-2.26-2.963-.777-1.384-1.187-3.077-1.187-4.888 0-3.34 2.857-6.064 6.373-6.064s6.373 2.717 6.373 6.064c0 .31-.253.562-.562.562-.31 0-.562-.254-.562-.563 0-2.723-2.35-4.94-5.248-4.94-2.89 0-5.248 2.217-5.248 4.94 0 1.62.36 3.116 1.04 4.337.726 1.293 1.21 1.85 2.076 2.722.22.22.22.58-.005.793-.102.117-.248.168-.39.168zm8.06-2.08c-1.338 0-2.513-.34-3.486-.997-1.67-1.135-2.672-2.98-2.672-4.938 0-.31.253-.562.562-.562.31 0 .563.253.563.563 0 1.58.816 3.076 2.183 4.005.793.54 1.727.804 2.852.804.27 0 .726-.028 1.176-.107.304-.056.597.152.653.456.056.304-.152.597-.456.653-.658.118-1.215.124-1.372.124zM16.77 24.75c-.05 0-.1-.006-.146-.023-1.794-.49-2.964-1.153-4.18-2.362-1.57-1.564-2.435-3.65-2.435-5.872 0-1.83 1.552-3.314 3.465-3.314 1.912 0 3.465 1.484 3.465 3.313 0 1.203 1.052 2.188 2.34 2.188 1.288 0 2.34-.978 2.34-2.188 0-4.24-3.656-7.69-8.15-7.69-3.2 0-6.12 1.78-7.437 4.535-.44.91-.658 1.974-.658 3.155 0 .878.08 2.262.748 4.056.107.293-.04.613-.332.726-.292.107-.613-.04-.726-.332-.55-1.48-.82-2.93-.82-4.45 0-1.35.258-2.576.77-3.64 1.502-3.138 4.82-5.168 8.45-5.168 5.112 0 9.274 3.954 9.274 8.814 0 1.828-1.558 3.313-3.465 3.313-1.906 0-3.464-1.484-3.464-3.312 0-1.204-1.052-2.188-2.34-2.188-1.288 0-2.34.98-2.34 2.188 0 1.918.748 3.724 2.104 5.074 1.063 1.057 2.098 1.642 3.684 2.076.298.084.478.393.394.69-.067.25-.292.412-.54.412z" fill="#000"/><path d="M0 0h27v27H0"/></g></svg> \ No newline at end of file
diff --git a/ui/webui/resources/images/fingerprint_failed.svg b/ui/webui/resources/images/fingerprint_failed.svg new file mode 100644 index 0000000..314ee0c6 --- /dev/null +++ b/ui/webui/resources/images/fingerprint_failed.svg
@@ -0,0 +1,4 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="#E51C23"> + <path fill="none" d="M0 0h24v24H0V0z"/> + <path d="M11 15h2v2h-2zm0-8h2v6h-2zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/> +</svg>
diff --git a/ui/webui/resources/images/fingerprint_signin.svg b/ui/webui/resources/images/fingerprint_signin.svg new file mode 100644 index 0000000..dc66b50 --- /dev/null +++ b/ui/webui/resources/images/fingerprint_signin.svg
@@ -0,0 +1 @@ +<svg width="27" height="27" viewBox="0 0 27 27" xmlns="http://www.w3.org/2000/svg"><title>fingerprint_blue_1x</title><g fill="none" fill-rule="evenodd"><path d="M20.036 5.03c-.09 0-.174-.024-.26-.063-2.153-1.114-4.026-1.592-6.265-1.592-2.232 0-4.336.534-6.265 1.586-.276.147-.613.052-.765-.224-.146-.275-.05-.613.225-.765 2.098-1.14 4.387-1.72 6.806-1.72 2.398 0 4.49.53 6.785 1.716.276.14.382.483.242.76-.1.19-.298.303-.5.303zM3.937 10.934c-.112 0-.224-.034-.326-.1-.252-.18-.314-.53-.134-.783C4.59 8.477 6.013 7.24 7.7 6.368c3.54-1.83 8.06-1.834 11.605-.012 1.682.867 3.1 2.093 4.22 3.656.18.254.123.602-.13.782-.254.18-.608.124-.788-.13-1.013-1.416-2.295-2.53-3.814-3.306-3.23-1.66-7.352-1.654-10.575.01-1.524.788-2.812 1.908-3.82 3.336-.112.152-.286.23-.46.23zm7.037 13.573c-.146 0-.287-.056-.4-.17-.972-.983-1.5-1.607-2.26-2.963-.777-1.384-1.187-3.077-1.187-4.888 0-3.34 2.857-6.064 6.373-6.064s6.373 2.717 6.373 6.064c0 .31-.253.562-.562.562-.31 0-.562-.254-.562-.563 0-2.723-2.35-4.94-5.248-4.94-2.89 0-5.248 2.217-5.248 4.94 0 1.62.36 3.116 1.04 4.337.726 1.293 1.21 1.85 2.076 2.722.22.22.22.58-.005.793-.102.117-.248.168-.39.168zm8.06-2.08c-1.338 0-2.513-.34-3.486-.997-1.67-1.135-2.672-2.98-2.672-4.938 0-.31.253-.562.562-.562.31 0 .563.253.563.563 0 1.58.816 3.076 2.183 4.005.793.54 1.727.804 2.852.804.27 0 .726-.028 1.176-.107.304-.056.597.152.653.456.056.304-.152.597-.456.653-.658.118-1.215.124-1.372.124zM16.77 24.75c-.05 0-.1-.006-.146-.023-1.794-.49-2.964-1.153-4.18-2.362-1.57-1.564-2.435-3.65-2.435-5.872 0-1.83 1.552-3.314 3.465-3.314 1.912 0 3.465 1.484 3.465 3.313 0 1.203 1.052 2.188 2.34 2.188 1.288 0 2.34-.978 2.34-2.188 0-4.24-3.656-7.69-8.15-7.69-3.2 0-6.12 1.78-7.437 4.535-.44.91-.658 1.974-.658 3.155 0 .878.08 2.262.748 4.056.107.293-.04.613-.332.726-.292.107-.613-.04-.726-.332-.55-1.48-.82-2.93-.82-4.45 0-1.35.258-2.576.77-3.64 1.502-3.138 4.82-5.168 8.45-5.168 5.112 0 9.274 3.954 9.274 8.814 0 1.828-1.558 3.313-3.465 3.313-1.906 0-3.464-1.484-3.464-3.312 0-1.204-1.052-2.188-2.34-2.188-1.288 0-2.34.98-2.34 2.188 0 1.918.748 3.724 2.104 5.074 1.063 1.057 2.098 1.642 3.684 2.076.298.084.478.393.394.69-.067.25-.292.412-.54.412z" fill="#4285F4"/><path d="M0 0h27v27H0"/></g></svg> \ No newline at end of file