165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/* 265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Copyright (C) 2014 The Android Open Source Project 365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Licensed under the Apache License, Version 2.0 (the "License"); 565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * you may not use this file except in compliance with the License. 665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * You may obtain a copy of the License at 765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * http://www.apache.org/licenses/LICENSE-2.0 965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 1065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Unless required by applicable law or agreed to in writing, software 1165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * distributed under the License is distributed on an "AS IS" BASIS, 1265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * See the License for the specific language governing permissions and 1465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * limitations under the License. 1565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 1665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepackage com.android.tv.settings.dialog.old; 1865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.annotation.TargetApi; 2065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Activity; 2165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Fragment; 2265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Context; 2365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.res.Configuration; 2465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.graphics.Bitmap; 2565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.net.Uri; 2665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Build; 2765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Bundle; 2865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Message; 2965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.provider.Settings; 3065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.provider.Settings.Secure; 3165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.telephony.TelephonyManager; 3265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.text.TextUtils; 3365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.Log; 3465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.KeyEvent; 3565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.LayoutInflater; 3665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.View; 3765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.ViewGroup; 3865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.webkit.CookieManager; 3965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.webkit.CookieSyncManager; 4065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.webkit.WebChromeClient; 4165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.webkit.WebSettings; 4265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.webkit.WebView; 4365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.webkit.WebViewClient; 4465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.R; 4665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.io.BufferedReader; 4865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.io.FileNotFoundException; 4965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.io.InputStream; 5065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.io.InputStreamReader; 5165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.io.IOException; 5265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.Locale; 5365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/** 5565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Fragment that shows a link containing the ToS. 5665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 5765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepublic class TosWebViewFragment extends Fragment { 5865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String TAG = "TosWebViewFragment"; 6065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final boolean DEBUG = false; 6165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // TODO switch to pointing to proper TLD once there is a reliable way to 6265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // map geography to proper TLD, b/11032160 6365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String GOOGLE_TOS_URL = "http://www.google.com/intl/%y_%z/policies/terms/"; 6465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String GOOGLE_PRIVACY_URL = 6565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane "http://www.google.com/intl/%y_%z/policies/privacy/"; 6665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String SETTINGS_SECURE_TOS_URL = "canvas_tos_url"; 6865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String SETTINGS_SECURE_PRIVACY_URL = "canvas_privacy_url"; 6965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final int SOURCE_URL = 1; 7165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final int SOURCE_STRING = 2; 7265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final int SOURCE_RESOURCE_ID = 3; 7365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String ARGUMENT_SHOW = "show"; 7565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String ARGUMENT_CONTENT_STRING = "content_string"; 7665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String ARGUMENT_CONTENT_URL = "content_url"; 7765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String ARGUMENT_CONTENT_RESOURCE_ID = "content_resource_id"; 7865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final int SHOW_TERMS_OF_SERVICE = 3; 8065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final int SHOW_PRIVACY_POLICY = 4; 8165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static final int SHOW_ADDITIONAL_TERMS = 5; 8265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 8465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Create instance and select page to display. The content is selected by the single parameter 8565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * and determined by a URL or resource string depending on the page to show. 8665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 8765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param show One of SHOW_TERMS_OF_SERVICE, SHOW_PRIVACY_POLICY, SHOW_ADDITIONAL_TERMS 8865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 8965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static TosWebViewFragment newInstance(int show) { 9065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TosWebViewFragment f = new TosWebViewFragment(); 9165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle args = new Bundle(); 9265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putInt(ARGUMENT_SHOW, show); 9365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane f.setArguments(args); 9465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return f; 9565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 9865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Create instance and display page from URL. 9965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 10065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param uri URL of page to show. 10165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 10265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static TosWebViewFragment newInstanceUrl(String pageUrl) { 10365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TosWebViewFragment f = new TosWebViewFragment(); 10465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle args = new Bundle(); 10565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putString(ARGUMENT_CONTENT_URL, pageUrl); 10665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane f.setArguments(args); 10765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return f; 10865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 11165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Create instance and display page from a string. 11265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 11365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param page Text to show. 11465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 11565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static TosWebViewFragment newInstance(String page) { 11665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TosWebViewFragment f = new TosWebViewFragment(); 11765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle args = new Bundle(); 11865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putString(ARGUMENT_CONTENT_STRING, page); 11965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane f.setArguments(args); 12065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return f; 12165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 12265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 12365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 12465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Create instance and display page from resource id. 12565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 12665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param resourceId id or string resourse to show. 12765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 12865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static TosWebViewFragment newInstance_resourceId(int resourceId) { 12965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TosWebViewFragment f = new TosWebViewFragment(); 13065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle args = new Bundle(); 13165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putInt(ARGUMENT_CONTENT_RESOURCE_ID, resourceId); 13265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane f.setArguments(args); 13365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return f; 13465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 13665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private class MyChromeClient extends WebChromeClient { 13765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 13865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture, 13965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Message resultMsg) { 14065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane resultMsg.obj = mWebView; 14165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane resultMsg.sendToTarget(); 14265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return true; 14365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 14565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 14665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onProgressChanged(WebView view, int newProgress) { 14765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 14965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 15065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public boolean onConsoleMessage(android.webkit.ConsoleMessage consoleMessage) { 15165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return true; 15265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 15565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private class MyWebViewClient extends WebViewClient { 15665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 15765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 15865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Before we load any page, we check with our session object to see if 15965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * we should do any special handling at this point 16065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 16165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 16265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public boolean shouldOverrideUrlLoading(WebView view, String url) { 16365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return false; 16465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 16565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 16665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 16765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onPageStarted(WebView view, String url, Bitmap favicon) { 16865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 16965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 17065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 17165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onReceivedError(WebView view, int errorCode, String description, 17265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String failingUrl) { 17365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.w(TAG, String.format( 17465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane "onReceivedError: errorCode %d, description: %s, url: %s", errorCode, 17565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane description, failingUrl)); 17665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mIsLoading = false; 17765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // If this is the first attempted page load, this could be a 17865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // connectivity issue 17965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // We treat it all as server error, let ShowError decide if network 18065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // is still up 18165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane onWebLoginError(errorCode, description); 18265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.onReceivedError(view, errorCode, description, failingUrl); 18365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 18465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 18565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 18665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onTooManyRedirects(WebView view, Message cancelMsg, Message continueMsg) { 18765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.e(TAG, "onTooManyRedirects"); 18865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Users probably don't care about redirects, it's a server error to 18965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // them 19065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane onWebLoginError(0, ""); 19165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 19265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 19365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 19465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onPageFinished(WebView view, String url) { 19565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (DEBUG) { 19665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.d(TAG, "Loaded " + url); 19765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 19865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane view.requestFocus(); 19965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 20165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void onWebLoginError(int errorCode, String description) { 20265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // TODO: Show error? 20365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 20665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private WebView mWebView; 20765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private String mSource; 20865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int mSourceType; 20965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private boolean mIsLoading; 21065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 21165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 21265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle) { 21365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane View content = inflater.inflate(R.layout.navigable_webview, null); 21465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 21565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (icicle == null) { 21665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWebView = (WebView) content.findViewById(R.id.webview); 21765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane CookieSyncManager.createInstance(getActivity()); 21865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWebView.setWebViewClient(new MyWebViewClient()); 21965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWebView.setWebChromeClient(new MyChromeClient()); 22065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane WebSettings s = mWebView.getSettings(); 22165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane s.setNeedInitialFocus(true); 22265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane s.setJavaScriptEnabled(true); 22365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane s.setSupportMultipleWindows(false); 22465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane s.setSaveFormData(false); 22565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane s.setSavePassword(false); 22665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane s.setAllowFileAccess(false); 22765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane s.setDatabaseEnabled(false); 22865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane s.setJavaScriptCanOpenWindowsAutomatically(false); 22965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane s.setLoadsImagesAutomatically(true); 23065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane s.setLightTouchEnabled(false); 23165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane s.setNeedInitialFocus(false); 23265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane s.setUseWideViewPort(true); 23365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane s.setSupportZoom(false); 23465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWebView.setMapTrackballToArrowKeys(false); 23565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 23665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int show = getArguments().getInt(ARGUMENT_SHOW, -1); 23765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane switch (show) { 23865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case SHOW_TERMS_OF_SERVICE: 23965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSourceType = SOURCE_URL; 24065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSource = Settings.Secure.getString(getActivity().getContentResolver(), 24165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane SETTINGS_SECURE_TOS_URL); 24265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mSource == null) { 24365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSource = GOOGLE_TOS_URL; 24465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 24565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSource = substitueArguments(mSource); 24665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 24765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case SHOW_PRIVACY_POLICY: 24865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSourceType = SOURCE_URL; 24965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSource = Settings.Secure.getString(getActivity().getContentResolver(), 25065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane SETTINGS_SECURE_PRIVACY_URL); 25165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mSource == null) { 25265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSource = GOOGLE_PRIVACY_URL; 25365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSource = substitueArguments(mSource); 25565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 25665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case SHOW_ADDITIONAL_TERMS: 25765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSourceType = SOURCE_STRING; 25865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSource = readStringFromResource(getActivity(), 25965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.raw.additional_terms_of_service); 26065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 26165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane default: 26265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // User is specifying a page to display, either by Url, resource id or string. 26365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSource = getArguments().getString(ARGUMENT_CONTENT_URL); 26465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mSource != null) { 26565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSourceType = SOURCE_URL; 26665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSource = substitueArguments(mSource); 26765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 26865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSourceType = SOURCE_STRING; 26965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSource = getArguments().getString(ARGUMENT_CONTENT_STRING); 27065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mSource == null) { 27165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int resourceId = getArguments().getInt(ARGUMENT_CONTENT_RESOURCE_ID); 27265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSource = getResources().getString(resourceId); 27365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 27465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 27565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 27665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 27765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 27865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return content; 27965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 28065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 28165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 28265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Determines the current activity mode and initializes ui appropriately. 28365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 28465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 28565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onResume() { 28665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.onResume(); 28765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mIsLoading = true; 28865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane switch (mSourceType) { 28965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case SOURCE_URL: 29065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWebView.loadUrl(mSource); 29165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 29265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case SOURCE_STRING: 29365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWebView.loadData(mSource,"text/html", null); 29465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 29565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 29665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWebView.onResume(); 29765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 29865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 29965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 30065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Stops page loading if it is in progress. 30165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 30265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 30365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onPause() { 30465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mIsLoading) { 30565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWebView.stopLoading(); 30665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mIsLoading = false; 30765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mWebView.onPause(); 30965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.onPause(); 31065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 31165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 31265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private String substitueArguments(String url) { 31365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Substitute locale if present in property 31465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (url.contains("%m")) { 31565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 31665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Configuration config = new Configuration(); 31765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Settings.System.getConfiguration(getActivity().getContentResolver(), config); 31865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (config.mcc != 0) { 31965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane url = url.replace("%m", Integer.toString(config.mcc)); 32065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 32165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // This will happen if the device doesn't have a SIM, in 32265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // which case we just use the locale. 32365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane url = url.replace("%m", "%s"); 32465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 32565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (Exception e) { 32665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Intentionally left blank 32765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 32865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 32965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (url.contains("%s")) { 33065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Locale locale = Locale.getDefault(); 33165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String tmp = locale.getLanguage() + "_" + locale.getCountry().toLowerCase(); 33265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane url = url.replace("%s", tmp); 33365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 33465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 33565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // %y is used to indicate a language variable to be replaced at runtime. 33665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (url.contains("%y")) { 33765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Locale locale = Locale.getDefault(); 33865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane url = url.replace("%y", locale.getLanguage()); 33965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 34065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 34165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // %z is used to indicate the country. We use the value set by the 34265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // SIM. We choose not to use the operator/network country but that 34365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // which is set on SIM as they most likely procured the device there 34465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (url.contains("%z")) { 34565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 34665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TelephonyManager telephony = (TelephonyManager) getActivity() 34765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .getSystemService(Context.TELEPHONY_SERVICE); 34865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 34965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Configuration config = new Configuration(); 35065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Settings.System.getConfiguration(getActivity().getContentResolver(), config); 35165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 35265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (telephony != null && config.mcc != 0) { 35365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String simCountryIso = telephony.getSimCountryIso(); 35465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (TextUtils.isEmpty(simCountryIso)) { 35565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane simCountryIso = "us"; 35665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane url = url.replace("%z", simCountryIso); 35865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 35965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // This will happen if the device doesn't have a SIM, in 36065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // which case we just use the country with the default 36165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // locale country 36265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Locale locale = Locale.getDefault(); 36365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane url = url.replace("%z", locale.getCountry().toLowerCase()); 36465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 36565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (Exception e) { 36665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Intentionally left blank 36765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 36865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 36965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return url; 37065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 37265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private String readStringFromResource(Context context, int resourceId) { 37365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane StringBuilder contents = new StringBuilder(); 37465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String sep = System.lineSeparator(); 37565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 37665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane InputStream is = context.getResources().openRawResource(resourceId); 37765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane BufferedReader input = new BufferedReader(new InputStreamReader(is), 1024*8); 37865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 37965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String line = null; 38065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane while ((line = input.readLine()) != null) { 38165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane contents.append(line); 38265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane contents.append(sep); 38365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } finally { 38565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane input.close(); 38665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (FileNotFoundException ex) { 38865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.e(TAG, "Couldn't find the file " + resourceId + " " + ex); 38965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return null; 39065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (IOException ex){ 39165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.e(TAG, "Error reading file " + resourceId + " " + ex); 39265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return null; 39365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return contents.toString(); 39565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane} 397