Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 60545527 authored by Doug Zongker's avatar Doug Zongker Committed by Android (Google) Code Review
Browse files

Merge "remove GoogleWebContentHelper class"

parents 917cd4fc c34705bc
Loading
Loading
Loading
Loading
+0 −281
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.util;

import android.content.ContentResolver;
import android.content.Context;
import android.net.http.SslError;
import android.os.Message;
import android.provider.Settings;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;

import java.util.Locale;

/**
 * Helper to display Google web content, and fallback on a static message if the
 * web content is unreachable. For example, this can be used to display
 * "Legal terms".
 * <p>
 * The typical usage pattern is to have two Gservices settings defined:
 * <ul>
 * <li>A secure URL that will be displayed on the device. This should be HTTPS
 * so hotspots won't intercept it giving us a false positive that the page
 * loaded successfully.
 * <li>A pretty human-readable URL that will be displayed to the user in case we
 * cannot reach the above URL.
 * </ul>
 * <p>
 * The typical call sequence is {@link #setUrlsFromGservices(String, String)},
 * {@link #setUnsuccessfulMessage(String)}, and {@link #loadUrl()}. At some
 * point, you'll want to display the layout via {@link #getLayout()}.
 */
public class GoogleWebContentHelper {
    
    private Context mContext;
    
    private String mSecureUrl;
    private String mPrettyUrl;

    private String mUnsuccessfulMessage;
    
    private ViewGroup mLayout;
    private WebView mWebView;
    private View mProgressBar;
    private TextView mTextView;
    
    private boolean mReceivedResponse;
    
    public GoogleWebContentHelper(Context context) {
        mContext = context;
    }
    
    /**
     * Fetches the URLs from Gservices.
     * 
     * @param secureSetting The setting key whose value contains the HTTPS URL.
     * @param prettySetting The setting key whose value contains the pretty URL.
     * @return This {@link GoogleWebContentHelper} so methods can be chained.
     */
    public GoogleWebContentHelper setUrlsFromGservices(String secureSetting, String prettySetting) {
        ContentResolver contentResolver = mContext.getContentResolver();
        mSecureUrl = fillUrl(Settings.Gservices.getString(contentResolver, secureSetting),
                mContext);
        mPrettyUrl = fillUrl(Settings.Gservices.getString(contentResolver, prettySetting), 
                mContext);
        return this;
    }
    
    /**
     * Fetch directly from provided urls.
     * 
     * @param secureUrl The HTTPS URL.
     * @param prettyUrl The pretty URL.
     * @return This {@link GoogleWebContentHelper} so methods can be chained.
     */
    public GoogleWebContentHelper setUrls(String secureUrl, String prettyUrl) {
        mSecureUrl = fillUrl(secureUrl, mContext);
        mPrettyUrl = fillUrl(prettyUrl, mContext);
        return this;
    }
    

    /**
     * Sets the message that will be shown if we are unable to load the page.
     * <p>
     * This should be called after {@link #setUrlsFromGservices(String, String)}
     * .
     * 
     * @param message The message to load. The first argument, according to
     *        {@link java.util.Formatter}, will be substituted with the pretty
     *        URL.
     * @return This {@link GoogleWebContentHelper} so methods can be chained.
     */
    public GoogleWebContentHelper setUnsuccessfulMessage(String message) {
        Locale locale = mContext.getResources().getConfiguration().locale;
        mUnsuccessfulMessage = String.format(locale, message, mPrettyUrl);
        return this;
    }

    /**
     * Begins loading the secure URL.
     * 
     * @return This {@link GoogleWebContentHelper} so methods can be chained.
     */
    public GoogleWebContentHelper loadUrl() {
        ensureViews();
        mWebView.loadUrl(mSecureUrl);
        return this;
    }

    /**
     * Loads data into the webview and also provides a failback url
     * @return This {@link GoogleWebContentHelper} so methods can be chained.
     */
    public GoogleWebContentHelper loadDataWithFailUrl(String base, String data, 
        String mimeType, String encoding, String failUrl) {
        ensureViews();
        mWebView.loadDataWithBaseURL(base, data, mimeType, encoding, failUrl);
        return this;
    }

