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

Commit 0acb1c32 authored by Steve Block's avatar Steve Block
Browse files

Drop support for Android HTTP stack

All future releases will use the Chromium HTTP stack and maintaining two HTTP
    stacks adds maintenance overhead. The Chromium HTTP stack requires V8, but we
    now use V8 in all build targets (b/5495373), so we can safely drop the Android
    HTTP stack.

LoadListener, HttpAuthHandlerImpl, Network, SslErrorHandlerImpl, WebViewWorker
- Android-stack specific, removed
StreamLoader, FrameLoader
- Require LoadListener, removed
CacheLoader, ContentLoader, DataLoader, FileLoader
- Extend StreamLoader, removed

BrowserFrame
- Removed methods that create LoadListener
- BrowserFrame.startLoadingResource() is called from native
CallbackProxy, WebView
- Removed calls to Network methods
CacheManager, CookieManager, CookieSyncManager, WebViewCore, WebResourceResponse
- Removed other Android-stack specific code
JniUtlil
- Removed useChromiumHttpStack()
WebViewDatabase
- Removed all code to create cookies and cache databases for Android HTTP stack

See corresponding WebKit change https://android-git.corp.google.com/g/166327.

Bug: 5495616
Change-Id: If491675516f6eb187077af4220214bb6e6a8d045
parent 1e17ecae
Loading
Loading
Loading
Loading
+4 −111
Original line number Diff line number Diff line
@@ -470,18 +470,6 @@ class BrowserFrame extends Handler {
        }
    }

    /**
     * We have received an SSL certificate for the main top-level page.
     * Used by the Android HTTP stack only.
     */
    void certificate(SslCertificate certificate) {
        if (mIsMainFrame) {
            // we want to make this call even if the certificate is null
            // (ie, the site is not secure)
            mCallbackProxy.onReceivedCertificate(certificate);
        }
    }

    /**
     * Destroy all native components of the BrowserFrame.
     */
@@ -515,10 +503,6 @@ class BrowserFrame extends Handler {
                        }
                    }
                }
                if (!JniUtil.useChromiumHttpStack()) {
                    WebViewWorker.getHandler().sendEmptyMessage(
                            WebViewWorker.MSG_TRIM_CACHE);
                }
                break;
            }

