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 |