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

Commit 398e49c8 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Avoid loading the full file to memory in ConfigUpdateInstallReceiver"

parents 931bbaab 8b1ce905
Loading
Loading
Loading
Loading
+18 −11
Original line number Diff line number Diff line
@@ -16,25 +16,30 @@

package com.android.server.updates;

import com.android.internal.util.HexDump;
import android.os.FileUtils;
import android.system.Os;
import android.system.ErrnoException;
import android.system.Os;
import android.util.Base64;
import android.util.Slog;

import com.android.internal.util.HexDump;

import libcore.io.Streams;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.StringBufferInputStream;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.PublicKey;
import java.security.NoSuchAlgorithmException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class CertificateTransparencyLogInstallReceiver extends ConfigUpdateInstallReceiver {

@@ -46,14 +51,13 @@ public class CertificateTransparencyLogInstallReceiver extends ConfigUpdateInsta
    }

    @Override
    protected void install(byte[] content, int version) throws IOException {
    protected void install(InputStream inputStream, int version) throws IOException {
        /* Install is complicated here because we translate the input, which is a JSON file
         * containing log information to a directory with a file per log. To support atomically
         * replacing the old configuration directory with the new there's a bunch of steps. We
         * create a new directory with the logs and then do an atomic update of the current symlink
         * to point to the new directory.
         */

        // 1. Ensure that the update dir exists and is readable
        updateDir.mkdir();
        if (!updateDir.isDirectory()) {
@@ -72,7 +76,8 @@ public class CertificateTransparencyLogInstallReceiver extends ConfigUpdateInsta
            // and so we cannot delete the directory since its in use. Instead just bump the version
            // and return.
            if (newVersion.getCanonicalPath().equals(currentSymlink.getCanonicalPath())) {
                writeUpdate(updateDir, updateVersion, Long.toString(version).getBytes());
                writeUpdate(updateDir, updateVersion,
                        new ByteArrayInputStream(Long.toString(version).getBytes()));
                deleteOldLogDirectories();
                return;
            } else {
@@ -92,6 +97,7 @@ public class CertificateTransparencyLogInstallReceiver extends ConfigUpdateInsta

            // 4. For each log in the log file create the corresponding file in <new_version>/ .
            try {
                byte[] content = Streams.readFullyNoClose(inputStream);
                JSONObject json = new JSONObject(new String(content, StandardCharsets.UTF_8));
                JSONArray logs = json.getJSONArray("logs");
                for (int i = 0; i < logs.length(); i++) {
@@ -119,7 +125,8 @@ public class CertificateTransparencyLogInstallReceiver extends ConfigUpdateInsta
        }
        Slog.i(TAG, "CT log directory updated to " + newVersion.getAbsolutePath());
        // 7. Update the current version information
        writeUpdate(updateDir, updateVersion, Long.toString(version).getBytes());
        writeUpdate(updateDir, updateVersion,
                new ByteArrayInputStream(Long.toString(version).getBytes()));
        // 8. Cleanup
        deleteOldLogDirectories();
    }
+20 −22
Original line number Diff line number Diff line
@@ -16,9 +16,6 @@

package com.android.server.updates;

import com.android.server.EventLogTags;
import com.android.internal.util.HexDump;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -26,6 +23,14 @@ import android.net.Uri;
import android.util.EventLog;
import android.util.Slog;

import com.android.internal.util.HexDump;
import com.android.server.EventLogTags;

import libcore.io.IoUtils;
import libcore.io.Streams;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -33,9 +38,6 @@ import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import libcore.io.IoUtils;
import libcore.io.Streams;

public class ConfigUpdateInstallReceiver extends BroadcastReceiver {

    private static final String TAG = "ConfigUpdateInstallReceiver";
@@ -61,8 +63,6 @@ public class ConfigUpdateInstallReceiver extends BroadcastReceiver {
            @Override
            public void run() {
                try {
                    // get the content path from the extras
                    byte[] altContent = getAltContent(context, intent);
                    // get the version from the extras
                    int altVersion = getVersionFromIntent(intent);
                    // get the previous value from the extras
@@ -79,7 +79,9 @@ public class ConfigUpdateInstallReceiver extends BroadcastReceiver {
                    } else {
                        // install the new content
                        Slog.i(TAG, "Found new update, installing...");
                        try (BufferedInputStream altContent = getAltContent(context, intent)) {
                            install(altContent, altVersion);
                        }
                        Slog.i(TAG, "Installation successful");
                        postInstall(context, intent);
                    }
@@ -130,14 +132,9 @@ public class ConfigUpdateInstallReceiver extends BroadcastReceiver {
        }
    }

    private byte[] getAltContent(Context c, Intent i) throws IOException {
    private BufferedInputStream getAltContent(Context c, Intent i) throws IOException {
        Uri content = getContentFromIntent(i);
        InputStream is = c.getContentResolver().openInputStream(content);
        try {
            return Streams.readFullyNoClose(is);
        } finally {
            is.close();
        }
        return new BufferedInputStream(c.getContentResolver().openInputStream(content));
    }

    private byte[] getCurrentContent() {
@@ -175,7 +172,7 @@ public class ConfigUpdateInstallReceiver extends BroadcastReceiver {
        return current.equals(required);
    }

    protected void writeUpdate(File dir, File file, byte[] content) throws IOException {
    protected void writeUpdate(File dir, File file, InputStream inputStream) throws IOException {
        FileOutputStream out = null;
        File tmp = null;
        try {
@@ -192,7 +189,7 @@ public class ConfigUpdateInstallReceiver extends BroadcastReceiver {
            tmp.setReadable(true, false);
            // write to it
            out = new FileOutputStream(tmp);
            out.write(content);
            Streams.copy(inputStream, out);
            // sync to disk
            out.getFD().sync();
            // atomic rename
@@ -207,9 +204,10 @@ public class ConfigUpdateInstallReceiver extends BroadcastReceiver {
        }
    }

    protected void install(byte[] content, int version) throws IOException {
        writeUpdate(updateDir, updateContent, content);
        writeUpdate(updateDir, updateVersion, Long.toString(version).getBytes());
    protected void install(InputStream inputStream, int version) throws IOException {
        writeUpdate(updateDir, updateContent, inputStream);
        writeUpdate(updateDir, updateVersion,
                new ByteArrayInputStream(Long.toString(version).getBytes()));
    }

    protected void postInstall(Context context, Intent intent) {