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

Commit 5e75e15a authored by Kurt Partridge's avatar Kurt Partridge Committed by Android (Google) Code Review
Browse files

Merge "[Lazy1] Switch to blocking log closures"

parents dbfd2825 7423005b
Loading
Loading
Loading
Loading
+32 −15
Original line number Diff line number Diff line
@@ -20,11 +20,11 @@ import android.content.Context;
import android.util.JsonWriter;
import android.util.Log;

import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.define.ProductionFlag;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
@@ -54,7 +54,6 @@ public class ResearchLog {
    private static final String TAG = ResearchLog.class.getSimpleName();
    private static final boolean DEBUG = false && ProductionFlag.IS_EXPERIMENTAL_DEBUG;
    private static final long FLUSH_DELAY_IN_MS = 1000 * 5;
    private static final int ABORT_TIMEOUT_IN_MS = 1000 * 4;

    /* package */ final ScheduledExecutorService mExecutor;
    /* package */ final File mFile;
@@ -100,7 +99,7 @@ public class ResearchLog {
     *
     * See class comment for details about {@code JsonWriter} construction.
     */
    public synchronized void close(final Runnable onClosed) {
    private synchronized void close(final Runnable onClosed) {
        mExecutor.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
@@ -131,15 +130,22 @@ public class ResearchLog {
        mExecutor.shutdown();
    }

    private boolean mIsAbortSuccessful;

    /**
     * Waits for publication requests to finish, closes the {@link JsonWriter}, but then deletes the
     * backing file used for output.
     * Block until the research log has shut down and spooled out all output or {@code timeout}
     * occurs.
     *
     * See class comment for details about {@code JsonWriter} construction.
     * @param timeout time to wait for close in milliseconds
     */
    public void blockingClose(final long timeout) {
        close(null);
        awaitTermination(timeout, TimeUnit.MILLISECONDS);
    }

    /**
     * Waits for publication requests to finish, closes the JsonWriter, but then deletes the backing
     * output file.
     */
    public synchronized void abort() {
    private synchronized void abort() {
        mExecutor.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
@@ -151,7 +157,7 @@ public class ResearchLog {
                    }
                } finally {
                    if (mFile != null) {
                        mIsAbortSuccessful = mFile.delete();
                        mFile.delete();
                    }
                }
                return null;
@@ -161,14 +167,25 @@ public class ResearchLog {
        mExecutor.shutdown();
    }

    public boolean blockingAbort() throws InterruptedException {
    /**
     * Block until the research log has aborted or {@code timeout} occurs.
     *
     * @param timeout time to wait for close in milliseconds
     */
    public void blockingAbort(final long timeout) {
        abort();
        mExecutor.awaitTermination(ABORT_TIMEOUT_IN_MS, TimeUnit.MILLISECONDS);
        return mIsAbortSuccessful;
        awaitTermination(timeout, TimeUnit.MILLISECONDS);
    }

    public void awaitTermination(int delay, TimeUnit timeUnit) throws InterruptedException {
        mExecutor.awaitTermination(delay, timeUnit);
    @UsedForTesting
    public void awaitTermination(final long delay, final TimeUnit timeUnit) {
        try {
            if (!mExecutor.awaitTermination(delay, timeUnit)) {
                Log.e(TAG, "ResearchLog executor timed out while awaiting terminaion");
            }
        } catch (final InterruptedException e) {
            Log.e(TAG, "ResearchLog executor interrupted while awaiting terminaion", e);
        }
    }

    /* package */ synchronized void flush() {
+13 −27
Original line number Diff line number Diff line
@@ -154,6 +154,9 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
    private static final int MAX_INPUTVIEW_LENGTH_TO_CAPTURE = 8192; // must be >=1
    private static final String PREF_RESEARCH_SAVED_CHANNEL = "pref_research_saved_channel";

    private static final long RESEARCHLOG_CLOSE_TIMEOUT_IN_MS = 5 * 1000;
    private static final long RESEARCHLOG_ABORT_TIMEOUT_IN_MS = 5 * 1000;

    private static final ResearchLogger sInstance = new ResearchLogger();
    private static String sAccountType = null;
    private static String sAllowedAccountDomain = null;
@@ -502,42 +505,29 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
            commitCurrentLogUnit();
            mMainLogBuffer.setIsStopping();
            mMainLogBuffer.shiftAndPublishAll();
            mMainResearchLog.close(null /* callback */);
            mMainResearchLog.blockingClose(RESEARCHLOG_CLOSE_TIMEOUT_IN_MS);
            mMainLogBuffer = null;
        }
        if (mFeedbackLogBuffer != null) {
            mFeedbackLog.close(null /* callback */);
            mFeedbackLog.blockingClose(RESEARCHLOG_CLOSE_TIMEOUT_IN_MS);
            mFeedbackLogBuffer = null;
        }
    }

    public boolean abort() {
    public void abort() {
        if (DEBUG) {
            Log.d(TAG, "abort called");
        }
        boolean didAbortMainLog = false;
        if (mMainLogBuffer != null) {
            mMainLogBuffer.clear();
            try {
                didAbortMainLog = mMainResearchLog.blockingAbort();
            } catch (InterruptedException e) {
                // Don't know whether this succeeded or not.  We assume not; this is reported
                // to the caller.
            }
            mMainResearchLog.blockingAbort(RESEARCHLOG_ABORT_TIMEOUT_IN_MS);
            mMainLogBuffer = null;
        }
        boolean didAbortFeedbackLog = false;
        if (mFeedbackLogBuffer != null) {
            mFeedbackLogBuffer.clear();
            try {
                didAbortFeedbackLog = mFeedbackLog.blockingAbort();
            } catch (InterruptedException e) {
                // Don't know whether this succeeded or not.  We assume not; this is reported
                // to the caller.
            }
            mFeedbackLog.blockingAbort(RESEARCHLOG_ABORT_TIMEOUT_IN_MS);
            mFeedbackLogBuffer = null;
        }
        return didAbortMainLog && didAbortFeedbackLog;
    }

    private void restart() {
@@ -620,7 +610,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang

    private void startRecordingInternal() {
        if (mUserRecordingLog != null) {
            mUserRecordingLog.abort();
            mUserRecordingLog.blockingAbort(RESEARCHLOG_ABORT_TIMEOUT_IN_MS);
        }
        mUserRecordingFile = createUserRecordingFile(mFilesDir);
        mUserRecordingLog = new ResearchLog(mUserRecordingFile, mLatinIME);
@@ -658,7 +648,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang

    private void cancelRecording() {
        if (mUserRecordingLog != null) {
            mUserRecordingLog.abort();
            mUserRecordingLog.blockingAbort(RESEARCHLOG_ABORT_TIMEOUT_IN_MS);
        }
        mUserRecordingLog = null;
        mUserRecordingLogBuffer = null;
@@ -670,7 +660,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
    private void saveRecording() {
        commitCurrentLogUnit();
        publishLogBuffer(mUserRecordingLogBuffer, mUserRecordingLog, true);
        mUserRecordingLog.close(null);
        mUserRecordingLog.blockingClose(RESEARCHLOG_CLOSE_TIMEOUT_IN_MS);
        mUserRecordingLog = null;
        mUserRecordingLogBuffer = null;

@@ -782,12 +772,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
                feedbackContents, accountName, recording);
        mFeedbackLogBuffer.shiftIn(feedbackLogUnit);
        publishLogBuffer(mFeedbackLogBuffer, mSavedFeedbackLog, true /* isIncludingPrivateData */);
        mSavedFeedbackLog.close(new Runnable() {
            @Override
            public void run() {
        mSavedFeedbackLog.blockingClose(RESEARCHLOG_CLOSE_TIMEOUT_IN_MS);
        uploadNow();
            }
        });

        if (isIncludingRecording && DEBUG_REPLAY_AFTER_FEEDBACK) {
            final Handler handler = new Handler();