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