1 // Copyright 2016 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.password_manager; 6 7 import android.app.Activity; 8 import android.content.Context; 9 import android.content.DialogInterface; 10 import android.text.SpannableString; 11 import android.text.Spanned; 12 import android.text.method.LinkMovementMethod; 13 import android.text.style.ClickableSpan; 14 import android.view.LayoutInflater; 15 import android.view.View; 16 import android.widget.TextView; 17 18 import androidx.appcompat.app.AlertDialog; 19 20 import org.chromium.base.annotations.CalledByNative; 21 import org.chromium.base.annotations.NativeMethods; 22 import org.chromium.chrome.R; 23 import org.chromium.ui.base.WindowAndroid; 24 25 /** 26 * The auto sign-in first run experience dialog is shown instead of usual auto sign-in snackbar 27 * when the user first encounters the auto sign-in feature. 28 */ 29 public class AutoSigninFirstRunDialog 30 implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener { 31 private final Context mContext; 32 private final String mTitle; 33 private final String mExplanation; 34 private final int mExplanationLinkStart; 35 private final int mExplanationLinkEnd; 36 private final String mOkButtonText; 37 private final String mTurnOffButtonText; 38 private long mNativeAutoSigninFirstRunDialog; 39 private AlertDialog mDialog; 40 private boolean mWasDismissedByNative; 41 AutoSigninFirstRunDialog(Context context, long nativeAutoSigninFirstRunDialog, String title, String explanation, int explanationLinkStart, int explanationLinkEnd, String okButtonText, String turnOffButtonText)42 private AutoSigninFirstRunDialog(Context context, long nativeAutoSigninFirstRunDialog, 43 String title, String explanation, int explanationLinkStart, int explanationLinkEnd, 44 String okButtonText, String turnOffButtonText) { 45 mNativeAutoSigninFirstRunDialog = nativeAutoSigninFirstRunDialog; 46 mContext = context; 47 mTitle = title; 48 mExplanation = explanation; 49 mExplanationLinkStart = explanationLinkStart; 50 mExplanationLinkEnd = explanationLinkEnd; 51 mOkButtonText = okButtonText; 52 mTurnOffButtonText = turnOffButtonText; 53 } 54 55 @CalledByNative createAndShowDialog(WindowAndroid windowAndroid, long nativeAutoSigninFirstRunDialog, String title, String explanation, int explanationLinkStart, int explanationLinkEnd, String okButtonText, String turnOffButtonText)56 private static AutoSigninFirstRunDialog createAndShowDialog(WindowAndroid windowAndroid, 57 long nativeAutoSigninFirstRunDialog, String title, String explanation, 58 int explanationLinkStart, int explanationLinkEnd, String okButtonText, 59 String turnOffButtonText) { 60 Activity activity = windowAndroid.getActivity().get(); 61 if (activity == null) return null; 62 63 AutoSigninFirstRunDialog dialog = new AutoSigninFirstRunDialog(activity, 64 nativeAutoSigninFirstRunDialog, title, explanation, explanationLinkStart, 65 explanationLinkEnd, okButtonText, turnOffButtonText); 66 dialog.show(); 67 return dialog; 68 } 69 show()70 private void show() { 71 final AlertDialog.Builder builder = 72 new AlertDialog.Builder(mContext, R.style.Theme_Chromium_AlertDialog) 73 .setTitle(mTitle) 74 .setPositiveButton(mOkButtonText, this) 75 .setNegativeButton(mTurnOffButtonText, this); 76 View view = LayoutInflater.from(mContext).inflate( 77 R.layout.auto_sign_in_first_run_dialog, null); 78 TextView summaryView = (TextView) view.findViewById(R.id.summary); 79 80 if (mExplanationLinkStart != mExplanationLinkEnd && mExplanationLinkEnd != 0) { 81 SpannableString spanableExplanation = new SpannableString(mExplanation); 82 spanableExplanation.setSpan(new ClickableSpan() { 83 @Override 84 public void onClick(View view) { 85 AutoSigninFirstRunDialogJni.get().onLinkClicked( 86 mNativeAutoSigninFirstRunDialog, AutoSigninFirstRunDialog.this); 87 mDialog.dismiss(); 88 } 89 }, mExplanationLinkStart, mExplanationLinkEnd, Spanned.SPAN_INCLUSIVE_INCLUSIVE); 90 summaryView.setText(spanableExplanation); 91 summaryView.setMovementMethod(LinkMovementMethod.getInstance()); 92 } else { 93 summaryView.setText(mExplanation); 94 summaryView.setMovementMethod(LinkMovementMethod.getInstance()); 95 } 96 builder.setView(view); 97 98 mDialog = builder.create(); 99 mDialog.setCanceledOnTouchOutside(false); 100 mDialog.setOnDismissListener(this); 101 mDialog.show(); 102 } 103 104 @Override onClick(DialogInterface dialog, int whichButton)105 public void onClick(DialogInterface dialog, int whichButton) { 106 if (whichButton == DialogInterface.BUTTON_NEGATIVE) { 107 AutoSigninFirstRunDialogJni.get().onTurnOffClicked( 108 mNativeAutoSigninFirstRunDialog, AutoSigninFirstRunDialog.this); 109 } else if (whichButton == DialogInterface.BUTTON_POSITIVE) { 110 AutoSigninFirstRunDialogJni.get().onOkClicked( 111 mNativeAutoSigninFirstRunDialog, AutoSigninFirstRunDialog.this); 112 } 113 } 114 115 @Override onDismiss(DialogInterface dialog)116 public void onDismiss(DialogInterface dialog) { 117 destroy(); 118 } 119 destroy()120 private void destroy() { 121 assert mNativeAutoSigninFirstRunDialog != 0; 122 AutoSigninFirstRunDialogJni.get().destroy( 123 mNativeAutoSigninFirstRunDialog, AutoSigninFirstRunDialog.this); 124 mNativeAutoSigninFirstRunDialog = 0; 125 mDialog = null; 126 } 127 128 @CalledByNative dismissDialog()129 private void dismissDialog() { 130 assert !mWasDismissedByNative; 131 mWasDismissedByNative = true; 132 mDialog.dismiss(); 133 } 134 135 @NativeMethods 136 interface Natives { onTurnOffClicked( long nativeAutoSigninFirstRunDialogAndroid, AutoSigninFirstRunDialog caller)137 void onTurnOffClicked( 138 long nativeAutoSigninFirstRunDialogAndroid, AutoSigninFirstRunDialog caller); onOkClicked( long nativeAutoSigninFirstRunDialogAndroid, AutoSigninFirstRunDialog caller)139 void onOkClicked( 140 long nativeAutoSigninFirstRunDialogAndroid, AutoSigninFirstRunDialog caller); destroy(long nativeAutoSigninFirstRunDialogAndroid, AutoSigninFirstRunDialog caller)141 void destroy(long nativeAutoSigninFirstRunDialogAndroid, AutoSigninFirstRunDialog caller); onLinkClicked( long nativeAutoSigninFirstRunDialogAndroid, AutoSigninFirstRunDialog caller)142 void onLinkClicked( 143 long nativeAutoSigninFirstRunDialogAndroid, AutoSigninFirstRunDialog caller); 144 } 145 } 146