    /**
     * Helper to handle the back key. Returns true if the back key was handled, 
     * otherwise returns false.
     * @param event the key event sent to {@link Activity#dispatchKeyEvent()}
     */
    public boolean handleKey(KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK 
                && event.getAction() == KeyEvent.ACTION_DOWN) {
            if (mWebView.canGoBack()) {
                mWebView.goBack();
                return true;
            }
        }
        return false;
    }

    /**
     * Returns the layout containing the web view, progress bar, and text view.
     * This class takes care of setting each one's visibility based on current
     * state.
     * 
     * @return The layout you should display.
     */
    public ViewGroup getLayout() {
        ensureViews();
        return mLayout;
    }

    private synchronized void ensureViews() {
        if (mLayout == null) {
            initializeViews();
        }
    }

    /**
     * Fills the URL with the locale.
     * 
     * @param url The URL in Formatter style for the extra info to be filled in.
     * @return The filled URL.
     */
    private static String fillUrl(String url, Context context) {
        
        if (TextUtils.isEmpty(url)) {
            return "";
        }

        /* We add another layer of indirection here to allow mcc's to fill
         * in Locales for TOS.  TODO - REMOVE when needed locales supported
         * natively (when not shipping devices to country X without support
         * for their locale).
         */
        String localeReplacement = context.
                getString(com.android.internal.R.string.locale_replacement);
        if (localeReplacement != null && localeReplacement.length() != 0) {
            url = String.format(url, localeReplacement);
        }

        Locale locale = Locale.getDefault();
        String tmp = locale.getLanguage() + "_" + locale.getCountry().toLowerCase();
        return String.format(url, tmp);
    }
    
    private void initializeViews() {

        LayoutInflater inflater =
                (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        
        mLayout = (ViewGroup) inflater.inflate(
                com.android.internal.R.layout.google_web_content_helper_layout, null);

        mWebView = (WebView) mLayout.findViewById(com.android.internal.R.id.web);
        mWebView.setWebViewClient(new MyWebViewClient());
        WebSettings settings = mWebView.getSettings();
        settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
        
        mProgressBar = mLayout.findViewById(com.android.internal.R.id.progressContainer);
        TextView message = (TextView) mProgressBar.findViewById(com.android.internal.R.id.message);
        message.setText(com.android.internal.R.string.googlewebcontenthelper_loading);
        
        mTextView = (TextView) mLayout.findViewById(com.android.internal.R.id.text);
        mTextView.setText(mUnsuccessfulMessage);
    }

    private synchronized void handleWebViewCompletion(boolean success) {
        
        if (mReceivedResponse) {
            return;
        } else {
            mReceivedResponse = true;
        }
        
        // In both cases, remove the progress bar
        ((ViewGroup) mProgressBar.getParent()).removeView(mProgressBar);

        // Remove the view that isn't relevant
        View goneView = success ? mTextView : mWebView;
        ((ViewGroup) goneView.getParent()).removeView(goneView);

        // Show the next view, which depends on success
        View visibleView = success ? mWebView : mTextView;
        visibleView.setVisibility(View.VISIBLE);
    }
    
    private class MyWebViewClient extends WebViewClient {

        @Override
        public void onPageFinished(WebView view, String url) {
            handleWebViewCompletion(true);
        }

        @Override
        public void onReceivedError(WebView view, int errorCode,
                String description, String failingUrl) {
            handleWebViewCompletion(false);
        }

        @Override
        public void onReceivedHttpAuthRequest(WebView view,
                HttpAuthHandler handler, String host, String realm) {
            handleWebViewCompletion(false);
        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler,
                SslError error) {
            handleWebViewCompletion(false);
        }

        @Override
        public void onTooManyRedirects(WebView view, Message cancelMsg,
                Message continueMsg) {
            handleWebViewCompletion(false);
        }
        
    }
    
}