diff options
Diffstat (limited to 'chromium/weblayer/shell/android')
10 files changed, 239 insertions, 43 deletions
diff --git a/chromium/weblayer/shell/android/BUILD.gn b/chromium/weblayer/shell/android/BUILD.gn index bc3a270505f..5a6d1f7ff78 100644 --- a/chromium/weblayer/shell/android/BUILD.gn +++ b/chromium/weblayer/shell/android/BUILD.gn @@ -203,7 +203,7 @@ android_apk("weblayer_support_apk") { rebase_path("$root_gen_dir/CHROME_VERSION.json", root_build_dir) native_lib_version_arg = "@FileArg($_native_lib_file:full-quoted)" - shared_libraries = [ "//weblayer:libweblayer" ] + shared_libraries = [ "//weblayer:libweblayer_test" ] } python_library("weblayer_shell_wpt") { diff --git a/chromium/weblayer/shell/android/browsertests_apk/metrics_browsertest.cc b/chromium/weblayer/shell/android/browsertests_apk/metrics_browsertest.cc index 30ff1b25e2c..a4f0af9ae89 100644 --- a/chromium/weblayer/shell/android/browsertests_apk/metrics_browsertest.cc +++ b/chromium/weblayer/shell/android/browsertests_apk/metrics_browsertest.cc @@ -4,33 +4,51 @@ #include <deque> -#include "base/android/jni_android.h" #include "base/command_line.h" +#include "base/metrics/metrics_hashes.h" +#include "base/metrics/statistics_recorder.h" #include "base/no_destructor.h" #include "base/test/bind_test_util.h" +#include "components/metrics/log_decoder.h" +#include "components/metrics/metrics_log_uploader.h" #include "components/metrics/metrics_switches.h" +#include "content/public/test/browser_test_utils.h" #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h" #include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h" #include "weblayer/browser/profile_impl.h" #include "weblayer/public/navigation_controller.h" #include "weblayer/public/profile.h" #include "weblayer/public/tab.h" +#include "weblayer/shell/android/browsertests_apk/metrics_test_helper.h" #include "weblayer/shell/browser/shell.h" #include "weblayer/test/weblayer_browser_test.h" -#include "weblayer/test/weblayer_browsertests_jni/MetricsTestHelper_jni.h" +#include "weblayer/test/weblayer_browser_test_utils.h" namespace weblayer { +namespace { + +bool HasHistogramWithHash(const metrics::ChromeUserMetricsExtension& uma_log, + uint64_t hash) { + for (int i = 0; i < uma_log.histogram_event_size(); ++i) { + if (uma_log.histogram_event(i).name_hash() == hash) { + return true; + } + } + return false; +} + +} // namespace + class MetricsBrowserTest : public WebLayerBrowserTest { public: void SetUp() override { - instance_ = this; - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); command_line->AppendSwitch(metrics::switches::kForceEnableMetricsReporting); - Java_MetricsTestHelper_installTestGmsBridge( - base::android::AttachCurrentThread(), HasUserConsent()); + InstallTestGmsBridge(HasUserConsent(), + base::BindRepeating(&MetricsBrowserTest::OnLogMetrics, + base::Unretained(this))); WebLayerMetricsServiceClient::GetInstance()->SetFastStartupForTesting(true); WebLayerMetricsServiceClient::GetInstance()->SetUploadIntervalForTesting( base::TimeDelta::FromMilliseconds(10)); @@ -38,20 +56,17 @@ class MetricsBrowserTest : public WebLayerBrowserTest { } void TearDown() override { - Java_MetricsTestHelper_removeTestGmsBridge( - base::android::AttachCurrentThread()); - instance_ = nullptr; + RemoveTestGmsBridge(); WebLayerBrowserTest::TearDown(); } - static void OnLogMetrics(const metrics::ChromeUserMetricsExtension& metric) { - if (!instance_) - return; - instance_->metrics_logs_.push_back(metric); - std::move(instance_->on_new_log_).Run(); + void OnLogMetrics(metrics::ChromeUserMetricsExtension metric) { + metrics_logs_.push_back(metric); + if (on_new_log_) + std::move(on_new_log_).Run(); } - metrics::ChromeUserMetricsExtension waitForNextMetricsLog() { + metrics::ChromeUserMetricsExtension WaitForNextMetricsLog() { if (metrics_logs_.empty()) { base::RunLoop run_loop; on_new_log_ = run_loop.QuitClosure(); @@ -71,23 +86,10 @@ class MetricsBrowserTest : public WebLayerBrowserTest { std::unique_ptr<Profile> profile_; std::deque<metrics::ChromeUserMetricsExtension> metrics_logs_; base::OnceClosure on_new_log_; - static MetricsBrowserTest* instance_; }; -MetricsBrowserTest* MetricsBrowserTest::instance_ = nullptr; - -void JNI_MetricsTestHelper_OnLogMetrics( - JNIEnv* env, - const base::android::JavaParamRef<jbyteArray>& data) { - metrics::ChromeUserMetricsExtension proto; - jbyte* src_bytes = env->GetByteArrayElements(data, nullptr); - proto.ParseFromArray(src_bytes, env->GetArrayLength(data.obj())); - env->ReleaseByteArrayElements(data, src_bytes, JNI_ABORT); - MetricsBrowserTest::OnLogMetrics(proto); -} - IN_PROC_BROWSER_TEST_F(MetricsBrowserTest, ProtoHasExpectedFields) { - metrics::ChromeUserMetricsExtension log = waitForNextMetricsLog(); + metrics::ChromeUserMetricsExtension log = WaitForNextMetricsLog(); EXPECT_EQ(metrics::ChromeUserMetricsExtension::ANDROID_WEBLAYER, log.product()); EXPECT_TRUE(log.has_client_id()); @@ -118,7 +120,7 @@ IN_PROC_BROWSER_TEST_F(MetricsBrowserTest, ProtoHasExpectedFields) { } IN_PROC_BROWSER_TEST_F(MetricsBrowserTest, PageLoadsEnableMultipleUploads) { - waitForNextMetricsLog(); + WaitForNextMetricsLog(); // At this point, the MetricsService should be asleep, and should not have // created any more metrics logs. @@ -133,7 +135,7 @@ IN_PROC_BROWSER_TEST_F(MetricsBrowserTest, PageLoadsEnableMultipleUploads) { // This may take slightly longer than UPLOAD_INTERVAL_MS, due to the time // spent processing the metrics log, but should be well within the timeout // (unless something is broken). - waitForNextMetricsLog(); + WaitForNextMetricsLog(); // If we get here, we got a second metrics log (and the test may pass). If // there was no second metrics log, then the above call will check fail with a @@ -143,6 +145,35 @@ IN_PROC_BROWSER_TEST_F(MetricsBrowserTest, PageLoadsEnableMultipleUploads) { // might potentially have a third metrics log in the queue. } +IN_PROC_BROWSER_TEST_F(MetricsBrowserTest, RendererHistograms) { + base::HistogramTester histogram_tester; + ASSERT_TRUE(embedded_test_server()->Start()); + + NavigateAndWaitForCompletion( + embedded_test_server()->GetURL("/simple_page.html"), shell()); + + uint64_t hash = base::HashMetricName("Android.SeccompStatus.RendererSandbox"); + + bool collect_final_metrics_for_log_called = false; + + WebLayerMetricsServiceClient::GetInstance() + ->SetCollectFinalMetricsForLogClosureForTesting( + base::BindLambdaForTesting( + [&]() { collect_final_metrics_for_log_called = true; })); + + // Not every WaitForNextMetricsLog call will end up calling + // MetricsServiceClient::CollectFinalMetricsForLog since there may already be + // staged logs to send (see ReportingService::SendNextLog). Since we need to + // wait for CollectFinalMetricsForLog to be run after the navigate call above, + // keep calling WaitForNextMetricsLog until CollectFinalMetricsForLog is + // called. + metrics::ChromeUserMetricsExtension uma_log; + while (!collect_final_metrics_for_log_called) + uma_log = WaitForNextMetricsLog(); + + ASSERT_TRUE(HasHistogramWithHash(uma_log, hash)); +} + class MetricsBrowserTestWithUserOptOut : public MetricsBrowserTest { bool HasUserConsent() override { return false; } }; diff --git a/chromium/weblayer/shell/android/browsertests_apk/metrics_test_helper.cc b/chromium/weblayer/shell/android/browsertests_apk/metrics_test_helper.cc new file mode 100644 index 00000000000..5b78584f5a1 --- /dev/null +++ b/chromium/weblayer/shell/android/browsertests_apk/metrics_test_helper.cc @@ -0,0 +1,61 @@ +// Copyright 2020 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 "weblayer/shell/android/browsertests_apk/metrics_test_helper.h" + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "base/no_destructor.h" +#include "weblayer/test/weblayer_browsertests_jni/MetricsTestHelper_jni.h" + +namespace weblayer { + +namespace { + +OnLogsMetricsCallback& GetOnLogMetricsCallback() { + static base::NoDestructor<OnLogsMetricsCallback> s_callback; + return *s_callback; +} + +} // namespace + +void InstallTestGmsBridge(bool has_user_consent, + const OnLogsMetricsCallback on_log_metrics) { + GetOnLogMetricsCallback() = on_log_metrics; + Java_MetricsTestHelper_installTestGmsBridge( + base::android::AttachCurrentThread(), has_user_consent); +} + +void RemoveTestGmsBridge() { + Java_MetricsTestHelper_removeTestGmsBridge( + base::android::AttachCurrentThread()); + GetOnLogMetricsCallback().Reset(); +} + +void CreateProfile(const std::string& name) { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_MetricsTestHelper_createProfile( + env, base::android::ConvertUTF8ToJavaString(env, name)); +} +void DestroyProfile(const std::string& name) { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_MetricsTestHelper_destroyProfile( + env, base::android::ConvertUTF8ToJavaString(env, name)); +} + +void JNI_MetricsTestHelper_OnLogMetrics( + JNIEnv* env, + const base::android::JavaParamRef<jbyteArray>& data) { + auto& callback = GetOnLogMetricsCallback(); + if (!callback) + return; + + metrics::ChromeUserMetricsExtension proto; + jbyte* src_bytes = env->GetByteArrayElements(data, nullptr); + proto.ParseFromArray(src_bytes, env->GetArrayLength(data.obj())); + env->ReleaseByteArrayElements(data, src_bytes, JNI_ABORT); + callback.Run(proto); +} + +} // namespace weblayer diff --git a/chromium/weblayer/shell/android/browsertests_apk/metrics_test_helper.h b/chromium/weblayer/shell/android/browsertests_apk/metrics_test_helper.h new file mode 100644 index 00000000000..6c54134cbcc --- /dev/null +++ b/chromium/weblayer/shell/android/browsertests_apk/metrics_test_helper.h @@ -0,0 +1,36 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBLAYER_SHELL_ANDROID_BROWSERTESTS_APK_METRICS_TEST_HELPER_H_ +#define WEBLAYER_SHELL_ANDROID_BROWSERTESTS_APK_METRICS_TEST_HELPER_H_ + +#include <string> + +#include "base/callback.h" +#include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h" + +namespace weblayer { + +// Various utilities to bridge to Java code for metrics related tests. + +using OnLogsMetricsCallback = + base::RepeatingCallback<void(metrics::ChromeUserMetricsExtension)>; + +// Call this in the SetUp() test harness method to install the test +// GmsBridge and to set the metrics user consent state. +void InstallTestGmsBridge( + bool has_user_consent, + const OnLogsMetricsCallback on_log_metrics = OnLogsMetricsCallback()); + +// Call this in the TearDown() test harness method to remove the GmsBridge. +void RemoveTestGmsBridge(); + +// See Profile::Create()'s comments for the semantics of |name|. +void CreateProfile(const std::string& name); + +void DestroyProfile(const std::string& name); + +} // namespace weblayer + +#endif // WEBLAYER_SHELL_ANDROID_BROWSERTESTS_APK_METRICS_TEST_HELPER_H_ diff --git a/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsActivity.java b/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsActivity.java index 4837ddac429..ecc26c1f6ca 100644 --- a/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsActivity.java +++ b/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsActivity.java @@ -14,11 +14,14 @@ import android.widget.RelativeLayout; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentTransaction; +import org.chromium.base.CommandLine; 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.Browser; +import org.chromium.weblayer.NewTabCallback; +import org.chromium.weblayer.NewTabType; import org.chromium.weblayer.Profile; import org.chromium.weblayer.Tab; import org.chromium.weblayer.TabCallback; @@ -50,12 +53,13 @@ public class WebLayerBrowserTestsActivity extends NativeBrowserTestActivity { WebLayer.loadAsync(getApplication(), webLayer -> { mWebLayer = webLayer; createShell(); + + NativeBrowserTest.javaStartupTasksComplete(); }); } catch (Exception e) { throw new RuntimeException("failed loading WebLayer", e); } - NativeBrowserTest.javaStartupTasksComplete(); } protected void createShell() { @@ -76,7 +80,10 @@ public class WebLayerBrowserTestsActivity extends NativeBrowserTestActivity { new RelativeLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); - Fragment fragment = WebLayer.createBrowserFragment("BrowserTestProfile"); + CommandLine commandLine = CommandLine.getInstance(); + String path = (commandLine.hasSwitch("start-in-incognito")) ? null : "BrowserTestProfile"; + + Fragment fragment = WebLayer.createBrowserFragment(path); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.add(viewId, fragment); @@ -93,6 +100,14 @@ public class WebLayerBrowserTestsActivity extends NativeBrowserTestActivity { mUrlView.setText(uri.toString()); } }); + // Set a new tab callback to make sure popups are added. + mTab.setNewTabCallback(new NewTabCallback() { + @Override + public void onNewTab(Tab tab, @NewTabType int type) {} + + @Override + public void onCloseTab() {} + }); } @Override diff --git a/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/MetricsTestHelper.java b/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/MetricsTestHelper.java index 41affaaf8ab..c89b0e38793 100644 --- a/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/MetricsTestHelper.java +++ b/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/MetricsTestHelper.java @@ -4,11 +4,16 @@ package org.chromium.weblayer_private; +import android.content.Context; +import android.text.TextUtils; + import org.chromium.base.Callback; +import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; +import org.chromium.weblayer.WebLayer; /** * Helper for metrics_browsertest.cc @@ -50,6 +55,26 @@ class MetricsTestHelper { } @CalledByNative + private static void createProfile(String name) { + Context appContext = ContextUtils.getApplicationContext(); + WebLayer weblayer = WebLayer.loadSync(appContext); + + String nameOrNull = null; + if (!TextUtils.isEmpty(name)) nameOrNull = name; + weblayer.getProfile(nameOrNull); + } + + @CalledByNative + private static void destroyProfile(String name) { + Context appContext = ContextUtils.getApplicationContext(); + WebLayer weblayer = WebLayer.loadSync(appContext); + + String nameOrNull = null; + if (!TextUtils.isEmpty(name)) nameOrNull = name; + weblayer.getProfile(nameOrNull).destroy(); + } + + @CalledByNative private static void removeTestGmsBridge() { GmsBridge.injectInstance(null); } diff --git a/chromium/weblayer/shell/android/shell_apk/AndroidManifest.xml b/chromium/weblayer/shell/android/shell_apk/AndroidManifest.xml index fabe6849287..83ab34ddbd4 100644 --- a/chromium/weblayer/shell/android/shell_apk/AndroidManifest.xml +++ b/chromium/weblayer/shell/android/shell_apk/AndroidManifest.xml @@ -9,7 +9,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.chromium.weblayer.shell"> - <application android:label="WebLayer shell"> + <application android:label="WebLayer shell" + android:supportsRtl="true"> <activity android:name="WebLayerShellActivity" android:launchMode="singleTask" android:theme="@style/ShellTheme" diff --git a/chromium/weblayer/shell/android/shell_apk/res/layout/shell_browser_controls.xml b/chromium/weblayer/shell/android/shell_apk/res/layout/shell_browser_controls.xml index a07648248cc..f0f01f50784 100644 --- a/chromium/weblayer/shell/android/shell_apk/res/layout/shell_browser_controls.xml +++ b/chromium/weblayer/shell/android/shell_apk/res/layout/shell_browser_controls.xml @@ -28,6 +28,7 @@ android:imeOptions="actionGo" android:layout_width="match_parent" android:layout_height="match_parent" + android:importantForAutofill="no" android:textSize="15sp"/> <View diff --git a/chromium/weblayer/shell/android/shell_apk/res/menu/app_menu.xml b/chromium/weblayer/shell/android/shell_apk/res/menu/app_menu.xml index 02821be9b0f..2d6ff129de0 100644 --- a/chromium/weblayer/shell/android/shell_apk/res/menu/app_menu.xml +++ b/chromium/weblayer/shell/android/shell_apk/res/menu/app_menu.xml @@ -17,4 +17,6 @@ android:title="Bottom view" /> <item android:id="@+id/site_settings_menu_id" android:title="Site Settings" /> + <item android:id="@+id/translate_menu_id" + android:title="Translate" /> </menu> diff --git a/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java b/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java index bb67a110ab9..fa140357af6 100644 --- a/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java +++ b/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java @@ -4,6 +4,7 @@ package org.chromium.weblayer.shell; +import android.app.Activity; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; @@ -19,6 +20,7 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.view.WindowManager; +import android.webkit.URLUtil; import android.widget.EditText; import android.widget.ImageButton; import android.widget.LinearLayout; @@ -32,6 +34,7 @@ import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; +import org.chromium.base.CommandLine; import org.chromium.base.IntentUtils; import org.chromium.weblayer.Browser; import org.chromium.weblayer.ContextMenuParams; @@ -43,6 +46,7 @@ import org.chromium.weblayer.NavigationController; import org.chromium.weblayer.NewTabCallback; import org.chromium.weblayer.NewTabType; import org.chromium.weblayer.Profile; +import org.chromium.weblayer.SettingType; import org.chromium.weblayer.SiteSettingsActivity; import org.chromium.weblayer.Tab; import org.chromium.weblayer.TabCallback; @@ -58,7 +62,7 @@ import java.util.List; * Activity for managing the Demo Shell. */ public class WebLayerShellActivity extends FragmentActivity { - private static final String PROFILE_NAME = "DefaultProfile"; + private static final String NON_INCOGNITO_PROFILE_NAME = "DefaultProfile"; private static class ContextMenuCreator implements View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener { @@ -133,6 +137,7 @@ public class WebLayerShellActivity extends FragmentActivity { private List<Tab> mPreviousTabList = new ArrayList<>(); private Runnable mExitFullscreenRunnable; private View mBottomView; + private boolean mInIncognitoMode; @Override protected void onCreate(final Bundle savedInstanceState) { @@ -173,6 +178,9 @@ public class WebLayerShellActivity extends FragmentActivity { popup.getMenuInflater().inflate(R.menu.app_menu, popup.getMenu()); MenuItem bottomMenuItem = popup.getMenu().findItem(R.id.toggle_bottom_view_id); bottomMenuItem.setChecked(mBottomView != null); + popup.getMenu() + .findItem(R.id.translate_menu_id) + .setVisible(mBrowser.getActiveTab().canTranslate()); popup.setOnMenuItemClickListener(item -> { if (item.getItemId() == R.id.reload_menu_id) { mBrowser.getActiveTab().getNavigationController().reload(); @@ -205,12 +213,20 @@ public class WebLayerShellActivity extends FragmentActivity { } if (item.getItemId() == R.id.site_settings_menu_id) { - Intent intent = - SiteSettingsActivity.createIntentForCategoryList(this, PROFILE_NAME); + // TODO(crbug.com/1083233): Figure out the right long-term behavior here. + if (mInIncognitoMode) return true; + + Intent intent = SiteSettingsActivity.createIntentForCategoryList( + this, NON_INCOGNITO_PROFILE_NAME); IntentUtils.safeStartActivity(this, intent); return true; } + if (item.getItemId() == R.id.translate_menu_id) { + mBrowser.getActiveTab().showTranslateUi(); + return true; + } + return false; }); popup.show(); @@ -254,6 +270,7 @@ public class WebLayerShellActivity extends FragmentActivity { fragment.setRetainInstance(true); mBrowser = Browser.fromFragment(fragment); mProfile = mBrowser.getProfile(); + mProfile.setBooleanSetting(SettingType.UKM_ENABLED, true); setTabCallbacks(mBrowser.getActiveTab(), fragment); mBrowser.setTopView(mTopContentsContainer); @@ -287,7 +304,7 @@ public class WebLayerShellActivity extends FragmentActivity { return; } String startupUrl = getUrlFromIntent(getIntent()); - if (TextUtils.isEmpty(startupUrl)) { + if (TextUtils.isEmpty(startupUrl) || !URLUtil.isValidUrl(startupUrl)) { startupUrl = "https://google.com"; } loadUrl(startupUrl); @@ -380,10 +397,10 @@ public class WebLayerShellActivity extends FragmentActivity { public void bringTabToFront() { tab.getBrowser().setActiveTab(tab); - Context context = WebLayerShellActivity.this; - Intent intent = new Intent(context, WebLayerShellActivity.class); + Activity activity = WebLayerShellActivity.this; + Intent intent = new Intent(activity, WebLayerShellActivity.class); intent.setAction(Intent.ACTION_MAIN); - context.getApplicationContext().startActivity(intent); + activity.startActivity(intent); } }); tab.getNavigationController().registerNavigationCallback(new NavigationCallback() { @@ -427,7 +444,14 @@ public class WebLayerShellActivity extends FragmentActivity { } } - Fragment fragment = WebLayer.createBrowserFragment(PROFILE_NAME); + if (CommandLine.isInitialized() + && CommandLine.getInstance().hasSwitch("start-in-incognito")) { + mInIncognitoMode = true; + } + + String profileName = mInIncognitoMode ? null : NON_INCOGNITO_PROFILE_NAME; + + Fragment fragment = WebLayer.createBrowserFragment(profileName); FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.add(mMainViewId, fragment); |