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

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

Merge "[Rlog47] Replayer service, inspect-researchLog.py"

parents ee456af9 588d9b5c
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -313,6 +313,10 @@
    <!-- TODO: remove translatable=false attribute once text is stable -->
    <string name="research_log_uploader_name" translatable="false">Research Uploader Service</string>

    <!-- Name for the research replaying service to be displayed to users.  [CHAR LIMIT=50] -->
    <!-- TODO: remove translatable=false attribute once text is stable -->
    <string name="research_log_replayer_name" translatable="false">Research Replayer Service</string>

    <!-- Preference for input language selection -->
    <string name="select_language">Input languages</string>

+23 −10
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 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
 * 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.
 * 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.inputmethod.research;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
@@ -40,6 +41,14 @@ public class Replayer {
    private boolean mIsReplaying = false;
    private KeyboardSwitcher mKeyboardSwitcher;

    private Replayer() {
    }

    private static final Replayer sInstance = new Replayer();
    public static Replayer getInstance() {
        return sInstance;
    }

    public void setKeyboardSwitcher(final KeyboardSwitcher keyboardSwitcher) {
        mKeyboardSwitcher = keyboardSwitcher;
    }
@@ -49,7 +58,7 @@ public class Replayer {
    private static final int COMPLETION_TIME_MS = 500;

    // TODO: Support historical events and multi-touch.
    public void replay(final ReplayData replayData) {
    public void replay(final ReplayData replayData, final Runnable callback) {
        if (mIsReplaying) {
            return;
        }
@@ -72,7 +81,7 @@ public class Replayer {
        // The adjustment needed to translate times from the original recorded time to the current
        // time.
        final long timeAdjustment = currentStartTime - origStartTime;
        final Handler handler = new Handler() {
        final Handler handler = new Handler(Looper.getMainLooper()) {
            // Track the time of the most recent DOWN event, to be passed as a parameter when
            // constructing a MotionEvent.  It's initialized here to the origStartTime, but this is
            // only a precaution.  The value should be overwritten by the first ACTION_DOWN event
@@ -113,8 +122,12 @@ public class Replayer {
                Log.d(TAG, "queuing event at " + msgTime);
            }
        }

        final long presentDoneTime = replayData.mTimes.get(numActions - 1) + timeAdjustment
                + COMPLETION_TIME_MS;
        handler.sendMessageAtTime(Message.obtain(handler, MSG_DONE), presentDoneTime);
        if (callback != null) {
            handler.postAtTime(callback, presentDoneTime + 1);
        }
    }
}
+65 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 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.inputmethod.research;

import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

import com.android.inputmethod.research.MotionEventReader.ReplayData;

import java.io.File;
import java.util.concurrent.TimeUnit;

/**
 * Provide a mechanism to invoke the replayer from outside.
 *
 * In particular, makes access from a host possible through {@code adb am startservice}.
 */
public class ReplayerService extends IntentService {
    private static final String TAG = ReplayerService.class.getSimpleName();
    private static final String EXTRA_FILENAME = "com.android.inputmethod.research.extra.FILENAME";
    private static final long MAX_REPLAY_TIME = TimeUnit.SECONDS.toMillis(60);

    public ReplayerService() {
        super(ReplayerService.class.getSimpleName());
    }

    @Override
    protected void onHandleIntent(final Intent intent) {
        final String filename = intent.getStringExtra(EXTRA_FILENAME);
        if (filename == null) return;

        final ReplayData replayData = new MotionEventReader().readMotionEventData(
                new File(filename));
        synchronized (this) {
            Replayer.getInstance().replay(replayData, new Runnable() {
                @Override
                public void run() {
                    synchronized (ReplayerService.this) {
                        ReplayerService.this.notify();
                    }
                }
            });
            try {
                wait(MAX_REPLAY_TIME);
            } catch (InterruptedException e) {
                Log.e(TAG, "Timeout while replaying.", e);
            }
        }
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -187,7 +187,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
    /* package for test */ LatinIME mLatinIME;
    private final Statistics mStatistics;
    private final MotionEventReader mMotionEventReader = new MotionEventReader();
    private final Replayer mReplayer = new Replayer();
    private final Replayer mReplayer = Replayer.getInstance();

    private Intent mUploadIntent;
    private Intent mUploadNowIntent;
@@ -783,7 +783,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
                public void run() {
                    final ReplayData replayData =
                            mMotionEventReader.readMotionEventData(mUserRecordingFile);
                    mReplayer.replay(replayData);
                    mReplayer.replay(replayData, null);
                }
            }, 1000);
        }