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

Commit 01060e66 authored by Chris Wailes's avatar Chris Wailes
Browse files

Added pool management code around zygote state changes.

The hidden api access log sample rate and api blacklist exemption
commands change the state of the zygote and processes spawned from the
zygote.  This means that blastulas spawned before the changes won't have
the proper state.  To fix this we now empty the process pool, apply the
changes, and then refill the pool.

Test: Build and boot
Test: Treehugger
Change-Id: I66b01930a160c1305fbeb8b6243deff7917aa598
parent ae93714d
Loading
Loading
Loading
Loading
+60 −12
Original line number Diff line number Diff line
@@ -185,13 +185,12 @@ class ZygoteConnection {
        }

        if (parsedArgs.mApiBlacklistExemptions != null) {
            handleApiBlacklistExemptions(parsedArgs.mApiBlacklistExemptions);
            return null;
            return handleApiBlacklistExemptions(zygoteServer, parsedArgs.mApiBlacklistExemptions);
        }

        if (parsedArgs.mHiddenApiAccessLogSampleRate != -1) {
            handleHiddenApiAccessLogSampleRate(parsedArgs.mHiddenApiAccessLogSampleRate);
            return null;
            return handleHiddenApiAccessLogSampleRate(zygoteServer,
                    parsedArgs.mHiddenApiAccessLogSampleRate);
        }

        if (parsedArgs.mPermittedCapabilities != 0 || parsedArgs.mEffectiveCapabilities != 0) {
@@ -325,15 +324,53 @@ class ZygoteConnection {
        }
    }

    private void handleApiBlacklistExemptions(String[] exemptions) {
    private Runnable stateChangeWithBlastulaPoolReset(ZygoteServer zygoteServer,
            Runnable stateChangeCode) {
        try {
            ZygoteInit.setApiBlacklistExemptions(exemptions);
            if (zygoteServer.isBlastulaPoolEnabled()) {
                Zygote.emptyBlastulaPool();
            }

            stateChangeCode.run();

            if (zygoteServer.isBlastulaPoolEnabled()) {
                Runnable fpResult =
                        zygoteServer.fillBlastulaPool(
                                new int[]{mSocket.getFileDescriptor().getInt$()});

                if (fpResult != null) {
                    zygoteServer.setForkChild();
                    return fpResult;
                }
            }

            mSocketOutStream.writeInt(0);

            return null;
        } catch (IOException ioe) {
            throw new IllegalStateException("Error writing to command socket", ioe);
        }
    }

    /**
     * Makes the necessary changes to implement a new API blacklist exemption policy, and then
     * responds to the system server, letting it know that the task has been completed.
     *
     * This necessitates a change to the internal state of the Zygote.  As such, if the blastula
     * pool is enabled all existing blastulas have an incorrect API blacklist exemption list.  To
     * properly handle this request the pool must be emptied and refilled.  This process can return
     * a Runnable object that must be returned to ZygoteServer.runSelectLoop to be invoked.
     *
     * @param zygoteServer  The server object that received the request
     * @param exemptions  The new exemption list.
     * @return A Runnable object representing a new app in any blastulas spawned from here; the
     *         zygote process will always receive a null value from this function.
     */
    private Runnable handleApiBlacklistExemptions(ZygoteServer zygoteServer, String[] exemptions) {
        return stateChangeWithBlastulaPoolReset(zygoteServer,
                () -> ZygoteInit.setApiBlacklistExemptions(exemptions));
    }

    private static class HiddenApiUsageLogger implements VMRuntime.HiddenApiUsageLogger {

        private final MetricsLogger mMetricsLogger = new MetricsLogger();
@@ -384,15 +421,26 @@ class ZygoteConnection {
        }
    }

    private void handleHiddenApiAccessLogSampleRate(int samplingRate) {
        try {
    /**
     * Changes the API access log sample rate for the Zygote and processes spawned from it.
     *
     * This necessitates a change to the internal state of the Zygote.  As such, if the blastula
     * pool is enabled all existing blastulas have an incorrect API access log sample rate.  To
     * properly handle this request the pool must be emptied and refilled.  This process can return
     * a Runnable object that must be returned to ZygoteServer.runSelectLoop to be invoked.
     *
     * @param zygoteServer  The server object that received the request
     * @param samplingRate  The new sample rate
     * @return A Runnable object representing a new app in any blastulas spawned from here; the
     *         zygote process will always receive a null value from this function.
     */
    private Runnable handleHiddenApiAccessLogSampleRate(ZygoteServer zygoteServer,
            int samplingRate) {
        return stateChangeWithBlastulaPoolReset(zygoteServer, () -> {
            ZygoteInit.setHiddenApiAccessLogSampleRate(samplingRate);
            HiddenApiUsageLogger.setHiddenApiAccessLogSampleRate(samplingRate);
            ZygoteInit.setHiddenApiUsageLogger(HiddenApiUsageLogger.getInstance());
            mSocketOutStream.writeInt(0);
        } catch (IOException ioe) {
            throw new IllegalStateException("Error writing to command socket", ioe);
        }
        });
    }

    protected void preload() {