aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod')
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java20
-rw-r--r--java/src/com/android/inputmethod/research/FeedbackActivity.java52
-rw-r--r--java/src/com/android/inputmethod/research/FeedbackFragment.java73
-rw-r--r--java/src/com/android/inputmethod/research/FeedbackLayout.java62
-rw-r--r--java/src/com/android/inputmethod/research/ResearchLogger.java150
5 files changed, 311 insertions, 46 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 8953cb8d1..4248921f4 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -20,6 +20,7 @@ import static com.android.inputmethod.latin.Constants.ImeOption.FORCE_ASCII;
import static com.android.inputmethod.latin.Constants.ImeOption.NO_MICROPHONE;
import static com.android.inputmethod.latin.Constants.ImeOption.NO_MICROPHONE_COMPAT;
+import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -38,7 +39,6 @@ import android.os.Debug;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
-import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.text.InputType;
import android.text.TextUtils;
@@ -2111,18 +2111,26 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
};
private void launchSettings() {
- launchSettingsClass(SettingsActivity.class);
+ handleClose();
+ launchSubActivity(SettingsActivity.class);
}
// Called from debug code only
public void launchDebugSettings() {
- launchSettingsClass(DebugSettingsActivity.class);
+ handleClose();
+ launchSubActivity(DebugSettingsActivity.class);
}
- private void launchSettingsClass(Class<? extends PreferenceActivity> settingsClass) {
- handleClose();
+ public void launchKeyboardedDialogActivity(Class<? extends Activity> activityClass) {
+ // Put the text in the attached EditText into a safe, saved state before switching to a
+ // new activity that will also use the soft keyboard.
+ commitTyped(LastComposedWord.NOT_A_SEPARATOR);
+ launchSubActivity(activityClass);
+ }
+
+ private void launchSubActivity(Class<? extends Activity> activityClass) {
Intent intent = new Intent();
- intent.setClass(LatinIME.this, settingsClass);
+ intent.setClass(LatinIME.this, activityClass);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
diff --git a/java/src/com/android/inputmethod/research/FeedbackActivity.java b/java/src/com/android/inputmethod/research/FeedbackActivity.java
new file mode 100644
index 000000000..c9f3b476a
--- /dev/null
+++ b/java/src/com/android/inputmethod/research/FeedbackActivity.java
@@ -0,0 +1,52 @@
+/*
+ * 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.Activity;
+import android.os.Bundle;
+import android.text.Editable;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.EditText;
+
+import com.android.inputmethod.latin.R;
+
+public class FeedbackActivity extends Activity {
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.research_feedback_activity);
+ final FeedbackLayout layout = (FeedbackLayout) findViewById(R.id.research_feedback_layout);
+ layout.setActivity(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ }
+
+ @Override
+ public void onBackPressed() {
+ ResearchLogger.getInstance().onLeavingSendFeedbackDialog();
+ super.onBackPressed();
+ }
+}
diff --git a/java/src/com/android/inputmethod/research/FeedbackFragment.java b/java/src/com/android/inputmethod/research/FeedbackFragment.java
new file mode 100644
index 000000000..a2e08e2b7
--- /dev/null
+++ b/java/src/com/android/inputmethod/research/FeedbackFragment.java
@@ -0,0 +1,73 @@
+/*
+ * 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.Activity;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.text.Editable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+
+import com.android.inputmethod.latin.R;
+
+public class FeedbackFragment extends Fragment {
+ private EditText mEditText;
+ private CheckBox mCheckBox;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ final View view = inflater.inflate(R.layout.research_feedback_fragment_layout, container,
+ false);
+ mEditText = (EditText) view.findViewById(R.id.research_feedback_contents);
+ mCheckBox = (CheckBox) view.findViewById(R.id.research_feedback_include_history);
+
+ final Button sendButton = (Button) view.findViewById(
+ R.id.research_feedback_send_button);
+ sendButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ final Editable editable = mEditText.getText();
+ final String feedbackContents = editable.toString();
+ final boolean includeHistory = mCheckBox.isChecked();
+ ResearchLogger.getInstance().sendFeedback(feedbackContents, includeHistory);
+ final Activity activity = FeedbackFragment.this.getActivity();
+ activity.finish();
+ ResearchLogger.getInstance().onLeavingSendFeedbackDialog();
+ }
+ });
+
+ final Button cancelButton = (Button) view.findViewById(
+ R.id.research_feedback_cancel_button);
+ cancelButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ final Activity activity = FeedbackFragment.this.getActivity();
+ activity.finish();
+ ResearchLogger.getInstance().onLeavingSendFeedbackDialog();
+ }
+ });
+
+ return view;
+ }
+}
diff --git a/java/src/com/android/inputmethod/research/FeedbackLayout.java b/java/src/com/android/inputmethod/research/FeedbackLayout.java
new file mode 100644
index 000000000..f2cbfe308
--- /dev/null
+++ b/java/src/com/android/inputmethod/research/FeedbackLayout.java
@@ -0,0 +1,62 @@
+/*
+ * 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.Activity;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.widget.LinearLayout;
+
+public class FeedbackLayout extends LinearLayout {
+ private Activity mActivity;
+
+ public FeedbackLayout(Context context) {
+ super(context);
+ }
+
+ public FeedbackLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public FeedbackLayout(Context context, AttributeSet attrs, int defstyle) {
+ super(context, attrs, defstyle);
+ }
+
+ public void setActivity(Activity activity) {
+ mActivity = activity;
+ }
+
+ @Override
+ public boolean dispatchKeyEventPreIme(KeyEvent event) {
+ if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
+ KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (state != null) {
+ if (event.getAction() == KeyEvent.ACTION_DOWN
+ && event.getRepeatCount() == 0) {
+ state.startTracking(event, this);
+ return true;
+ } else if (event.getAction() == KeyEvent.ACTION_UP
+ && !event.isCanceled() && state.isTracking(event)) {
+ mActivity.onBackPressed();
+ return true;
+ }
+ }
+ }
+ return super.dispatchKeyEventPreIme(event);
+ }
+}
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index b40bfe387..e6828da50 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -83,7 +83,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
private static final String WHITESPACE_SEPARATORS = " \t\n\r";
private static final int MAX_INPUTVIEW_LENGTH_TO_CAPTURE = 8192; // must be >=1
private static final String PREF_RESEARCH_LOGGER_UUID_STRING = "pref_research_logger_uuid";
- private static final int ABORT_TIMEOUT_IN_MS = 10 * 1000;
+ private static final int ABORT_TIMEOUT_IN_MS = 10 * 1000; // timeout to notify user
private static final ResearchLogger sInstance = new ResearchLogger();
// to write to a different filename, e.g., for testing, set mFile before calling start()
@@ -95,7 +95,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
// the system to do so.
/* package */ ResearchLog mIntentionalResearchLog;
// LogUnits are queued here and released only when the user requests the intentional log.
- private final List<LogUnit> mIntentionalResearchLogQueue = new ArrayList<LogUnit>();
+ private List<LogUnit> mIntentionalResearchLogQueue = new ArrayList<LogUnit>();
private boolean mIsPasswordView = false;
private boolean mIsLoggingSuspended = false;
@@ -268,22 +268,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
}
}
- private void logWholeSessionHistory() throws IOException {
- try {
- LogUnit headerLogUnit = new LogUnit();
- headerLogUnit.addLogAtom(EVENTKEYS_INTENTIONAL_LOG, EVENTKEYS_NULLVALUES, false);
- mIntentionalResearchLog.publishAllEvents(headerLogUnit);
- for (LogUnit logUnit : mIntentionalResearchLogQueue) {
- mIntentionalResearchLog.publishAllEvents(logUnit);
- }
- mIntentionalResearchLog.stop();
- mIntentionalResearchLog = new ResearchLog(createLogFile(mFilesDir));
- mIntentionalResearchLog.start();
- } finally {
- mIntentionalResearchLogQueue.clear();
- }
- }
-
private void restart() {
stop();
start();
@@ -325,13 +309,17 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
}
public void presentResearchDialog(final LatinIME latinIME) {
+ if (mInFeedbackDialog) {
+ Toast.makeText(latinIME, R.string.research_please_exit_feedback_form,
+ Toast.LENGTH_LONG).show();
+ return;
+ }
final CharSequence title = latinIME.getString(R.string.english_ime_research_log);
final boolean showEnable = mIsLoggingSuspended || !sIsLogging;
final CharSequence[] items = new CharSequence[] {
- latinIME.getString(R.string.note_timestamp_for_researchlog),
- showEnable ? latinIME.getString(R.string.enable_session_logging) :
- latinIME.getString(R.string.do_not_log_this_session),
- latinIME.getString(R.string.log_whole_session_history)
+ latinIME.getString(R.string.research_feedback_menu_option),
+ showEnable ? latinIME.getString(R.string.research_enable_session_logging) :
+ latinIME.getString(R.string.research_do_not_log_this_session)
};
final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
@Override
@@ -339,9 +327,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
di.dismiss();
switch (position) {
case 0:
- userTimestamp();
- Toast.makeText(latinIME, R.string.notify_recorded_timestamp,
- Toast.LENGTH_LONG).show();
+ presentFeedbackDialog(latinIME);
break;
case 1:
if (showEnable) {
@@ -349,11 +335,13 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
setLoggingAllowed(true);
}
resumeLogging();
- Toast.makeText(latinIME, R.string.notify_session_logging_enabled,
+ Toast.makeText(latinIME,
+ R.string.research_notify_session_logging_enabled,
Toast.LENGTH_LONG).show();
} else {
Toast toast = Toast.makeText(latinIME,
- R.string.notify_session_log_deleting, Toast.LENGTH_LONG);
+ R.string.research_notify_session_log_deleting,
+ Toast.LENGTH_LONG);
toast.show();
boolean isLogDeleted = abort();
final long currentTime = System.currentTimeMillis();
@@ -361,21 +349,10 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
SUSPEND_DURATION_IN_MINUTES;
suspendLoggingUntil(resumeTime);
toast.cancel();
- Toast.makeText(latinIME, R.string.notify_logging_suspended,
+ Toast.makeText(latinIME, R.string.research_notify_logging_suspended,
Toast.LENGTH_LONG).show();
}
break;
- case 2:
- try {
- logWholeSessionHistory();
- Toast.makeText(latinIME, R.string.notify_session_history_logged,
- Toast.LENGTH_LONG).show();
- } catch (IOException e) {
- Toast.makeText(latinIME, R.string.notify_session_history_not_logged,
- Toast.LENGTH_LONG).show();
- e.printStackTrace();
- }
- break;
}
}
@@ -386,6 +363,83 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
latinIME.showOptionDialog(builder.create());
}
+ private boolean mInFeedbackDialog = false;
+ public void presentFeedbackDialog(LatinIME latinIME) {
+ mInFeedbackDialog = true;
+ latinIME.launchKeyboardedDialogActivity(FeedbackActivity.class);
+ }
+
+ private ResearchLog mFeedbackLog;
+ private List<LogUnit> mFeedbackQueue;
+ private ResearchLog mSavedMainResearchLog;
+ private ResearchLog mSavedIntentionalResearchLog;
+ private List<LogUnit> mSavedIntentionalResearchLogQueue;
+
+ private void saveLogsForFeedback() {
+ mFeedbackLog = mIntentionalResearchLog;
+ if (mIntentionalResearchLogQueue != null) {
+ mFeedbackQueue = new ArrayList<LogUnit>(mIntentionalResearchLogQueue);
+ } else {
+ mFeedbackQueue = null;
+ }
+ mSavedMainResearchLog = mMainResearchLog;
+ mSavedIntentionalResearchLog = mIntentionalResearchLog;
+ mSavedIntentionalResearchLogQueue = mIntentionalResearchLogQueue;
+
+ mMainResearchLog = null;
+ mIntentionalResearchLog = null;
+ mIntentionalResearchLogQueue = new ArrayList<LogUnit>();
+ }
+
+ private static final int LOG_DRAIN_TIMEOUT_IN_MS = 1000 * 5;
+ public void sendFeedback(final String feedbackContents, final boolean includeHistory) {
+ if (includeHistory && mFeedbackLog != null) {
+ try {
+ LogUnit headerLogUnit = new LogUnit();
+ headerLogUnit.addLogAtom(EVENTKEYS_INTENTIONAL_LOG, EVENTKEYS_NULLVALUES, false);
+ mFeedbackLog.publishAllEvents(headerLogUnit);
+ for (LogUnit logUnit : mFeedbackQueue) {
+ mFeedbackLog.publishAllEvents(logUnit);
+ }
+ userFeedback(mFeedbackLog, feedbackContents);
+ mFeedbackLog.stop();
+ try {
+ mFeedbackLog.waitUntilStopped(LOG_DRAIN_TIMEOUT_IN_MS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ mIntentionalResearchLog = new ResearchLog(createLogFile(mFilesDir));
+ mIntentionalResearchLog.start();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ mIntentionalResearchLogQueue.clear();
+ }
+ mResearchLogUploader.uploadNow(null);
+ } else {
+ // create a separate ResearchLog just for feedback
+ final ResearchLog feedbackLog = new ResearchLog(createLogFile(mFilesDir));
+ try {
+ feedbackLog.start();
+ userFeedback(feedbackLog, feedbackContents);
+ feedbackLog.stop();
+ feedbackLog.waitUntilStopped(LOG_DRAIN_TIMEOUT_IN_MS);
+ mResearchLogUploader.uploadNow(null);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void onLeavingSendFeedbackDialog() {
+ mInFeedbackDialog = false;
+ mMainResearchLog = mSavedMainResearchLog;
+ mIntentionalResearchLog = mSavedIntentionalResearchLog;
+ mIntentionalResearchLogQueue = mSavedIntentionalResearchLogQueue;
+ }
+
public void initSuggest(Suggest suggest) {
mSuggest = suggest;
}
@@ -540,7 +594,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
return;
}
if (mMainResearchLog == null) {
- Log.w(TAG, "ResearchLog was not properly set up");
return;
}
if (isPrivacySensitive) {
@@ -647,6 +700,9 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
public static void latinIME_onStartInputViewInternal(final EditorInfo editorInfo,
final SharedPreferences prefs) {
final ResearchLogger researchLogger = getInstance();
+ if (researchLogger.mInFeedbackDialog) {
+ researchLogger.saveLogsForFeedback();
+ }
researchLogger.start();
if (editorInfo != null) {
final Context context = researchLogger.mContext;
@@ -688,6 +744,20 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
researchLogger.onWordComplete(scrubbedWord);
}
+ private static final String[] EVENTKEYS_USER_FEEDBACK = {
+ "UserFeedback", "FeedbackContents"
+ };
+
+ private void userFeedback(ResearchLog researchLog, String feedbackContents) {
+ // this method is special; it directs the feedbackContents to a particular researchLog
+ final LogUnit logUnit = new LogUnit();
+ final Object[] values = {
+ feedbackContents
+ };
+ logUnit.addLogAtom(EVENTKEYS_USER_FEEDBACK, values, false);
+ researchLog.publishAllEvents(logUnit);
+ }
+
// Regular logging methods
private static final String[] EVENTKEYS_LATINKEYBOARDVIEW_PROCESSMOTIONEVENT = {