1 // Copyright 2017 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.chrome.browser.firstrun; 6 7 import android.os.Bundle; 8 import android.view.LayoutInflater; 9 import android.view.View; 10 import android.view.ViewGroup; 11 import android.view.accessibility.AccessibilityEvent; 12 import android.widget.Button; 13 14 import androidx.fragment.app.Fragment; 15 16 import org.chromium.base.metrics.RecordUserAction; 17 import org.chromium.base.task.PostTask; 18 import org.chromium.chrome.R; 19 import org.chromium.chrome.browser.locale.DefaultSearchEngineDialogHelper; 20 import org.chromium.chrome.browser.locale.LocaleManager; 21 import org.chromium.chrome.browser.locale.LocaleManager.SearchEnginePromoType; 22 import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory; 23 import org.chromium.components.browser_ui.widget.RadioButtonLayout; 24 import org.chromium.content_public.browser.UiThreadTaskTraits; 25 26 /** A {@link Fragment} that presents a set of search engines for the user to choose from. */ 27 public class DefaultSearchEngineFirstRunFragment extends Fragment implements FirstRunFragment { 28 /** FRE page that instantiates this fragment. */ 29 public static class Page implements FirstRunPage<DefaultSearchEngineFirstRunFragment> { 30 @Override instantiateFragment()31 public DefaultSearchEngineFirstRunFragment instantiateFragment() { 32 return new DefaultSearchEngineFirstRunFragment(); 33 } 34 } 35 36 @SearchEnginePromoType 37 private int mSearchEnginePromoDialoType; 38 private boolean mShownRecorded; 39 40 /** Layout that displays the available search engines to the user. */ 41 private RadioButtonLayout mEngineLayout; 42 43 /** The button that lets a user proceed to the next page after an engine is selected. */ 44 private Button mButton; 45 46 @Override onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)47 public View onCreateView( 48 LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 49 View rootView = inflater.inflate( 50 R.layout.default_search_engine_first_run_fragment, container, false); 51 mEngineLayout = (RadioButtonLayout) rootView.findViewById( 52 R.id.default_search_engine_dialog_options); 53 mButton = (Button) rootView.findViewById(R.id.button_primary); 54 mButton.setEnabled(false); 55 56 assert TemplateUrlServiceFactory.get().isLoaded(); 57 mSearchEnginePromoDialoType = LocaleManager.getInstance().getSearchEnginePromoShowType(); 58 if (mSearchEnginePromoDialoType != LocaleManager.SearchEnginePromoType.DONT_SHOW) { 59 Runnable dismissRunnable = new Runnable() { 60 @Override 61 public void run() { 62 getPageDelegate().advanceToNextPage(); 63 } 64 }; 65 new DefaultSearchEngineDialogHelper( 66 mSearchEnginePromoDialoType, mEngineLayout, mButton, dismissRunnable); 67 } 68 69 return rootView; 70 } 71 72 @Override setInitialA11yFocus()73 public void setInitialA11yFocus() { 74 // Ignore calls before view is created. 75 if (getView() == null) return; 76 77 final View title = getView().findViewById(R.id.chooser_title); 78 title.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED); 79 } 80 81 @Override setUserVisibleHint(boolean isVisibleToUser)82 public void setUserVisibleHint(boolean isVisibleToUser) { 83 super.setUserVisibleHint(isVisibleToUser); 84 85 if (isVisibleToUser) { 86 if (mSearchEnginePromoDialoType == LocaleManager.SearchEnginePromoType.DONT_SHOW) { 87 PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { 88 @Override 89 public void run() { 90 getPageDelegate().advanceToNextPage(); 91 } 92 }); 93 } 94 95 recordShown(); 96 } 97 } 98 recordShown()99 private void recordShown() { 100 if (mShownRecorded) return; 101 102 if (mSearchEnginePromoDialoType == LocaleManager.SearchEnginePromoType.SHOW_NEW) { 103 RecordUserAction.record("SearchEnginePromo.NewDevice.Shown.FirstRun"); 104 } else if (mSearchEnginePromoDialoType 105 == LocaleManager.SearchEnginePromoType.SHOW_EXISTING) { 106 RecordUserAction.record("SearchEnginePromo.ExistingDevice.Shown.FirstRun"); 107 } 108 109 mShownRecorded = true; 110 } 111 } 112