13380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler/* 23380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * Copyright (C) 2012 The Android Open Source Project 33380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * 43380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * Licensed under the Apache License, Version 2.0 (the "License"); you may not 53380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * use this file except in compliance with the License. You may obtain a copy of 63380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * the License at 73380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * 83380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * http://www.apache.org/licenses/LICENSE-2.0 93380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * 103380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * Unless required by applicable law or agreed to in writing, software 113380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 123380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 133380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * License for the specific language governing permissions and limitations under 143380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * the License. 153380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler */ 163380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 173380534a62abf20b4509db6068ac02b1b880712fDaniel Sandlerpackage com.android.systemui.statusbar; 183380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 19de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport android.os.Handler; 20de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport android.os.Message; 21de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport android.os.SystemClock; 22de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport android.util.Log; 23de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport android.view.MotionEvent; 24de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlock 253380534a62abf20b4509db6068ac02b1b880712fDaniel Sandlerimport java.io.BufferedWriter; 263380534a62abf20b4509db6068ac02b1b880712fDaniel Sandlerimport java.io.FileDescriptor; 273380534a62abf20b4509db6068ac02b1b880712fDaniel Sandlerimport java.io.FileWriter; 283380534a62abf20b4509db6068ac02b1b880712fDaniel Sandlerimport java.io.IOException; 293380534a62abf20b4509db6068ac02b1b880712fDaniel Sandlerimport java.io.PrintWriter; 303380534a62abf20b4509db6068ac02b1b880712fDaniel Sandlerimport java.util.HashSet; 313380534a62abf20b4509db6068ac02b1b880712fDaniel Sandlerimport java.util.LinkedList; 323380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 333380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler/** 343380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * Convenience class for capturing gestures for later analysis. 353380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler */ 363380534a62abf20b4509db6068ac02b1b880712fDaniel Sandlerpublic class GestureRecorder { 373380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public static final boolean DEBUG = true; // for now 383380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public static final String TAG = GestureRecorder.class.getSimpleName(); 393380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 403380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public class Gesture { 413380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public abstract class Record { 423380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler long time; 433380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public abstract String toJson(); 443380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 453380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public class MotionEventRecord extends Record { 463380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public MotionEvent event; 473380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public MotionEventRecord(long when, MotionEvent event) { 483380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler this.time = when; 49b8bacccfc159fe204e5b09b52de55f8ba853f713John Spurlock this.event = MotionEvent.obtain(event); 503380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 513380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler String actionName(int action) { 523380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler switch (action) { 533380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler case MotionEvent.ACTION_DOWN: 543380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler return "down"; 553380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler case MotionEvent.ACTION_UP: 563380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler return "up"; 573380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler case MotionEvent.ACTION_MOVE: 583380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler return "move"; 593380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler case MotionEvent.ACTION_CANCEL: 603380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler return "cancel"; 613380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler default: 623380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler return String.valueOf(action); 633380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 643380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 653380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public String toJson() { 66780d668bee92ecdef6e08d92fc227f92425a58c8Daniel Sandler return String.format( 67780d668bee92ecdef6e08d92fc227f92425a58c8Daniel Sandler ("{\"type\":\"motion\", \"time\":%d, \"action\":\"%s\", " 68780d668bee92ecdef6e08d92fc227f92425a58c8Daniel Sandler + "\"x\":%.2f, \"y\":%.2f, \"s\":%.2f, \"p\":%.2f}"), 693380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler this.time, 703380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler actionName(this.event.getAction()), 713380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler this.event.getRawX(), 72780d668bee92ecdef6e08d92fc227f92425a58c8Daniel Sandler this.event.getRawY(), 73780d668bee92ecdef6e08d92fc227f92425a58c8Daniel Sandler this.event.getSize(), 74780d668bee92ecdef6e08d92fc227f92425a58c8Daniel Sandler this.event.getPressure() 753380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler ); 763380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 773380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 783380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public class TagRecord extends Record { 793380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public String tag, info; 803380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public TagRecord(long when, String tag, String info) { 813380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler this.time = when; 823380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler this.tag = tag; 833380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler this.info = info; 843380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 853380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public String toJson() { 863380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler return String.format("{\"type\":\"tag\", \"time\":%d, \"tag\":\"%s\", \"info\":\"%s\"}", 873380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler this.time, 883380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler this.tag, 893380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler this.info 903380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler ); 913380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 923380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 933380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler private LinkedList<Record> mRecords = new LinkedList<Record>(); 943380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler private HashSet<String> mTags = new HashSet<String>(); 953380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler long mDownTime = -1; 963380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler boolean mComplete = false; 973380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 983380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public void add(MotionEvent ev) { 993380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mRecords.add(new MotionEventRecord(ev.getEventTime(), ev)); 1003380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler if (mDownTime < 0) { 1013380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mDownTime = ev.getDownTime(); 1023380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } else { 1033380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler if (mDownTime != ev.getDownTime()) { 104cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock Log.w(TAG, "Assertion failure in GestureRecorder: event downTime (" 1053380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler +ev.getDownTime()+") does not match gesture downTime ("+mDownTime+")"); 1063380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1073380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1083380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler switch (ev.getActionMasked()) { 1093380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler case MotionEvent.ACTION_UP: 1103380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler case MotionEvent.ACTION_CANCEL: 1113380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mComplete = true; 1123380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1133380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1143380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public void tag(long when, String tag, String info) { 1153380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mRecords.add(new TagRecord(when, tag, info)); 1163380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mTags.add(tag); 1173380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1183380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public boolean isComplete() { 1193380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler return mComplete; 1203380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1213380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public String toJson() { 1223380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler StringBuilder sb = new StringBuilder(); 1233380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler boolean first = true; 1243380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler sb.append("["); 1253380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler for (Record r : mRecords) { 1263380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler if (!first) sb.append(", "); 1273380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler first = false; 1283380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler sb.append(r.toJson()); 1293380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1303380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler sb.append("]"); 1313380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler return sb.toString(); 1323380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1333380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1343380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 1353380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler // -=-=-=-=-=-=-=-=-=-=-=- 1363380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 1373380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler static final long SAVE_DELAY = 5000; // ms 1383380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler static final int SAVE_MESSAGE = 6351; 1393380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 1403380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler private LinkedList<Gesture> mGestures; 1413380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler private Gesture mCurrentGesture; 1423380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler private int mLastSaveLen = -1; 1433380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler private String mLogfile; 1443380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 1453380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler private Handler mHandler = new Handler() { 1463380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler @Override 1473380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public void handleMessage(Message msg) { 1483380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler if (msg.what == SAVE_MESSAGE) { 1493380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler save(); 1503380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1513380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1523380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler }; 1533380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 1543380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public GestureRecorder(String filename) { 1553380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mLogfile = filename; 1563380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mGestures = new LinkedList<Gesture>(); 1573380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mCurrentGesture = null; 1583380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1593380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 1603380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public void add(MotionEvent ev) { 1613380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler synchronized (mGestures) { 1623380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler if (mCurrentGesture == null || mCurrentGesture.isComplete()) { 1633380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mCurrentGesture = new Gesture(); 1643380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mGestures.add(mCurrentGesture); 1653380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1663380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mCurrentGesture.add(ev); 1673380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1683380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler saveLater(); 1693380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1703380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 1713380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public void tag(long when, String tag, String info) { 1723380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler synchronized (mGestures) { 1733380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler if (mCurrentGesture == null) { 1743380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mCurrentGesture = new Gesture(); 1753380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mGestures.add(mCurrentGesture); 1763380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1773380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mCurrentGesture.tag(when, tag, info); 1783380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1793380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler saveLater(); 1803380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1813380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 1823380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public void tag(long when, String tag) { 1833380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler tag(when, tag, null); 1843380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1853380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 1863380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public void tag(String tag) { 1873380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler tag(SystemClock.uptimeMillis(), tag, null); 1883380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1893380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 1903380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public void tag(String tag, String info) { 1913380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler tag(SystemClock.uptimeMillis(), tag, info); 1923380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 1933380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 1943380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler /** 1953380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * Generates a JSON string capturing all completed gestures. 1963380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler * Not threadsafe; call with a lock. 1973380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler */ 1983380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public String toJsonLocked() { 1993380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler StringBuilder sb = new StringBuilder(); 2003380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler boolean first = true; 2013380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler sb.append("["); 2023380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler int count = 0; 2033380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler for (Gesture g : mGestures) { 2043380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler if (!g.isComplete()) continue; 2053380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler if (!first) sb.append("," ); 2063380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler first = false; 2073380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler sb.append(g.toJson()); 2083380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler count++; 2093380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 2103380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mLastSaveLen = count; 2113380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler sb.append("]"); 2123380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler return sb.toString(); 2133380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 2143380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 2153380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public String toJson() { 2163380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler String s; 2173380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler synchronized (mGestures) { 2183380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler s = toJsonLocked(); 2193380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 2203380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler return s; 2213380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 2223380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 2233380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public void saveLater() { 2243380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mHandler.removeMessages(SAVE_MESSAGE); 2253380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mHandler.sendEmptyMessageDelayed(SAVE_MESSAGE, SAVE_DELAY); 2263380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 2273380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 2283380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public void save() { 2293380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler synchronized (mGestures) { 2303380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler try { 2313380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler BufferedWriter w = new BufferedWriter(new FileWriter(mLogfile, /*append=*/ true)); 2323380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler w.append(toJsonLocked() + "\n"); 2333380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler w.close(); 2343380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mGestures.clear(); 2353380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler // If we have a pending gesture, push it back 23675fcac4eebdf7ff68a534e9af1664c571f40ef30Daniel Sandler if (mCurrentGesture != null && !mCurrentGesture.isComplete()) { 2373380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mGestures.add(mCurrentGesture); 2383380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 2393380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler if (DEBUG) { 240cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock Log.v(TAG, String.format("Wrote %d complete gestures to %s", mLastSaveLen, mLogfile)); 2413380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 2423380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } catch (IOException e) { 243cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock Log.e(TAG, String.format("Couldn't write gestures to %s", mLogfile), e); 2443380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler mLastSaveLen = -1; 2453380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 2463380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 2473380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 2483380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler 2493380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2503380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler save(); 2513380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler if (mLastSaveLen >= 0) { 2523380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler pw.println(String.valueOf(mLastSaveLen) + " gestures written to " + mLogfile); 2533380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } else { 2543380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler pw.println("error writing gestures"); 2553380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 2563380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler } 2573380534a62abf20b4509db6068ac02b1b880712fDaniel Sandler} 258