Commit 4ca61512 authored by tedchoc's avatar tedchoc Committed by Commit Bot

Ensure promo dialogs are dismissed when activities are destroyed.

BUG=727959

Review-Url: https://codereview.chromium.org/2921453003
Cr-Commit-Position: refs/heads/master@{#476452}
parent ae0d1121
......@@ -5,7 +5,6 @@
package org.chromium.chrome.browser.locale;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.Nullable;
......@@ -22,7 +21,6 @@ import org.chromium.chrome.browser.locale.LocaleManager.SearchEnginePromoType;
import org.chromium.chrome.browser.search_engines.TemplateUrlService;
import org.chromium.chrome.browser.widget.PromoDialog;
import org.chromium.chrome.browser.widget.RadioButtonLayout;
import org.chromium.ui.base.WindowAndroid;
/** A dialog that forces the user to choose a default search engine. */
public class DefaultSearchEnginePromoDialog extends PromoDialog {
......@@ -46,11 +44,11 @@ public class DefaultSearchEnginePromoDialog extends PromoDialog {
* Construct and show the dialog. Will be asynchronous if the TemplateUrlService has not yet
* been loaded.
*
* @param context Context to build the dialog with.
* @param activity Activity to build the dialog with.
* @param dialogType Type of dialog to show.
* @param onDismissed Notified about whether the user chose an engine when it got dismissed.
*/
public static void show(final Context context, @SearchEnginePromoType final int dialogType,
public static void show(final Activity activity, @SearchEnginePromoType final int dialogType,
@Nullable final Callback<Boolean> onDismissed) {
assert LibraryLoader.isInitialized();
......@@ -61,21 +59,20 @@ public class DefaultSearchEnginePromoDialog extends PromoDialog {
public void onTemplateUrlServiceLoaded() {
instance.unregisterLoadListener(this);
Activity activity = WindowAndroid.activityFromContext(context);
if (ApplicationStatus.getStateForActivity(activity) == ActivityState.DESTROYED) {
if (onDismissed != null) onDismissed.onResult(false);
return;
}
new DefaultSearchEnginePromoDialog(context, dialogType, onDismissed).show();
new DefaultSearchEnginePromoDialog(activity, dialogType, onDismissed).show();
}
});
if (!instance.isLoaded()) instance.load();
}
private DefaultSearchEnginePromoDialog(
Context context, int dialogType, @Nullable Callback<Boolean> onDismissed) {
super(context);
Activity activity, int dialogType, @Nullable Callback<Boolean> onDismissed) {
super(activity);
mDialogType = dialogType;
mOnDismissed = onDismissed;
setOnDismissListener(this);
......@@ -129,8 +126,8 @@ public class DefaultSearchEnginePromoDialog extends PromoDialog {
@Override
public void onDismiss(DialogInterface dialog) {
if (mHelper.getCurrentlySelectedKeyword() == null) {
// This shouldn't happen, but in case it does, finish the Activity so that the user has
// to respond to the dialog next time.
// If no selection, finish the Activity so that the user has to respond to the dialog
// next time.
if (getOwnerActivity() != null) getOwnerActivity().finish();
}
......
......@@ -4,6 +4,7 @@
package org.chromium.chrome.browser.locale;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
......@@ -208,22 +209,22 @@ public class LocaleManager {
* Shows a promotion dialog about search engines depending on Locale and other conditions.
* See {@link LocaleManager#getSearchEnginePromoShowType()} for possible types and logic.
*
* @param context Context showing the dialog.
* @param activity Activity showing the dialog.
* @param onDismissed Notified when the dialog is dismissed and whether the user acted on it.
* @return Whether such dialog is needed.
*/
public boolean showSearchEnginePromoIfNeeded(
Context context, @Nullable Callback<Boolean> onDismissed) {
Activity activity, @Nullable Callback<Boolean> onDismissed) {
int shouldShow = getSearchEnginePromoShowType();
switch (shouldShow) {
case SEARCH_ENGINE_PROMO_DONT_SHOW:
return false;
case SEARCH_ENGINE_PROMO_SHOW_SOGOU:
new SogouPromoDialog(context, this, onDismissed).show();
new SogouPromoDialog(activity, this, onDismissed).show();
return true;
case SEARCH_ENGINE_PROMO_SHOW_EXISTING:
case SEARCH_ENGINE_PROMO_SHOW_NEW:
DefaultSearchEnginePromoDialog.show(context, shouldShow, onDismissed);
DefaultSearchEnginePromoDialog.show(activity, shouldShow, onDismissed);
return true;
default:
assert false;
......
......@@ -4,7 +4,7 @@
package org.chromium.chrome.browser.locale;
import android.content.Context;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
......@@ -68,9 +68,9 @@ public class SogouPromoDialog extends PromoDialog {
/**
* Creates an instance of the dialog.
*/
public SogouPromoDialog(
Context context, LocaleManager localeManager, @Nullable Callback<Boolean> onDismissed) {
super(context);
public SogouPromoDialog(Activity activity, LocaleManager localeManager,
@Nullable Callback<Boolean> onDismissed) {
super(activity);
mLocaleManager = localeManager;
setOnDismissListener(this);
setCanceledOnTouchOutside(false);
......
......@@ -5,7 +5,6 @@
package org.chromium.chrome.browser.preferences.datareduction;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.view.View;
......@@ -42,10 +41,10 @@ public class DataReductionPromoScreen extends PromoDialog {
/**
* DataReductionPromoScreen constructor.
*
* @param context An Android context.
* @param activity An Android activity to display the dialog.
*/
public DataReductionPromoScreen(Context context) {
super(context);
public DataReductionPromoScreen(Activity activity) {
super(activity);
mState = DataReductionProxyUma.ACTION_DISMISSED;
}
......
......@@ -4,8 +4,7 @@
package org.chromium.chrome.browser.widget;
import android.app.Dialog;
import android.content.Context;
import android.app.Activity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
......@@ -19,8 +18,8 @@ import org.chromium.chrome.R;
/**
* Generic builder for promo dialogs.
*/
public abstract class PromoDialog
extends Dialog implements View.OnClickListener, DialogInterface.OnDismissListener {
public abstract class PromoDialog extends AlwaysDismissedDialog
implements View.OnClickListener, DialogInterface.OnDismissListener {
/** Parameters that can be used to create a new PromoDialog. */
public static class DialogParams {
/**
......@@ -56,13 +55,13 @@ public abstract class PromoDialog
private final FrameLayout mScrimView;
private final PromoDialogLayout mDialogLayout;
protected PromoDialog(Context context) {
super(context, R.style.PromoDialog);
protected PromoDialog(Activity activity) {
super(activity, R.style.PromoDialog);
mScrimView = new FrameLayout(context);
mScrimView = new FrameLayout(activity);
mScrimView.setBackgroundColor(ApiCompatibilityUtils.getColor(
context.getResources(), R.color.modal_dialog_scrim_color));
LayoutInflater.from(context).inflate(R.layout.promo_dialog_layout, mScrimView, true);
activity.getResources(), R.color.modal_dialog_scrim_color));
LayoutInflater.from(activity).inflate(R.layout.promo_dialog_layout, mScrimView, true);
mDialogLayout = (PromoDialogLayout) mScrimView.findViewById(R.id.promo_dialog_layout);
mDialogLayout.initialize(getDialogParams());
......
......@@ -4,7 +4,7 @@
package org.chromium.chrome.browser.widget;
import android.content.Context;
import android.app.Activity;
import android.content.DialogInterface;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
......@@ -13,27 +13,39 @@ import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.widget.LinearLayout;
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.ApiCompatibilityUtils;
import org.chromium.base.ThreadUtils;
import org.chromium.base.test.BaseJUnit4ClassRunner;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.widget.PromoDialog.DialogParams;
import org.chromium.chrome.test.util.ApplicationTestUtils;
import org.chromium.chrome.test.ChromeActivityTestRule;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import java.util.concurrent.Callable;
/**
* Tests for the PromoDialog and PromoDialogLayout.
*/
@RunWith(BaseJUnit4ClassRunner.class)
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({
ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
})
public class PromoDialogTest {
// TODO(tedchoc): Find a way to introduce a lightweight activity that doesn't spin up the world.
// crbug.com/728297
@Rule
public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
/**
* Creates a PromoDialog. Doesn't call {@link PromoDialog#show} because there is no Window to
* attach them to, but it does create them and inflate the layouts.
......@@ -44,16 +56,15 @@ public class PromoDialogTest {
public final PromoDialog dialog;
public final PromoDialogLayout dialogLayout;
private final Context mContext;
private final DialogParams mDialogParams;
PromoDialogWrapper(final DialogParams dialogParams) throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
PromoDialogWrapper(final Activity activity, final DialogParams dialogParams)
throws Exception {
mDialogParams = dialogParams;
dialog = ThreadUtils.runOnUiThreadBlocking(new Callable<PromoDialog>() {
@Override
public PromoDialog call() throws Exception {
PromoDialog dialog = new PromoDialog(mContext) {
PromoDialog dialog = new PromoDialog(activity) {
@Override
public DialogParams getDialogParams() {
return mDialogParams;
......@@ -105,13 +116,8 @@ public class PromoDialogTest {
}
@Before
public void setUp() {
ApplicationTestUtils.setUp(InstrumentationRegistry.getTargetContext(), true);
}
@After
public void tearDown() throws Exception {
ApplicationTestUtils.tearDown(InstrumentationRegistry.getTargetContext());
public void setUp() throws Exception {
mActivityTestRule.startMainActivityOnBlankPage();
}
@Test
......@@ -136,7 +142,8 @@ public class PromoDialogTest {
/** Confirm that PromoDialogs are constructed with all the elements expected. */
private void checkDialogControlVisibility(final DialogParams dialogParams) throws Exception {
PromoDialogWrapper wrapper = new PromoDialogWrapper(dialogParams);
PromoDialogWrapper wrapper =
new PromoDialogWrapper(mActivityTestRule.getActivity(), dialogParams);
PromoDialogLayout promoDialogLayout = wrapper.dialogLayout;
View illustration = promoDialogLayout.findViewById(R.id.illustration);
......@@ -175,7 +182,8 @@ public class PromoDialogTest {
dialogParams.secondaryButtonStringResource = R.string.cancel;
dialogParams.footerStringResource = R.string.learn_more;
PromoDialogWrapper wrapper = new PromoDialogWrapper(dialogParams);
PromoDialogWrapper wrapper =
new PromoDialogWrapper(mActivityTestRule.getActivity(), dialogParams);
final PromoDialogLayout promoDialogLayout = wrapper.dialogLayout;
LinearLayout flippableLayout =
(LinearLayout) promoDialogLayout.findViewById(R.id.full_promo_content);
......@@ -211,7 +219,8 @@ public class PromoDialogTest {
dialogParams.primaryButtonStringResource = R.string.ok;
dialogParams.secondaryButtonStringResource = R.string.cancel;
PromoDialogWrapper wrapper = new PromoDialogWrapper(dialogParams);
PromoDialogWrapper wrapper =
new PromoDialogWrapper(mActivityTestRule.getActivity(), dialogParams);
final PromoDialogLayout promoDialogLayout = wrapper.dialogLayout;
// Nothing should have been clicked yet.
......@@ -248,7 +257,8 @@ public class PromoDialogTest {
dialogParams.headerStringResource = R.string.data_reduction_promo_title;
dialogParams.primaryButtonStringResource = R.string.data_reduction_enable_button;
PromoDialogWrapper wrapper = new PromoDialogWrapper(dialogParams);
PromoDialogWrapper wrapper =
new PromoDialogWrapper(mActivityTestRule.getActivity(), dialogParams);
PromoDialogLayout promoDialogLayout = wrapper.dialogLayout;
ViewGroup scrollableLayout =
(ViewGroup) promoDialogLayout.findViewById(R.id.scrollable_promo_content);
......@@ -267,7 +277,8 @@ public class PromoDialogTest {
dialogParams.headerStringResource = R.string.search_with_sogou;
dialogParams.primaryButtonStringResource = R.string.ok;
PromoDialogWrapper wrapper = new PromoDialogWrapper(dialogParams);
PromoDialogWrapper wrapper =
new PromoDialogWrapper(mActivityTestRule.getActivity(), dialogParams);
PromoDialogLayout promoDialogLayout = wrapper.dialogLayout;
ViewGroup scrollableLayout =
(ViewGroup) promoDialogLayout.findViewById(R.id.scrollable_promo_content);
......@@ -286,7 +297,8 @@ public class PromoDialogTest {
dialogParams.headerStringResource = R.string.search_with_sogou;
dialogParams.primaryButtonStringResource = R.string.ok;
PromoDialogWrapper wrapper = new PromoDialogWrapper(dialogParams);
PromoDialogWrapper wrapper =
new PromoDialogWrapper(mActivityTestRule.getActivity(), dialogParams);
PromoDialogLayout promoDialogLayout = wrapper.dialogLayout;
// Add a dummy control view to ensure the scrolling container has some content.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment