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

Commit 49b79e55 authored by Chris Wailes's avatar Chris Wailes Committed by Christian Wailes
Browse files

Code cleanup in ZygoteConection.java

Generic code cleanup and modernization for ZygoteConnection.

Test: m & flash & boot device
Change-Id: I56bff2aaae4ff98c687cb2c2998f857cfdc86295
Merged-In: I56bff2aaae4ff98c687cb2c2998f857cfdc86295
(cherry picked from commit 1f26331d)
parent 142f8596
Loading
Loading
Loading
Loading
+106 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.android.internal.os;

import android.metrics.LogMaker;
import android.os.Process;
import android.util.StatsLog;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;

import dalvik.system.VMRuntime.HiddenApiUsageLogger;

class StatsdHiddenApiUsageLogger implements HiddenApiUsageLogger {

    private final MetricsLogger mMetricsLogger = new MetricsLogger();
    private static final StatsdHiddenApiUsageLogger sInstance = new StatsdHiddenApiUsageLogger();
    private int mHiddenApiAccessLogSampleRate = 0;
    private int mHiddenApiAccessStatslogSampleRate = 0;

    static void setHiddenApiAccessLogSampleRates(int sampleRate, int newSampleRate) {
        sInstance.mHiddenApiAccessLogSampleRate = sampleRate;
        sInstance.mHiddenApiAccessStatslogSampleRate = newSampleRate;
    }

    static StatsdHiddenApiUsageLogger getInstance() {
        return StatsdHiddenApiUsageLogger.sInstance;
    }

    public void hiddenApiUsed(int sampledValue, String packageName, String signature,
            int accessMethod, boolean accessDenied) {
        if (sampledValue < mHiddenApiAccessLogSampleRate) {
            logUsage(packageName, signature, accessMethod, accessDenied);
        }

        if (sampledValue < mHiddenApiAccessStatslogSampleRate) {
            newLogUsage(signature, accessMethod, accessDenied);
        }
    }

    private void logUsage(String packageName, String signature, int accessMethod,
            boolean accessDenied) {
        int accessMethodMetric = HiddenApiUsageLogger.ACCESS_METHOD_NONE;
        switch(accessMethod) {
            case HiddenApiUsageLogger.ACCESS_METHOD_NONE:
                accessMethodMetric = MetricsEvent.ACCESS_METHOD_NONE;
                break;
            case HiddenApiUsageLogger.ACCESS_METHOD_REFLECTION:
                accessMethodMetric = MetricsEvent.ACCESS_METHOD_REFLECTION;
                break;
            case HiddenApiUsageLogger.ACCESS_METHOD_JNI:
                accessMethodMetric = MetricsEvent.ACCESS_METHOD_JNI;
                break;
            case HiddenApiUsageLogger.ACCESS_METHOD_LINKING:
                accessMethodMetric = MetricsEvent.ACCESS_METHOD_LINKING;
                break;
        }

        LogMaker logMaker = new LogMaker(MetricsEvent.ACTION_HIDDEN_API_ACCESSED)
                .setPackageName(packageName)
                .addTaggedData(MetricsEvent.FIELD_HIDDEN_API_SIGNATURE, signature)
                .addTaggedData(MetricsEvent.FIELD_HIDDEN_API_ACCESS_METHOD,
                    accessMethodMetric);

        if (accessDenied) {
            logMaker.addTaggedData(MetricsEvent.FIELD_HIDDEN_API_ACCESS_DENIED, 1);
        }

        mMetricsLogger.write(logMaker);
    }

    private void newLogUsage(String signature, int accessMethod, boolean accessDenied) {
        int accessMethodProto = StatsLog.HIDDEN_API_USED__ACCESS_METHOD__NONE;
        switch(accessMethod) {
            case HiddenApiUsageLogger.ACCESS_METHOD_NONE:
                accessMethodProto = StatsLog.HIDDEN_API_USED__ACCESS_METHOD__NONE;
                break;
            case HiddenApiUsageLogger.ACCESS_METHOD_REFLECTION:
                accessMethodProto = StatsLog.HIDDEN_API_USED__ACCESS_METHOD__REFLECTION;
                break;
            case HiddenApiUsageLogger.ACCESS_METHOD_JNI:
                accessMethodProto = StatsLog.HIDDEN_API_USED__ACCESS_METHOD__JNI;
                break;
            case HiddenApiUsageLogger.ACCESS_METHOD_LINKING:
                accessMethodProto = StatsLog.HIDDEN_API_USED__ACCESS_METHOD__LINKING;
                break;
        }

        int uid = Process.myUid();
        StatsLog.write(StatsLog.HIDDEN_API_USED, uid, signature, accessMethodProto, accessDenied);
    }
}
+20 −100
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import static com.android.internal.os.ZygoteConnectionConstants.WRAPPED_PID_TIME

import android.annotation.UnsupportedAppUsage;
import android.content.pm.ApplicationInfo;
import android.metrics.LogMaker;
import android.net.Credentials;
import android.net.LocalSocket;
import android.os.Parcel;
@@ -35,10 +34,6 @@ import android.system.ErrnoException;
import android.system.Os;
import android.system.StructPollfd;
import android.util.Log;
import android.util.StatsLog;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;

import dalvik.system.VMRuntime;

@@ -53,6 +48,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.concurrent.TimeUnit;

/**
 * A connection that can make spawn requests.
@@ -82,17 +78,16 @@ class ZygoteConnection {
     *
     * @param socket non-null; connected socket
     * @param abiList non-null; a list of ABIs this zygote supports.
     * @throws IOException
     * @throws IOException If obtaining the peer credentials fails
     */
    ZygoteConnection(LocalSocket socket, String abiList) throws IOException {
        mSocket = socket;
        this.abiList = abiList;

        mSocketOutStream
                = new DataOutputStream(socket.getOutputStream());

        mSocketReader = new BufferedReader(
                new InputStreamReader(socket.getInputStream()), 256);
        mSocketOutStream = new DataOutputStream(socket.getOutputStream());
        mSocketReader =
                new BufferedReader(
                        new InputStreamReader(socket.getInputStream()), Zygote.SOCKET_BUFFER_SIZE);

        mSocket.setSoTimeout(CONNECTION_TIMEOUT_MILLIS);

@@ -124,8 +119,7 @@ class ZygoteConnection {
     * for by calling {@code ZygoteConnection.isClosedByPeer}.
     */
    Runnable processOneCommand(ZygoteServer zygoteServer) {
        String args[];
        ZygoteArguments parsedArgs = null;
        String[] args;

        try {
            args = Zygote.readArgumentList(mSocketReader);
@@ -140,11 +134,11 @@ class ZygoteConnection {
            return null;
        }

        int pid = -1;
        int pid;
        FileDescriptor childPipeFd = null;
        FileDescriptor serverPipeFd = null;

        parsedArgs = new ZygoteArguments(args);
        ZygoteArguments parsedArgs = new ZygoteArguments(args);

        if (parsedArgs.mAbiListQuery) {
            handleAbiListQuery();
@@ -229,7 +223,7 @@ class ZygoteConnection {
            }
        }

        /**
        /*
         * In order to avoid leaking descriptors to the Zygote child,
         * the native code must close the two Zygote socket descriptors
         * in the child process before it switches from Zygote-root to
@@ -255,8 +249,6 @@ class ZygoteConnection {
            fdsToClose[1] = fd.getInt$();
        }

        fd = null;

        pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
                parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
@@ -390,82 +382,6 @@ class ZygoteConnection {
        }
    }

    private static class HiddenApiUsageLogger implements VMRuntime.HiddenApiUsageLogger {

        private final MetricsLogger mMetricsLogger = new MetricsLogger();
        private static HiddenApiUsageLogger sInstance = new HiddenApiUsageLogger();
        private int mHiddenApiAccessLogSampleRate = 0;
        private int mHiddenApiAccessStatslogSampleRate = 0;

        public static void setHiddenApiAccessLogSampleRates(int sampleRate, int newSampleRate) {
            sInstance.mHiddenApiAccessLogSampleRate = sampleRate;
            sInstance.mHiddenApiAccessStatslogSampleRate = newSampleRate;
        }

        public static HiddenApiUsageLogger getInstance() {
            return HiddenApiUsageLogger.sInstance;
        }

        public void hiddenApiUsed(int sampledValue, String packageName, String signature,
                int accessMethod, boolean accessDenied) {
            if (sampledValue < mHiddenApiAccessLogSampleRate) {
                logUsage(packageName, signature, accessMethod, accessDenied);
            }
            if (sampledValue < mHiddenApiAccessStatslogSampleRate) {
                newLogUsage(signature, accessMethod, accessDenied);
            }
        }

        private void logUsage(String packageName, String signature, int accessMethod,
                                  boolean accessDenied) {
            int accessMethodMetric = HiddenApiUsageLogger.ACCESS_METHOD_NONE;
            switch(accessMethod) {
                case HiddenApiUsageLogger.ACCESS_METHOD_NONE:
                    accessMethodMetric = MetricsEvent.ACCESS_METHOD_NONE;
                    break;
                case HiddenApiUsageLogger.ACCESS_METHOD_REFLECTION:
                    accessMethodMetric = MetricsEvent.ACCESS_METHOD_REFLECTION;
                    break;
                case HiddenApiUsageLogger.ACCESS_METHOD_JNI:
                    accessMethodMetric = MetricsEvent.ACCESS_METHOD_JNI;
                    break;
                case HiddenApiUsageLogger.ACCESS_METHOD_LINKING:
                    accessMethodMetric = MetricsEvent.ACCESS_METHOD_LINKING;
                    break;
            }
            LogMaker logMaker = new LogMaker(MetricsEvent.ACTION_HIDDEN_API_ACCESSED)
                    .setPackageName(packageName)
                    .addTaggedData(MetricsEvent.FIELD_HIDDEN_API_SIGNATURE, signature)
                    .addTaggedData(MetricsEvent.FIELD_HIDDEN_API_ACCESS_METHOD,
                        accessMethodMetric);
            if (accessDenied) {
                logMaker.addTaggedData(MetricsEvent.FIELD_HIDDEN_API_ACCESS_DENIED, 1);
            }
            mMetricsLogger.write(logMaker);
        }

        private void newLogUsage(String signature, int accessMethod, boolean accessDenied) {
            int accessMethodProto = StatsLog.HIDDEN_API_USED__ACCESS_METHOD__NONE;
            switch(accessMethod) {
                case HiddenApiUsageLogger.ACCESS_METHOD_NONE:
                    accessMethodProto = StatsLog.HIDDEN_API_USED__ACCESS_METHOD__NONE;
                    break;
                case HiddenApiUsageLogger.ACCESS_METHOD_REFLECTION:
                    accessMethodProto = StatsLog.HIDDEN_API_USED__ACCESS_METHOD__REFLECTION;
                    break;
                case HiddenApiUsageLogger.ACCESS_METHOD_JNI:
                    accessMethodProto = StatsLog.HIDDEN_API_USED__ACCESS_METHOD__JNI;
                    break;
                case HiddenApiUsageLogger.ACCESS_METHOD_LINKING:
                    accessMethodProto = StatsLog.HIDDEN_API_USED__ACCESS_METHOD__LINKING;
                    break;
            }
            int uid = Process.myUid();
            StatsLog.write(StatsLog.HIDDEN_API_USED, uid, signature,
                                   accessMethodProto, accessDenied);
        }
    }

    /**
     * Changes the API access log sample rate for the Zygote and processes spawned from it.
     *
@@ -485,8 +401,9 @@ class ZygoteConnection {
        return stateChangeWithUsapPoolReset(zygoteServer, () -> {
            int maxSamplingRate = Math.max(samplingRate, statsdSamplingRate);
            ZygoteInit.setHiddenApiAccessLogSampleRate(maxSamplingRate);
            HiddenApiUsageLogger.setHiddenApiAccessLogSampleRates(samplingRate, statsdSamplingRate);
            ZygoteInit.setHiddenApiUsageLogger(HiddenApiUsageLogger.getInstance());
            StatsdHiddenApiUsageLogger.setHiddenApiAccessLogSampleRates(
                    samplingRate, statsdSamplingRate);
            ZygoteInit.setHiddenApiUsageLogger(StatsdHiddenApiUsageLogger.getInstance());
        });
    }

@@ -543,7 +460,7 @@ class ZygoteConnection {
     */
    private Runnable handleChildProc(ZygoteArguments parsedArgs,
            FileDescriptor pipeFd, boolean isZygote) {
        /**
        /*
         * By the time we get here, the native code has closed the two actual Zygote
         * socket connections, and substituted /dev/null in their place.  The LocalSocket
         * objects still need to be closed properly.
@@ -596,11 +513,11 @@ class ZygoteConnection {
                // bail) happens in a timely manner.
                final int BYTES_REQUIRED = 4;  // Bytes in an int.

                StructPollfd fds[] = new StructPollfd[] {
                StructPollfd[] fds = new StructPollfd[] {
                        new StructPollfd()
                };

                byte data[] = new byte[BYTES_REQUIRED];
                byte[] data = new byte[BYTES_REQUIRED];

                int remainingSleepTime = WRAPPED_PID_TIMEOUT_MILLIS;
                int dataIndex = 0;
@@ -614,7 +531,10 @@ class ZygoteConnection {

                    int res = android.system.Os.poll(fds, remainingSleepTime);
                    long endTime = System.nanoTime();
                    int elapsedTimeMs = (int)((endTime - startTime) / 1000000l);
                    int elapsedTimeMs =
                            (int) TimeUnit.MILLISECONDS.convert(
                                    endTime - startTime,
                                    TimeUnit.NANOSECONDS);
                    remainingSleepTime = WRAPPED_PID_TIMEOUT_MILLIS - elapsedTimeMs;

                    if (res > 0) {