@@ -767,10 +751,9 @@ class BrowserFrame extends Handler {
        } else if (mSettings.getAllowContentAccess() &&
                   url.startsWith(ANDROID_CONTENT)) {
            try {
                // Strip off mimetype, for compatibility with ContentLoader.java
                // If we don't do this, we can fail to load Gmail attachments,
                // because the URL being loaded doesn't exactly match the URL we
                // have permission to read.
                // Strip off MIME type. If we don't do this, we can fail to
                // load Gmail attachments, because the URL being loaded doesn't
                // exactly match the URL we have permission to read.
                int mimeIndex = url.lastIndexOf('?');
                if (mimeIndex != -1) {
                    url = url.substring(0, mimeIndex);
@@ -786,102 +769,12 @@ class BrowserFrame extends Handler {
        }
    }

    /**
     * Start loading a resource.
     * @param loaderHandle The native ResourceLoader that is the target of the
     *                     data.
     * @param url The url to load.
     * @param method The http method.
     * @param headers The http headers.
     * @param postData If the method is "POST" postData is sent as the request
     *                 body. Is null when empty.
     * @param postDataIdentifier If the post data contained form this is the form identifier, otherwise it is 0.
     * @param cacheMode The cache mode to use when loading this resource. See WebSettings.setCacheMode
     * @param mainResource True if the this resource is the main request, not a supporting resource
     * @param userGesture
     * @param synchronous True if the load is synchronous.
     * @return A newly created LoadListener object.
     */
    private LoadListener startLoadingResource(int loaderHandle,
                                              String url,
                                              String method,
                                              HashMap headers,
                                              byte[] postData,
                                              long postDataIdentifier,
                                              int cacheMode,
                                              boolean mainResource,
                                              boolean userGesture,
                                              boolean synchronous,
                                              String username,
                                              String password) {
        if (mSettings.getCacheMode() != WebSettings.LOAD_DEFAULT) {
            cacheMode = mSettings.getCacheMode();
        }

        if (method.equals("POST")) {
            // Don't use the cache on POSTs when issuing a normal POST
            // request.
            if (cacheMode == WebSettings.LOAD_NORMAL) {
                cacheMode = WebSettings.LOAD_NO_CACHE;
            }
            String[] ret = getUsernamePassword();
            if (ret != null) {
                String domUsername = ret[0];
                String domPassword = ret[1];
                maybeSavePassword(postData, domUsername, domPassword);
            }
        }

        // is this resource the main-frame top-level page?
        boolean isMainFramePage = mIsMainFrame;

        if (DebugFlags.BROWSER_FRAME) {
            Log.v(LOGTAG, "startLoadingResource: url=" + url + ", method="
                    + method + ", postData=" + postData + ", isMainFramePage="
                    + isMainFramePage + ", mainResource=" + mainResource
                    + ", userGesture=" + userGesture);
        }

        // Create a LoadListener
        LoadListener loadListener = LoadListener.getLoadListener(mContext,
                this, url, loaderHandle, synchronous, isMainFramePage,
                mainResource, userGesture, postDataIdentifier, username, password);

        if (LoadListener.getNativeLoaderCount() > MAX_OUTSTANDING_REQUESTS) {
            // send an error message, so that loadListener can be deleted
            // after this is returned. This is important as LoadListener's 
            // nativeError will remove the request from its DocLoader's request
            // list. But the set up is not done until this method is returned.
            loadListener.error(
                    android.net.http.EventHandler.ERROR, mContext.getString(
                            com.android.internal.R.string.httpErrorTooManyRequests));
            return loadListener;
        }

        // Note that we are intentionally skipping
        // inputStreamForAndroidResource.  This is so that FrameLoader will use
        // the various StreamLoader classes to handle assets.
        FrameLoader loader = new FrameLoader(loadListener, mSettings, method,
                mCallbackProxy.shouldInterceptRequest(url));
        loader.setHeaders(headers);
        loader.setPostData(postData);
        // Set the load mode to the mode used for the current page.
        // If WebKit wants validation, go to network directly.
        loader.setCacheMode(headers.containsKey("If-Modified-Since")
                || headers.containsKey("If-None-Match") ? 
                        WebSettings.LOAD_NO_CACHE : cacheMode);
        loader.executeLoad();
        // Set referrer to current URL?
        return !synchronous ? loadListener : null;
    }

    /**
     * If this looks like a POST request (form submission) containing a username
     * and password, give the user the option of saving them. Will either do
     * nothing, or block until the UI interaction is complete.
     *
     * Called by startLoadingResource when using the Apache HTTP stack.
     * Called directly by WebKit when using the Chrome HTTP stack.
     * Called directly by WebKit.
     *
     * @param postData The data about to be sent as the body of a POST request.
     * @param username The username entered by the user (sniffed from the DOM).
+0 −79
Original line number Diff line number Diff line
/*
 * Copyright (C) 2007 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 android.webkit;

import android.net.http.Headers;
import android.text.TextUtils;
import android.webkit.JniUtil;

/**
 * This class is a concrete implementation of StreamLoader that uses a
 * CacheResult as the source for the stream. The CacheResult stored mimetype
 * and encoding is added to the HTTP response headers.
 */
class CacheLoader extends StreamLoader {

    CacheManager.CacheResult mCacheResult;  // Content source

    /**
     * Constructs a CacheLoader for use when loading content from the cache.
     *
     * @param loadListener LoadListener to pass the content to
     * @param result CacheResult used as the source for the content.
     */
    CacheLoader(LoadListener loadListener, CacheManager.CacheResult result) {
        super(loadListener);

        assert !JniUtil.useChromiumHttpStack();

        mCacheResult = result;
    }

    @Override
    protected boolean setupStreamAndSendStatus() {
        mDataStream = mCacheResult.inStream;
        mContentLength = mCacheResult.contentLength;
        mLoadListener.status(1, 1, mCacheResult.httpStatusCode, "OK");
        return true;
    }

    @Override
    protected void buildHeaders(Headers headers) {
        StringBuilder sb = new StringBuilder(mCacheResult.mimeType);
        if (!TextUtils.isEmpty(mCacheResult.encoding)) {
            sb.append(';');
            sb.append(mCacheResult.encoding);
        }
        headers.setContentType(sb.toString());

        if (!TextUtils.isEmpty(mCacheResult.location)) {
            headers.setLocation(mCacheResult.location);
        }

        if (!TextUtils.isEmpty(mCacheResult.expiresString)) {
            headers.setExpires(mCacheResult.expiresString);
        }

        if (!TextUtils.isEmpty(mCacheResult.contentdisposition)) {
            headers.setContentDisposition(mCacheResult.contentdisposition);
        }

        if (!TextUtils.isEmpty(mCacheResult.crossDomain)) {
            headers.setXPermittedCrossDomainPolicies(mCacheResult.crossDomain);
        }
    }
}
+26 −610

File changed.

Preview size limit exceeded, changes collapsed.

+0 −8
Original line number Diff line number Diff line
@@ -920,10 +920,6 @@ class CallbackProxy extends Handler {
        if (PERF_PROBE) {
            mWebCoreThreadTime = SystemClock.currentThreadTimeMillis();
            mWebCoreIdleTime = 0;
            if (!JniUtil.useChromiumHttpStack()) {
                // Network is only used with the Android HTTP stack.
                Network.getInstance(mContext).startTiming();
            }
            // un-comment this if PERF_PROBE is true
//            Looper.myQueue().setWaitCallback(mIdleCallback);
        }
@@ -941,10 +937,6 @@ class CallbackProxy extends Handler {
            Log.d("WebCore", "WebCore thread used " +
                    (SystemClock.currentThreadTimeMillis() - mWebCoreThreadTime)
                    + " ms and idled " + mWebCoreIdleTime + " ms");
            if (!JniUtil.useChromiumHttpStack()) {
                // Network is only used with the Android HTTP stack.
                Network.getInstance(mContext).stopTiming();
            }
        }
        Message msg = obtainMessage(PAGE_FINISHED, url);
        sendMessage(msg);
+0 −98
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 android.webkit;

import android.net.http.EventHandler;
import android.net.http.Headers;
import android.net.Uri;

/**
 * This class is a concrete implementation of StreamLoader that loads
 * "content:" URIs
 */
class ContentLoader extends StreamLoader {

    private String mUrl;
    private String mContentType;

    /**
     * Construct a ContentLoader with the specified content URI
     *
     * @param rawUrl "content:" url pointing to content to be loaded. This url
     *               is the same url passed in to the WebView.
     * @param loadListener LoadListener to pass the content to
     */
    ContentLoader(String rawUrl, LoadListener loadListener) {
        super(loadListener);

        /* strip off mimetype */
        int mimeIndex = rawUrl.lastIndexOf('?');
        if (mimeIndex != -1) {
            mUrl = rawUrl.substring(0, mimeIndex);
            mContentType = rawUrl.substring(mimeIndex + 1);
        } else {
            mUrl = rawUrl;
        }

    }

    private String errString(Exception ex) {
        String exMessage = ex.getMessage();
        String errString = mContext.getString(
                com.android.internal.R.string.httpErrorFileNotFound);
        if (exMessage != null) {
            errString += " " + exMessage;
        }
        return errString;
    }

    @Override
    protected boolean setupStreamAndSendStatus() {
        Uri uri = Uri.parse(mUrl);
        if (uri == null) {
            mLoadListener.error(
                    EventHandler.FILE_NOT_FOUND_ERROR,
                    mContext.getString(
                            com.android.internal.R.string.httpErrorBadUrl) +
                    " " + mUrl);
            return false;
        }

        try {
            mDataStream = mContext.getContentResolver().openInputStream(uri);
            mLoadListener.status(1, 1, 200, "OK");
        } catch (java.io.FileNotFoundException ex) {
            mLoadListener.error(EventHandler.FILE_NOT_FOUND_ERROR, errString(ex));
            return false;
        } catch (RuntimeException ex) {
            // readExceptionWithFileNotFoundExceptionFromParcel in DatabaseUtils
            // can throw a serial of RuntimeException. Catch them all here.
            mLoadListener.error(EventHandler.FILE_ERROR, errString(ex));
            return false;
        }
        return true;
    }

    @Override
    protected void buildHeaders(Headers headers) {
        if (mContentType != null) {
            headers.setContentType("text/html");
        }
        // content can change, we don't want WebKit to cache it
        headers.setCacheControl("no-store, no-cache");
    }
}
Loading