| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 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.pageinfo; | |
| 6 | |
| 7 import android.app.Dialog; | |
| 8 import android.content.Context; | |
| 9 import android.content.DialogInterface; | |
| 10 import android.content.Intent; | |
| 11 import android.graphics.Color; | |
| 12 import android.provider.Browser; | |
| 13 import android.text.TextUtils; | |
| 14 import android.view.LayoutInflater; | |
| 15 import android.view.View; | |
| 16 import android.view.View.OnClickListener; | |
| 17 import android.view.ViewGroup; | |
| 18 import android.view.Window; | |
| 19 import android.widget.Button; | |
| 20 import android.widget.ImageView; | |
| 21 import android.widget.LinearLayout; | |
| 22 import android.widget.ScrollView; | |
| 23 import android.widget.TextView; | |
| 24 | |
| 25 import org.chromium.base.ApiCompatibilityUtils; | |
| 26 import org.chromium.base.Log; | |
| 27 import org.chromium.base.annotations.CalledByNative; | |
| 28 import org.chromium.chrome.R; | |
| 29 import org.chromium.chrome.browser.ResourceId; | |
| 30 import org.chromium.content_public.browser.WebContents; | |
| 31 import org.chromium.content_public.browser.WebContentsObserver; | |
| 32 | |
| 33 /** | |
| 34 * Java side of Android implementation of the website settings UI. | |
| 35 */ | |
| 36 public class ConnectionInfoPopup implements OnClickListener { | |
| 37 private static final String TAG = "ConnectionInfoPopup"; | |
| 38 | |
| 39 private static final String HELP_URL = | |
| 40 "https://support.google.com/chrome/answer/95617"; | |
| 41 private static final int DESCRIPTION_TEXT_SIZE_SP = 12; | |
| 42 private final Context mContext; | |
| 43 private final Dialog mDialog; | |
| 44 private final LinearLayout mContainer; | |
| 45 private final WebContents mWebContents; | |
| 46 private final int mPaddingWide, mPaddingThin; | |
| 47 private final long mNativeConnectionInfoPopup; | |
| 48 private TextView mCertificateViewer, mMoreInfoLink; | |
| 49 private ViewGroup mCertificateLayout, mDescriptionLayout; | |
| 50 private Button mResetCertDecisionsButton; | |
| 51 private String mLinkUrl; | |
| 52 | |
| 53 private ConnectionInfoPopup(Context context, WebContents webContents) { | |
| 54 mContext = context; | |
| 55 mWebContents = webContents; | |
| 56 | |
| 57 mContainer = new LinearLayout(mContext); | |
| 58 mContainer.setOrientation(LinearLayout.VERTICAL); | |
| 59 mContainer.setBackgroundColor(Color.WHITE); | |
| 60 mPaddingWide = (int) context.getResources().getDimension( | |
| 61 R.dimen.connection_info_padding_wide); | |
| 62 mPaddingThin = (int) context.getResources().getDimension( | |
| 63 R.dimen.connection_info_padding_thin); | |
| 64 mContainer.setPadding(mPaddingWide, mPaddingWide, mPaddingWide, | |
| 65 mPaddingWide - mPaddingThin); | |
| 66 | |
| 67 mDialog = new Dialog(mContext); | |
| 68 mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); | |
| 69 mDialog.setCanceledOnTouchOutside(true); | |
| 70 // This needs to come after other member initialization. | |
| 71 mNativeConnectionInfoPopup = nativeInit(this, webContents); | |
| 72 final WebContentsObserver webContentsObserver = | |
| 73 new WebContentsObserver(mWebContents) { | |
| 74 @Override | |
| 75 public void navigationEntryCommitted() { | |
| 76 // If a navigation is committed (e.g. from in-page redirect), th
e data we're | |
| 77 // showing is stale so dismiss the dialog. | |
| 78 mDialog.dismiss(); | |
| 79 } | |
| 80 | |
| 81 @Override | |
| 82 public void destroy() { | |
| 83 super.destroy(); | |
| 84 mDialog.dismiss(); | |
| 85 } | |
| 86 }; | |
| 87 mDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { | |
| 88 @Override | |
| 89 public void onDismiss(DialogInterface dialog) { | |
| 90 assert mNativeConnectionInfoPopup != 0; | |
| 91 webContentsObserver.destroy(); | |
| 92 nativeDestroy(mNativeConnectionInfoPopup); | |
| 93 } | |
| 94 }); | |
| 95 } | |
| 96 | |
| 97 /** | |
| 98 * Adds certificate section, which contains an icon, a headline, a | |
| 99 * description and a label for certificate info link. | |
| 100 */ | |
| 101 @CalledByNative | |
| 102 private void addCertificateSection(int enumeratedIconId, String headline, St
ring description, | |
| 103 String label) { | |
| 104 View section = addSection(enumeratedIconId, headline, description); | |
| 105 assert mCertificateLayout == null; | |
| 106 mCertificateLayout = (ViewGroup) section.findViewById(R.id.connection_in
fo_text_layout); | |
| 107 if (label != null && !label.isEmpty()) { | |
| 108 setCertificateViewer(label); | |
| 109 } | |
| 110 } | |
| 111 | |
| 112 /** | |
| 113 * Adds Description section, which contains an icon, a headline, and a | |
| 114 * description. Most likely headline for description is empty | |
| 115 */ | |
| 116 @CalledByNative | |
| 117 private void addDescriptionSection(int enumeratedIconId, String headline, St
ring description) { | |
| 118 View section = addSection(enumeratedIconId, headline, description); | |
| 119 assert mDescriptionLayout == null; | |
| 120 mDescriptionLayout = (ViewGroup) section.findViewById(R.id.connection_in
fo_text_layout); | |
| 121 } | |
| 122 | |
| 123 private View addSection(int enumeratedIconId, String headline, String descri
ption) { | |
| 124 View section = LayoutInflater.from(mContext).inflate(R.layout.connection
_info, | |
| 125 null); | |
| 126 ImageView i = (ImageView) section.findViewById(R.id.connection_info_icon
); | |
| 127 int drawableId = ResourceId.mapToDrawableId(enumeratedIconId); | |
| 128 i.setImageResource(drawableId); | |
| 129 | |
| 130 TextView h = (TextView) section.findViewById(R.id.connection_info_headli
ne); | |
| 131 h.setText(headline); | |
| 132 if (TextUtils.isEmpty(headline)) h.setVisibility(View.GONE); | |
| 133 | |
| 134 TextView d = (TextView) section.findViewById(R.id.connection_info_descri
ption); | |
| 135 d.setText(description); | |
| 136 d.setTextSize(DESCRIPTION_TEXT_SIZE_SP); | |
| 137 if (TextUtils.isEmpty(description)) d.setVisibility(View.GONE); | |
| 138 | |
| 139 mContainer.addView(section); | |
| 140 return section; | |
| 141 } | |
| 142 | |
| 143 private void setCertificateViewer(String label) { | |
| 144 assert mCertificateViewer == null; | |
| 145 mCertificateViewer = new TextView(mContext); | |
| 146 mCertificateViewer.setText(label); | |
| 147 mCertificateViewer.setTextColor(ApiCompatibilityUtils.getColor( | |
| 148 mContext.getResources(), R.color.website_settings_popup_text_lin
k)); | |
| 149 mCertificateViewer.setTextSize(DESCRIPTION_TEXT_SIZE_SP); | |
| 150 mCertificateViewer.setOnClickListener(this); | |
| 151 mCertificateViewer.setPadding(0, mPaddingThin, 0, 0); | |
| 152 mCertificateLayout.addView(mCertificateViewer); | |
| 153 } | |
| 154 | |
| 155 @CalledByNative | |
| 156 private void addResetCertDecisionsButton(String label) { | |
| 157 assert mNativeConnectionInfoPopup != 0; | |
| 158 assert mResetCertDecisionsButton == null; | |
| 159 | |
| 160 mResetCertDecisionsButton = new Button(mContext); | |
| 161 mResetCertDecisionsButton.setText(label); | |
| 162 mResetCertDecisionsButton.setBackgroundResource( | |
| 163 R.drawable.connection_info_reset_cert_decisions); | |
| 164 mResetCertDecisionsButton.setTextColor(ApiCompatibilityUtils.getColor( | |
| 165 mContext.getResources(), | |
| 166 R.color.connection_info_popup_reset_cert_decisions_button)); | |
| 167 mResetCertDecisionsButton.setTextSize(DESCRIPTION_TEXT_SIZE_SP); | |
| 168 mResetCertDecisionsButton.setOnClickListener(this); | |
| 169 | |
| 170 LinearLayout container = new LinearLayout(mContext); | |
| 171 container.setOrientation(LinearLayout.VERTICAL); | |
| 172 container.addView(mResetCertDecisionsButton); | |
| 173 container.setPadding(0, 0, 0, mPaddingWide); | |
| 174 mContainer.addView(container); | |
| 175 } | |
| 176 | |
| 177 @CalledByNative | |
| 178 private void addMoreInfoLink(String linkText) { | |
| 179 mMoreInfoLink = new TextView(mContext); | |
| 180 mLinkUrl = HELP_URL; | |
| 181 mMoreInfoLink.setText(linkText); | |
| 182 mMoreInfoLink.setTextColor(ApiCompatibilityUtils.getColor( | |
| 183 mContext.getResources(), R.color.website_settings_popup_text_lin
k)); | |
| 184 mMoreInfoLink.setTextSize(DESCRIPTION_TEXT_SIZE_SP); | |
| 185 mMoreInfoLink.setPadding(0, mPaddingThin, 0, 0); | |
| 186 mMoreInfoLink.setOnClickListener(this); | |
| 187 mDescriptionLayout.addView(mMoreInfoLink); | |
| 188 } | |
| 189 | |
| 190 /** Displays the ConnectionInfoPopup. */ | |
| 191 @CalledByNative | |
| 192 private void showDialog() { | |
| 193 ScrollView scrollView = new ScrollView(mContext); | |
| 194 scrollView.addView(mContainer); | |
| 195 mDialog.addContentView(scrollView, | |
| 196 new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PA
RENT, | |
| 197 LinearLayout.LayoutParams.MATCH_PARENT)); | |
| 198 | |
| 199 mDialog.getWindow().setLayout( | |
| 200 ViewGroup.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.W
RAP_CONTENT); | |
| 201 mDialog.show(); | |
| 202 } | |
| 203 | |
| 204 @Override | |
| 205 public void onClick(View v) { | |
| 206 if (mResetCertDecisionsButton == v) { | |
| 207 nativeResetCertDecisions(mNativeConnectionInfoPopup, mWebContents); | |
| 208 mDialog.dismiss(); | |
| 209 } else if (mCertificateViewer == v) { | |
| 210 byte[][] certChain = CertificateChainHelper.getCertificateChain(mWeb
Contents); | |
| 211 if (certChain == null) { | |
| 212 // The WebContents may have been destroyed/invalidated. If so, | |
| 213 // ignore this request. | |
| 214 return; | |
| 215 } | |
| 216 CertificateViewer.showCertificateChain(mContext, certChain); | |
| 217 } else if (mMoreInfoLink == v) { | |
| 218 mDialog.dismiss(); | |
| 219 try { | |
| 220 Intent i = Intent.parseUri(mLinkUrl, Intent.URI_INTENT_SCHEME); | |
| 221 i.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true); | |
| 222 i.putExtra(Browser.EXTRA_APPLICATION_ID, mContext.getPackageName
()); | |
| 223 mContext.startActivity(i); | |
| 224 } catch (Exception ex) { | |
| 225 // Do nothing intentionally. | |
| 226 Log.w(TAG, "Bad URI %s", mLinkUrl, ex); | |
| 227 } | |
| 228 } | |
| 229 } | |
| 230 | |
| 231 /** | |
| 232 * Shows a connection info dialog for the provided WebContents. | |
| 233 * | |
| 234 * The popup adds itself to the view hierarchy which owns the reference whil
e it's | |
| 235 * visible. | |
| 236 * | |
| 237 * @param context Context which is used for launching a dialog. | |
| 238 * @param webContents The WebContents for which to show Website information.
This | |
| 239 * information is retrieved for the visible entry. | |
| 240 */ | |
| 241 public static void show(Context context, WebContents webContents) { | |
| 242 new ConnectionInfoPopup(context, webContents); | |
| 243 } | |
| 244 | |
| 245 private static native long nativeInit(ConnectionInfoPopup popup, | |
| 246 WebContents webContents); | |
| 247 private native void nativeDestroy(long nativeConnectionInfoPopupAndroid); | |
| 248 private native void nativeResetCertDecisions( | |
| 249 long nativeConnectionInfoPopupAndroid, WebContents webContents); | |
| 250 } | |
| OLD | NEW |