1/*
2 * Copyright 2014, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.managedprovisioning.preprovisioning;
18
19import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PROVISIONING_WEB_ACTIVITY_TIME_MS;
20
21import static java.net.HttpURLConnection.HTTP_FORBIDDEN;
22
23import android.content.Context;
24import android.content.Intent;
25import android.os.Bundle;
26import android.support.annotation.Nullable;
27import android.webkit.URLUtil;
28import android.webkit.WebResourceRequest;
29import android.webkit.WebResourceResponse;
30import android.webkit.WebSettings;
31import android.webkit.WebView;
32import android.webkit.WebViewClient;
33import android.widget.Toast;
34
35import com.android.managedprovisioning.R;
36import com.android.managedprovisioning.common.ProvisionLogger;
37import com.android.managedprovisioning.common.SettingsFacade;
38import com.android.managedprovisioning.common.SetupLayoutActivity;
39import com.android.managedprovisioning.preprovisioning.terms.TermsActivity;
40
41/**
42 * This activity shows a web view, which loads the url indicated in the starting intent. By default
43 * the user can click on links and load other urls. However, by passing the allowed url base, the
44 * web view can be limited to urls that start with this base.
45 *
46 * <p>This activity is considered for using by
47 * {@link TermsActivity} to display the support web pages
48 * about provisioning concepts.
49 */
50public class WebActivity extends SetupLayoutActivity {
51    private static final String EXTRA_URL = "extra_url";
52    private static final String EXTRA_STATUS_BAR_COLOR = "extra_status_bar_color";
53
54    private WebView mWebView;
55    private SettingsFacade mSettingsFacade = new SettingsFacade();
56
57    @Override
58    public void onCreate(Bundle savedInstanceState) {
59        super.onCreate(savedInstanceState);
60
61        String extraUrl = getIntent().getStringExtra(EXTRA_URL);
62        if (extraUrl == null) {
63            Toast.makeText(this, R.string.url_error, Toast.LENGTH_SHORT).show();
64            ProvisionLogger.loge("No url provided to WebActivity.");
65            finish();
66        }
67
68        Bundle extras = getIntent().getExtras();
69        if (extras.containsKey(EXTRA_STATUS_BAR_COLOR)) {
70            setMainColor(extras.getInt(EXTRA_STATUS_BAR_COLOR));
71        }
72
73        mWebView = new WebView(this);
74        // We need a custom WebViewClient. Without this an external browser will load the URL.
75        mWebView.setWebViewClient(new WebViewClient() {
76            @Override
77            public WebResourceResponse shouldInterceptRequest(WebView view,
78                    WebResourceRequest request) {
79                String url = request.getUrl().toString();
80                if (!URLUtil.isHttpsUrl(url)) {
81                    ProvisionLogger.loge("Secure connection required, but insecure URL requested "
82                            + "explicitly, or as a part of the page.");
83                    return createNewSecurityErrorResponse();
84                }
85                return super.shouldInterceptRequest(view, request);
86            }
87        });
88        mWebView.loadUrl(extraUrl);
89        // Enable zoom gesture in web view.
90        WebSettings webSettings = mWebView.getSettings();
91        webSettings.setBuiltInZoomControls(true);
92        webSettings.setDisplayZoomControls(false);
93        webSettings.setJavaScriptEnabled(true);
94        if (!mSettingsFacade.isUserSetupCompleted(this)) {
95            // User should not be able to escape provisioning if user setup isn't complete.
96            mWebView.setOnLongClickListener(v -> true);
97        }
98        setContentView(mWebView);
99    }
100
101    private WebResourceResponse createNewSecurityErrorResponse() {
102        WebResourceResponse response = new WebResourceResponse("text/plain", "UTF-8", null);
103        response.setStatusCodeAndReasonPhrase(HTTP_FORBIDDEN, "Secure connection required");
104        return response;
105    }
106
107    protected int getMetricsCategory() {
108        return PROVISIONING_WEB_ACTIVITY_TIME_MS;
109    }
110
111    @Override
112    public void onBackPressed() {
113        if (mWebView.canGoBack()) {
114            mWebView.goBack();
115        } else {
116            super.onBackPressed();
117        }
118    }
119
120    /**
121     * Creates an intent to launch the {@link WebActivity}.
122     * @param url the url to be shown upon launching this activity
123     */
124    @Nullable
125    public static Intent createIntent(Context context, String url, int statusBarColor) {
126        if (URLUtil.isNetworkUrl(url)) {
127            return new Intent(context, WebActivity.class)
128                    .putExtra(EXTRA_URL, url)
129                    .putExtra(EXTRA_STATUS_BAR_COLOR, statusBarColor);
130        }
131        return null;
132    }
133}
134