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

Commit 293fc50e authored by Ziad Youssef's avatar Ziad Youssef
Browse files

Add pin webview to memory logic to Update Service V2

Test:  atest com.android.server.webkit.WebViewUpdateServiceTest

Bug: 308907090
Bug: 307594624
Change-Id: I52763b9dc1ddb283aa56f37b06d619df90e8af5b
parent af862b0d
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.server.webkit;

import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
@@ -31,8 +32,12 @@ import android.webkit.WebViewFactory;
import android.webkit.WebViewProviderInfo;
import android.webkit.WebViewProviderResponse;

import com.android.server.LocalServices;
import com.android.server.PinnerService;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
@@ -83,6 +88,8 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {
    private static final int VALIDITY_INCORRECT_SIGNATURE = 3;
    private static final int VALIDITY_NO_LIBRARY_FLAG = 4;

    private static final String PIN_GROUP = "webview";

    private final SystemInterface mSystemInterface;
    private final Context mContext;

@@ -349,6 +356,39 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {
        return newPackage;
    }

    private void pinWebviewIfRequired(ApplicationInfo appInfo) {
        PinnerService pinnerService = LocalServices.getService(PinnerService.class);
        if (pinnerService == null) {
            // This happens in unit tests which do not have services.
            return;
        }
        int webviewPinQuota = pinnerService.getWebviewPinQuota();
        if (webviewPinQuota <= 0) {
            return;
        }

        pinnerService.unpinGroup(PIN_GROUP);

        ArrayList<String> apksToPin = new ArrayList<>();
        boolean pinSharedFirst = appInfo.metaData.getBoolean("PIN_SHARED_LIBS_FIRST", true);
        for (String sharedLib : appInfo.sharedLibraryFiles) {
            apksToPin.add(sharedLib);
        }
        apksToPin.add(appInfo.sourceDir);
        if (!pinSharedFirst) {
            // We want to prioritize pinning of the native library that is most likely used by apps
            // which in some build flavors live in the main apk and as a shared library for others.
            Collections.reverse(apksToPin);
        }
        for (String apk : apksToPin) {
            if (webviewPinQuota <= 0) {
                break;
            }
            int bytesPinned = pinnerService.pinFile(apk, webviewPinQuota, appInfo, PIN_GROUP);
            webviewPinQuota -= bytesPinned;
        }
    }

    /**
     * This is called when we change WebView provider, either when the current provider is
     * updated or a new provider is chosen / takes precedence.
@@ -357,6 +397,7 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {
        synchronized (mLock) {
            mAnyWebViewInstalled = true;
            if (mNumRelroCreationsStarted == mNumRelroCreationsFinished) {
                pinWebviewIfRequired(newPackage.applicationInfo);
                mCurrentWebViewPackage = newPackage;

                // The relro creations might 'finish' (not start at all) before