Skip to content

Commit

Permalink
Reland "Add weblayer browser_tests APK so we can run the tests on And…
Browse files Browse the repository at this point in the history
…roid."

This is a reland of aaa2ec5 with fix from patchset 1 to 2 due to conflict with r702520.

Original change's description:
> Add weblayer browser_tests APK so we can run the tests on Android.
>
> The Shell C++ class isn't used on Android (unlike in content_shell) because we want to consume WebLayer there using the idiomatic Java API. At the same time, we want to write browser tests the same way for all platforms. So fake this by creating a Shell that reuses the existing BrowserController class that was created by Java.
>
> Change-Id: I946957f39eb79cff2e84c8abda56eed98b28d0a0
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1815884
> Reviewed-by: Clark DuVall <cduvall@chromium.org>
> Commit-Queue: John Abd-El-Malek <jam@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#702563}

TBR=cduvall@chromium.org

Change-Id: I425b7b15d9f742a25a5b7c9dd306067ca29e551b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1838953
Reviewed-by: John Abd-El-Malek <jam@chromium.org>
Commit-Queue: John Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#702657}
  • Loading branch information
John Abd-El-Malek authored and Commit Bot committed Oct 4, 2019
1 parent 5e9020f commit 4a9ab59
Show file tree
Hide file tree
Showing 16 changed files with 394 additions and 16 deletions.
10 changes: 4 additions & 6 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,10 @@ group("gn_all") {
}

if (is_win || (is_linux && !is_chromeos) || is_android) {
deps += [ "//weblayer/shell:weblayer_shell" ]
}

# TODO: enable this on Android.
if (is_win || (is_linux && !is_chromeos)) {
deps += [ "//weblayer/test:weblayer_browsertests" ]
deps += [
"//weblayer/shell:weblayer_shell",
"//weblayer/test:weblayer_browsertests",
]
}

if (!is_ios && !is_android) {
Expand Down
5 changes: 5 additions & 0 deletions build/android/pylib/constants/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@
chrome.PackageInfo('org.chromium.webview_ui_test',
'org.chromium.webview_ui_test.WebViewUiTestActivity',
'webview-command-line', None),
'weblayer_browsertests':
chrome.PackageInfo(
'org.chromium.weblayer_browsertests_apk',
'org.chromium.weblayer_browsertests_apk.WebLayerBrowserTestsActivity',
'chrome-native-tests-command-line', None),
})


