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

Commit 81bc3bd9 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

Add SystemApi(MODULE_LIBRARIES) to AtomicFile API

Cleaning up the API in the process

Test: atest android.jobscheduler.cts
Bug: 142281756

Change-Id: Ia52dc6fda867f3015ecbf068a0a69cc0f17cd92a
parent bda69cf1
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.util.AtomicFile;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SystemConfigFileCommitEventLogger;
import android.util.Xml;

import com.android.internal.annotations.GuardedBy;
@@ -102,6 +103,7 @@ public final class JobStore {
    private boolean mWriteInProgress;

    private static final Object sSingletonLock = new Object();
    private final SystemConfigFileCommitEventLogger mEventLogger;
    private final AtomicFile mJobsFile;
    /** Handler backed by IoThread for writing to disk. */
    private final Handler mIoHandler = IoThread.getHandler();
@@ -141,7 +143,8 @@ public final class JobStore {
        File systemDir = new File(dataDir, "system");
        File jobDir = new File(systemDir, "job");
        jobDir.mkdirs();
        mJobsFile = new AtomicFile(new File(jobDir, "jobs.xml"), "jobs");
        mEventLogger = new SystemConfigFileCommitEventLogger("jobs");
        mJobsFile = new AtomicFile(new File(jobDir, "jobs.xml"), mEventLogger);

        mJobSet = new JobSet();

@@ -426,7 +429,7 @@ public final class JobStore {
            int numSystemJobs = 0;
            int numSyncJobs = 0;
            try {
                final long startTime = SystemClock.uptimeMillis();
                mEventLogger.setStartTime(SystemClock.uptimeMillis());
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                XmlSerializer out = new FastXmlSerializer();
                out.setOutput(baos, StandardCharsets.UTF_8.name());
@@ -459,7 +462,7 @@ public final class JobStore {
                out.endDocument();

                // Write out to disk in one fell swoop.
                FileOutputStream fos = mJobsFile.startWrite(startTime);
                FileOutputStream fos = mJobsFile.startWrite();
                fos.write(baos.toByteArray());
                mJobsFile.finishWrite(fos);
            } catch (IOException e) {
+1 −0
Original line number Diff line number Diff line
@@ -51408,6 +51408,7 @@ package android.util {
    method public void failWrite(java.io.FileOutputStream);
    method public void finishWrite(java.io.FileOutputStream);
    method public java.io.File getBaseFile();
    method public long getLastModifiedTime();
    method public java.io.FileInputStream openRead() throws java.io.FileNotFoundException;
    method public byte[] readFully() throws java.io.IOException;
    method public java.io.FileOutputStream startWrite() throws java.io.IOException;
+9 −0
Original line number Diff line number Diff line
@@ -183,9 +183,18 @@ package android.os {

package android.util {

  public class AtomicFile {
    ctor public AtomicFile(@NonNull java.io.File, @Nullable android.util.SystemConfigFileCommitEventLogger);
  }

  public final class Log {
    method public static int logToRadioBuffer(int, @Nullable String, @Nullable String);
  }

  public class SystemConfigFileCommitEventLogger {
    ctor public SystemConfigFileCommitEventLogger(@NonNull String);
    method public void setStartTime(long);
  }

}
+41 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.annotation;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.SOURCE;

import android.os.SystemClock;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
 * @memberDoc Value is a non-negative timestamp in the
 *            {@link SystemClock#uptimeMillis()} time base.
 * @paramDoc Value is a non-negative timestamp in the
 *            {@link SystemClock#uptimeMillis()} time base.
 * @returnDoc Value is a non-negative timestamp in the
 *            {@link SystemClock#uptimeMillis()} time base.
 * @hide
 */
@Retention(SOURCE)
@Target({METHOD, PARAMETER, FIELD})
public @interface UptimeMillisLong {
}
+36 −10
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@

package android.util;

import android.annotation.CurrentTimeMillisLong;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.os.FileUtils;
import android.os.SystemClock;

@@ -48,15 +53,14 @@ import java.util.function.Consumer;
public class AtomicFile {
    private final File mBaseName;
    private final File mBackupName;
    private final String mCommitTag;
    private long mStartTime;
    private SystemConfigFileCommitEventLogger mCommitEventLogger;

    /**
     * Create a new AtomicFile for a file located at the given File path.
     * The secondary backup file will be the same file path with ".bak" appended.
     */
    public AtomicFile(File baseName) {
        this(baseName, null);
        this(baseName, (SystemConfigFileCommitEventLogger) null);
    }

    /**
@@ -64,9 +68,22 @@ public class AtomicFile {
     * automatically log commit events.
     */
    public AtomicFile(File baseName, String commitTag) {
        this(baseName, new SystemConfigFileCommitEventLogger(commitTag));
    }

    /**
     * Internal constructor that also allows you to have the class
     * automatically log commit events.
     *
     * @hide
     */
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    @SuppressLint("StreamFiles")
    public AtomicFile(@NonNull File baseName,
            @Nullable SystemConfigFileCommitEventLogger commitEventLogger) {
        mBaseName = baseName;
        mBackupName = new File(baseName.getPath() + ".bak");
        mCommitTag = commitTag;
        mCommitEventLogger = commitEventLogger;
    }

    /**
@@ -100,7 +117,7 @@ public class AtomicFile {
     * access to AtomicFile.
     */
    public FileOutputStream startWrite() throws IOException {
        return startWrite(mCommitTag != null ? SystemClock.uptimeMillis() : 0);
        return startWrite(0);
    }

    /**
@@ -108,9 +125,19 @@ public class AtomicFile {
     * start time of the operation to adjust how the commit is logged.
     * @param startTime The effective start time of the operation, in the time
     * base of {@link SystemClock#uptimeMillis()}.
     *
     * @deprecated Use {@link SystemConfigFileCommitEventLogger#setStartTime} followed
     * by {@link #startWrite()}
     */
    @Deprecated
    public FileOutputStream startWrite(long startTime) throws IOException {
        mStartTime = startTime;
        if (mCommitEventLogger != null) {
            if (startTime != 0) {
                mCommitEventLogger.setStartTime(startTime);
            }

            mCommitEventLogger.onStartWrite();
        }

        // Rename the current file so it may be used as a backup during the next read
        if (mBaseName.exists()) {
@@ -159,9 +186,8 @@ public class AtomicFile {
            } catch (IOException e) {
                Log.w("AtomicFile", "finishWrite: Got exception:", e);
            }
            if (mCommitTag != null) {
                com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
                        mCommitTag, SystemClock.uptimeMillis() - mStartTime);
            if (mCommitEventLogger != null) {
                mCommitEventLogger.onFinishWrite();
            }
        }
    }
@@ -240,11 +266,11 @@ public class AtomicFile {

    /**
     * Gets the last modified time of the atomic file.
     * {@hide}
     *
     * @return last modified time in milliseconds since epoch.  Returns zero if
     *     the file does not exist or an I/O error is encountered.
     */
    @CurrentTimeMillisLong
    public long getLastModifiedTime() {
        if (mBackupName.exists()) {
            return mBackupName.lastModified();
Loading