aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKurt Partridge <kep@google.com>2012-06-06 20:47:53 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-06-06 20:47:53 -0700
commit9b300f0caa978f4fc103c34b9be0165a49a2e24b (patch)
treec2c68733c9e423f1769bcff61213027b5e9c1fb7
parent4fff6a04988aa47ec716068d41cde1858dc52def (diff)
parent724bc479f7d796d6ce5d5e200216bea855b818b2 (diff)
downloadlatinime-9b300f0caa978f4fc103c34b9be0165a49a2e24b.tar.gz
latinime-9b300f0caa978f4fc103c34b9be0165a49a2e24b.tar.xz
latinime-9b300f0caa978f4fc103c34b9be0165a49a2e24b.zip
Merge "add research log ui control"
-rw-r--r--java/res/values/strings.xml16
-rw-r--r--java/res/xml/key_styles_common.xml19
-rw-r--r--java/res/xml/key_styles_f1.xml43
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java3
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java9
-rw-r--r--java/src/com/android/inputmethod/latin/ResearchLogger.java114
7 files changed, 177 insertions, 33 deletions
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index d51d3789a..d663b008d 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -26,6 +26,8 @@
<string name="english_ime_settings">Android keyboard settings</string>
<!-- Title for Latin keyboard input options dialog [CHAR LIMIT=25] -->
<string name="english_ime_input_options">Input options</string>
+ <!-- Title for Latin keyboard research log dialog, which contains special commands for users that contribute data for research. [CHAR LIMIT=25] -->
+ <string name="english_ime_research_log">Research Log Commands</string>
<!-- Name of Android spell checker service -->
<string name="spell_checker_service_name">Android spell checker</string>
@@ -233,6 +235,20 @@
<!-- Title for input language selection screen -->
<string name="language_selection_title">Input languages</string>
+ <!-- Title for dialog option that lets user mark a particular time in the log for later review by experts [CHAR LIMIT=25] -->
+ <string name="note_timestamp_for_researchlog">Note timestamp in log</string>
+ <!-- Toast notification message that the time has been marked for later review. [CHAR LIMIT=25] -->
+ <string name="notify_recorded_timestamp">Recorded timestamp</string>
+
+ <!-- Title for dialog option to let users cancel logging and delete log for this session [CHAR LIMIT=25] -->
+ <string name="do_not_log_this_session">Do not log this session</string>
+ <!-- Toast notification that the system is processing the request to delete the log for this session [CHAR LIMIT=25] -->
+ <string name="notify_session_log_deleting">Deleting session log</string>
+ <!-- Toast notification that the system has successfully deleted the log for this session [CHAR LIMIT=25] -->
+ <string name="notify_session_log_deleted">Session log deleted</string>
+ <!-- Toast notification that the system has failed to delete the log for this session [CHAR LIMIT=25] -->
+ <string name="notify_session_log_not_deleted">Session log NOT deleted</string>
+
<!-- Preference for input language selection -->
<string name="select_language">Input languages</string>
diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml
index 622da2120..162119dab 100644
--- a/java/res/xml/key_styles_common.xml
+++ b/java/res/xml/key_styles_common.xml
@@ -22,23 +22,8 @@
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
<!-- Base key style for the key which may have settings or tab key as popup key. -->
- <switch>
- <case
- latin:clobberSettingsKey="true"
- >
- <key-style
- latin:styleName="f1MoreKeysStyle"
- latin:backgroundType="functional" />
- </case>
- <!-- clobberSettingsKey="false" -->
- <default>
- <key-style
- latin:styleName="f1MoreKeysStyle"
- latin:keyLabelFlags="hasPopupHint"
- latin:moreKeys="!text/settings_as_more_key"
- latin:backgroundType="functional" />
- </default>
- </switch>
+ <include
+ latin:keyboardLayout="@xml/key_styles_f1" />
<!-- Functional key styles -->
<switch>
<case
diff --git a/java/res/xml/key_styles_f1.xml b/java/res/xml/key_styles_f1.xml
new file mode 100644
index 000000000..8dfc3cb84
--- /dev/null
+++ b/java/res/xml/key_styles_f1.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <!-- Base key style for the key which may have settings or tab key as popup key. -->
+ <!-- Kept as a separate file for cleaner overriding by an overlay. -->
+ <switch>
+ <case
+ latin:clobberSettingsKey="true"
+ >
+ <key-style
+ latin:styleName="f1MoreKeysStyle"
+ latin:backgroundType="functional" />
+ </case>
+ <!-- clobberSettingsKey="false" -->
+ <default>
+ <key-style
+ latin:styleName="f1MoreKeysStyle"
+ latin:keyLabelFlags="hasPopupHint"
+ latin:moreKeys="!text/settings_as_more_key"
+ latin:backgroundType="functional" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index db84c20f5..6fc630d05 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -89,7 +89,8 @@ public class Keyboard {
private static final int MINIMUM_LETTER_CODE = CODE_TAB;
/** Special keys code. Must be negative.
- * These should be aligned with values/keycodes.xml
+ * These should be aligned with KeyboardCodesSet.ID_TO_NAME[],
+ * KeyboardCodesSet.DEFAULT[] and KeyboardCodesSet.RTL[]
*/
public static final int CODE_SHIFT = -1;
public static final int CODE_SWITCH_ALPHA_SYMBOL = -2;
@@ -101,8 +102,9 @@ public class Keyboard {
public static final int CODE_ACTION_NEXT = -8;
public static final int CODE_ACTION_PREVIOUS = -9;
public static final int CODE_LANGUAGE_SWITCH = -10;
+ public static final int CODE_RESEARCH = -11;
// Code value representing the code is not specified.
- public static final int CODE_UNSPECIFIED = -11;
+ public static final int CODE_UNSPECIFIED = -12;
public final KeyboardId mId;
public final int mThemeId;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
index 67cb74f4d..f7981a320 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
@@ -52,6 +52,7 @@ public class KeyboardCodesSet {
"key_action_next",
"key_action_previous",
"key_language_switch",
+ "key_research",
"key_unspecified",
"key_left_parenthesis",
"key_right_parenthesis",
@@ -86,6 +87,7 @@ public class KeyboardCodesSet {
Keyboard.CODE_ACTION_NEXT,
Keyboard.CODE_ACTION_PREVIOUS,
Keyboard.CODE_LANGUAGE_SWITCH,
+ Keyboard.CODE_RESEARCH,
Keyboard.CODE_UNSPECIFIED,
CODE_LEFT_PARENTHESIS,
CODE_RIGHT_PARENTHESIS,
@@ -112,6 +114,7 @@ public class KeyboardCodesSet {
DEFAULT[11],
DEFAULT[12],
DEFAULT[13],
+ DEFAULT[14],
CODE_RIGHT_PARENTHESIS,
CODE_LEFT_PARENTHESIS,
CODE_GREATER_THAN_SIGN,
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 1738c57a7..a64b03ab5 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1332,6 +1332,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
case Keyboard.CODE_LANGUAGE_SWITCH:
handleLanguageSwitchKey();
break;
+ case Keyboard.CODE_RESEARCH:
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.getInstance().presentResearchDialog(this);
+ }
+ break;
default:
if (primaryCode == Keyboard.CODE_TAB
&& mInputAttributes.mEditorAction == EditorInfo.IME_ACTION_NEXT) {
@@ -2446,10 +2451,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setItems(items, listener)
.setTitle(title);
- showOptionDialogInternal(builder.create());
+ showOptionDialog(builder.create());
}
- private void showOptionDialogInternal(AlertDialog dialog) {
+ /* package */ void showOptionDialog(AlertDialog dialog) {
final IBinder windowToken = mKeyboardSwitcher.getKeyboardView().getWindowToken();
if (windowToken == null) return;
diff --git a/java/src/com/android/inputmethod/latin/ResearchLogger.java b/java/src/com/android/inputmethod/latin/ResearchLogger.java
index 16285091b..bb003f766 100644
--- a/java/src/com/android/inputmethod/latin/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/latin/ResearchLogger.java
@@ -18,6 +18,8 @@ package com.android.inputmethod.latin;
import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.inputmethodservice.InputMethodService;
@@ -33,9 +35,9 @@ import android.view.MotionEvent;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
+import android.widget.Toast;
import com.android.inputmethod.keyboard.Key;
-import com.android.inputmethod.keyboard.KeyDetector;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@@ -134,12 +136,16 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
}
if (prefs != null) {
sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false);
- prefs.registerOnSharedPreferenceChangeListener(sInstance);
+ prefs.registerOnSharedPreferenceChangeListener(this);
}
}
public synchronized void start() {
Log.d(TAG, "start called");
+ if (!sIsLogging) {
+ // Log.w(TAG, "not in usability mode; not logging");
+ return;
+ }
if (mFilesDir == null || !mFilesDir.exists()) {
Log.w(TAG, "IME storage directory does not exist. Cannot start logging.");
} else {
@@ -192,16 +198,17 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
- }
- mJsonWriter = NULL_JSON_WRITER;
- mFile = null;
- mLoggingState = LOGGING_STATE_OFF;
- if (DEBUG) {
- Log.d(TAG, "logfile closed");
- }
- Log.d(TAG, "finished stop(), notifying");
- synchronized (ResearchLogger.this) {
- ResearchLogger.this.notify();
+ } finally {
+ mJsonWriter = NULL_JSON_WRITER;
+ mFile = null;
+ mLoggingState = LOGGING_STATE_OFF;
+ if (DEBUG) {
+ Log.d(TAG, "logfile closed");
+ }
+ Log.d(TAG, "finished stop(), notifying");
+ synchronized (ResearchLogger.this) {
+ ResearchLogger.this.notify();
+ }
}
}
});
@@ -213,6 +220,38 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
}
}
+ public synchronized boolean abort() {
+ Log.d(TAG, "abort called");
+ boolean isLogFileDeleted = false;
+ if (mLoggingHandler != null && mLoggingState == LOGGING_STATE_ON) {
+ mLoggingState = LOGGING_STATE_STOPPING;
+ try {
+ Log.d(TAG, "closing jsonwriter");
+ mJsonWriter.endArray();
+ mJsonWriter.close();
+ } catch (IllegalStateException e1) {
+ // assume that this is just the json not being terminated properly.
+ // ignore
+ e1.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ mJsonWriter = NULL_JSON_WRITER;
+ // delete file
+ final boolean isDeleted = mFile.delete();
+ if (isDeleted) {
+ isLogFileDeleted = true;
+ }
+ mFile = null;
+ mLoggingState = LOGGING_STATE_OFF;
+ if (DEBUG) {
+ Log.d(TAG, "logfile closed");
+ }
+ }
+ }
+ return isLogFileDeleted;
+ }
+
/* package */ synchronized void flush() {
try {
mJsonWriter.flush();
@@ -227,6 +266,50 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
return;
}
sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false);
+ if (sIsLogging == false) {
+ abort();
+ }
+ }
+
+ /* package */ void presentResearchDialog(final LatinIME latinIME) {
+ final CharSequence title = latinIME.getString(R.string.english_ime_research_log);
+ final CharSequence[] items = new CharSequence[] {
+ latinIME.getString(R.string.note_timestamp_for_researchlog),
+ latinIME.getString(R.string.do_not_log_this_session),
+ };
+ final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface di, int position) {
+ di.dismiss();
+ switch (position) {
+ case 0:
+ ResearchLogger.getInstance().userTimestamp();
+ Toast.makeText(latinIME, R.string.notify_recorded_timestamp,
+ Toast.LENGTH_LONG).show();
+ break;
+ case 1:
+ Toast toast = Toast.makeText(latinIME,
+ R.string.notify_session_log_deleting, Toast.LENGTH_LONG);
+ toast.show();
+ final ResearchLogger logger = ResearchLogger.getInstance();
+ boolean isLogDeleted = logger.abort();
+ toast.cancel();
+ if (isLogDeleted) {
+ Toast.makeText(latinIME, R.string.notify_session_log_deleted,
+ Toast.LENGTH_LONG).show();
+ } else {
+ Toast.makeText(latinIME,
+ R.string.notify_session_log_not_deleted, Toast.LENGTH_LONG)
+ .show();
+ }
+ break;
+ }
+ }
+ };
+ final AlertDialog.Builder builder = new AlertDialog.Builder(latinIME)
+ .setItems(items, listener)
+ .setTitle(title);
+ latinIME.showOptionDialog(builder.create());
}
private static final String CURRENT_TIME_KEY = "_ct";
@@ -756,4 +839,11 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
getInstance().writeEvent(EVENTKEYS_SUGGESTIONSVIEW_SETSUGGESTIONS, values);
}
}
+
+ private static final String[] EVENTKEYS_USER_TIMESTAMP = {
+ "UserTimestamp"
+ };
+ public void userTimestamp() {
+ getInstance().writeEvent(EVENTKEYS_USER_TIMESTAMP, EVENTKEYS_NULLVALUES);
+ }
}