Expand Down
1 change: 1 addition & 0 deletions testing/android/native_test/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ android_library("native_test_java") {
"//base:base_java",
"//base:base_java_test_support",
"//testing/android/reporter:reporter_java",
"//third_party/android_deps:android_support_v4_java",
]
java_files = [
"java/src/org/chromium/native_test/NativeBrowserTest.java",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@

package org.chromium.native_test;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

import java.io.File;

/**
* An {@link android.app.Activity} for running native browser tests.
*/
public abstract class NativeBrowserTestActivity extends Activity {
public abstract class NativeBrowserTestActivity extends FragmentActivity {
private static final String TAG = "cr_NativeTest";

private NativeTest mTest = new NativeTest();
Expand Down
17 changes: 17 additions & 0 deletions weblayer/browser/browser_controller_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,19 @@

namespace weblayer {

namespace {

#if defined(OS_ANDROID)
BrowserController* g_last_browser_controller;
#endif

} // namespace

BrowserControllerImpl::BrowserControllerImpl(ProfileImpl* profile)
: profile_(profile) {
#if defined(OS_ANDROID)
g_last_browser_controller = this;
#endif
content::WebContents::CreateParams create_params(
profile_->GetBrowserContext());
web_contents_ = content::WebContents::Create(create_params);
Expand Down Expand Up @@ -150,4 +161,10 @@ std::unique_ptr<BrowserController> BrowserController::Create(Profile* profile) {
static_cast<ProfileImpl*>(profile));
}

#if defined(OS_ANDROID)
BrowserController* BrowserController::GetLastControllerForTesting() {
return g_last_browser_controller;
}
#endif

} // namespace weblayer
4 changes: 4 additions & 0 deletions weblayer/public/browser_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ class BrowserController {
public:
static std::unique_ptr<BrowserController> Create(Profile* profile);

#if defined(OS_ANDROID)
static BrowserController* GetLastControllerForTesting();
#endif

virtual ~BrowserController() {}

virtual void AddObserver(BrowserObserver* observer) = 0;
Expand Down
1 change: 1 addition & 0 deletions weblayer/shell/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jumbo_static_library("weblayer_shell_lib") {
"app/shell_main_params.h",
"browser/shell.cc",
"browser/shell.h",
"browser/shell_android.cc",
"common/shell_switches.cc",
"common/shell_switches.h",
]
Expand Down
42 changes: 42 additions & 0 deletions weblayer/shell/android/browsertests_apk/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>

<!-- Copyright 2019 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.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.chromium.weblayer_browsertests_apk">

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<application android:name="WebLayerBrowserTestsApplication" android:label="WebLayerBrowserTests">
<activity android:name="WebLayerBrowserTestsActivity"
android:launchMode="singleTask"
android:theme="@android:style/Theme.Holo.Light.NoActionBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
android:windowSoftInputMode="adjustPan|stateUnspecified">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

<meta-data android:name="org.chromium.weblayer.WebLayerPackage"
android:value="org.chromium.weblayer_browsertests_apk"/>
</application>

<instrumentation android:name="org.chromium.native_test.NativeTestInstrumentationTestRunner"
android:label="WebLayerBrowserTests"
android:targetPackage="org.chromium.weblayer_browsertests_apk"
chromium-junit3="true"/>
</manifest>
6 changes: 6 additions & 0 deletions weblayer/shell/android/browsertests_apk/DEPS
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
include_rules = [
"+content/public/android",
"+content/public/app",
"+content/public/test",
"+ui/android",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.weblayer_browsertests_apk;

import android.net.Uri;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.base.test.util.UrlUtils;
import org.chromium.content_public.browser.BrowserStartupController;
import org.chromium.native_test.NativeBrowserTest;
import org.chromium.native_test.NativeBrowserTestActivity;
import org.chromium.weblayer.BrowserController;
import org.chromium.weblayer.BrowserFragmentController;
import org.chromium.weblayer.BrowserObserver;
import org.chromium.weblayer.ListenableFuture;
import org.chromium.weblayer.Profile;
import org.chromium.weblayer.WebLayer;

import java.io.File;

/** An Activity base class for running browser tests against WebLayerShell. */
public class WebLayerBrowserTestsActivity extends NativeBrowserTestActivity {
private static final String TAG = "cr.native_test";

private WebLayer mWebLayer;
private Profile mProfile;
private BrowserFragmentController mBrowserFragmentController;
private BrowserController mBrowserController;
private EditText mUrlView;
private View mMainView;

@Override
protected void onDestroy() {
if (mProfile != null) mProfile.destroy();
if (mBrowserFragmentController != null) mBrowserFragmentController.destroy();
super.onDestroy();
}

@Override
protected void initializeBrowserProcess() {
BrowserStartupController.get(LibraryProcessType.PROCESS_WEBLAYER)
.setContentMainCallbackForTests(() -> {
// This jumps into C++ to set up and run the test harness. The test harness runs
// ContentMain()-equivalent code, and then waits for javaStartupTasksComplete()
// to be called.
runTests();
});

try {
ListenableFuture<WebLayer> future = WebLayer.create(getApplication());
future.addCallback((WebLayer webLayer) -> {
mWebLayer = webLayer;
createShell();
});
} catch (Exception e) {
throw new RuntimeException("failed loading WebLayer", e);
}

NativeBrowserTest.javaStartupTasksComplete();
}

protected void createShell() {
LinearLayout mainView = new LinearLayout(this);
int viewId = View.generateViewId();
mainView.setId(viewId);
mMainView = mainView;
setContentView(mainView);

mUrlView = new EditText(this);
mUrlView.setId(View.generateViewId());
// The background of the top-view must be opaque, otherwise it bleeds through to the
// cc::Layer that mirrors the contents of the top-view.
mUrlView.setBackgroundColor(0xFFa9a9a9);

RelativeLayout topContentsContainer = new RelativeLayout(this);
topContentsContainer.addView(mUrlView,
new RelativeLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));

mProfile = mWebLayer.createProfile(null);

mBrowserFragmentController = mProfile.createBrowserFragmentController(this);

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(viewId, mBrowserFragmentController.getFragment());
transaction.commit();

mBrowserFragmentController.setTopView(topContentsContainer);

mBrowserController = mBrowserFragmentController.getBrowserController();
mBrowserController.addObserver(new BrowserObserver() {
@Override
public void visibleUrlChanged(Uri uri) {
mUrlView.setText(uri.toString());
}
});
}

@Override
protected File getPrivateDataDirectory() {
return new File(UrlUtils.getIsolatedTestRoot(),
WebLayerBrowserTestsApplication.PRIVATE_DATA_DIRECTORY_SUFFIX);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.weblayer_browsertests_apk;

import android.content.Context;

import org.chromium.base.PathUtils;
import org.chromium.native_test.NativeBrowserTestApplication;
import org.chromium.ui.base.ResourceBundle;

/**
* A basic weblayer_public.browser.tests {@link android.app.Application}.
*/
public class WebLayerBrowserTestsApplication extends NativeBrowserTestApplication {
static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "weblayer_shell";

@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);

if (isBrowserProcess()) {
// Test-only stuff, see also NativeUnitTest.java.
PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX);
ResourceBundle.setNoAvailableLocalePaks();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2019 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 <memory>

#include "base/android/jni_android.h"
#include "base/android/library_loader/library_loader_hooks.h"
#include "base/bind.h"
#include "base/message_loop/message_pump.h"
#include "content/public/app/content_jni_onload.h"
#include "content/public/app/content_main.h"
#include "content/public/test/nested_message_pump_android.h"
#include "testing/android/native_test/native_test_launcher.h"
#include "weblayer/app/content_main_delegate_impl.h"
#include "weblayer/shell/app/shell_main_params.h"

// This is called by the VM when the shared library is first loaded.
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
base::android::InitVM(vm);
if (!content::android::OnJNIOnLoadInit())
return -1;

// This needs to be done before base::TestSuite::Initialize() is called,
// as it also tries to set MessagePumpForUIFactory.
base::MessagePump::OverrideMessagePumpForUIFactory(
[]() -> std::unique_ptr<base::MessagePump> {
return std::make_unique<content::NestedMessagePumpAndroid>();
});

content::SetContentMainDelegate(
new weblayer::ContentMainDelegateImpl(weblayer::CreateMainParams()));
return JNI_VERSION_1_4;
}
Loading

0 comments on commit 4a9ab59

Please sign in to comment.