Opensource a test tool called EditTextVariations

This CL opensouces a testing tool called EditTextVariations that has
been used internally to test IME behaviors on various
EditorInfo#inputType and EditorInfo#imeOptions.

Bug: 80039502
Test: Manually verified as follows.
 1. tapas EditTextVariations
 2. make -j
 3. adb install -r $ANDROID_TARGET_OUT_TESTCASES/EditTextVariations/EditTextVariations.apk
Change-Id: Ia87e655573c2fd1fc09d56e4af90bfb1dfd65f9b
This commit is contained in:
Yohei Yukawa 2018-05-22 10:31:28 -07:00
parent a3b17c255d
commit f97da47c02
27 changed files with 2073 additions and 0 deletions

View File

@ -0,0 +1,26 @@
# Copyright (C) 2013 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.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := EditTextVariations
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 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.
-->
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.inputmethod.tools.edittextvariations"
android:versionName="0.67"
android:versionCode="67"
>
<supports-screens android:resizeable="true" />
<uses-sdk
android:targetSdkVersion="27"
android:minSdkVersion="11" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:allowBackup="false"
>
<activity
android:name=".EditTextVariations"
android:windowSoftInputMode="stateHidden|adjustPan"
android:theme="@style/defaultActivityTheme"
android:label="@string/app_name"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -0,0 +1,56 @@
<!--
/*
**
** Copyright 2014, 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.
*/
-->
body {
background-color: black;
}
div.placeholder {
color: #a0a0a0;
font-size: 18px;
margin: 0px 0px -34px 0px;
padding: 4px 0px 4px 0px
}
div.input {
border: none;
margin: 4px 0px 4px -8px;
}
input {
color: black;
background-color: white;
font-size: 18px;
line-height: 200%;
vertical-align: center;
padding-left: 8px;
border-top: none;
border-right: none;
border-bottom: none;
border-left: none;
}
textarea {
color: black;
background-color: white;
font-size: 18px;
line-height: 150%;
vertical-align: center;
padding-left: 8px;
border-top: none;
border-right: none;
border-bottom: none;
border-left: none;
}

View File

@ -0,0 +1,56 @@
<!--
/*
**
** Copyright 2011, 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.
*/
-->
body {
background-color: black;
}
div.placeholder {
color: #a0a0a0;
font-size: 18px;
margin: 0px 0px -34px 0px;
padding: 4px 0px 4px 0px
}
div.input {
border: none;
margin: 4px 0px 4px -8px;
}
input {
color: black;
background-color: white;
font-size: 18px;
line-height: 200%;
vertical-align: center;
padding-left: 8px;
border-top: none;
border-right: none;
border-bottom: none;
border-left: none;
}
textarea {
color: black;
background-color: white;
font-size: 18px;
line-height: 150%;
vertical-align: center;
padding-left: 8px;
border-top: none;
border-right: none;
border-bottom: none;
border-left: none;
}

View File

@ -0,0 +1,56 @@
<!--
/*
**
** Copyright 2011, 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.
*/
-->
body {
background-color: #16191C;
}
div.placeholder {
color: #808080;
font-size: 18px;
margin: 0px 0px -34px 0px;
padding: 4px 0px 4px 0px
}
div.input {
border: none;
margin: 4px 0px 4px -8px;
}
input {
color: white;
background-color: rgba(0, 0, 0, 0.0);
font-size: 18px;
line-height: 180%;
vertical-align: center;
padding-left: 8px;
border-top: none;
border-right: none;
border-bottom: 1px solid #5E6063;
border-left: none;
}
textarea {
color: white;
background-color: rgba(0, 0, 0, 0.0);
font-size: 18px;
line-height: 150%;
vertical-align: center;
padding-left: 8px;
border-top: none;
border-right: none;
border-bottom: 1px solid #5E6063;
border-left: none;
}

View File

@ -0,0 +1,56 @@
<!--
/*
**
** Copyright 2011, 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.
*/
-->
body {
background-color: #F2F2F2;
}
div.placeholder {
color: #808080;
font-size: 18px;
margin: 0px 0px -34px 0px;
padding: 4px 0px 4px 0px
}
div.input {
border: none;
margin: 4px 0px 4px -8px;
}
input {
color: black;
background-color: rgba(0, 0, 0, 0.0);
font-size: 18px;
line-height: 150%;
vertical-align: center;
padding-left: 8px;
border-top: none;
border-right: none;
border-bottom: 1px solid #808080;
border-left: none;
}
textarea {
color: black;
background-color: rgba(0, 0, 0, 0.0);
font-size: 18px;
line-height: 150%;
vertical-align: center;
padding-left: 8px;
border-top: none;
border-right: none;
border-bottom: 1px solid #808080;
border-left: none;
}

View File

@ -0,0 +1,56 @@
<!--
/*
**
** Copyright 2011, 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.
*/
-->
body {
background-color: #f3f3f3;
}
div.placeholder {
color: #a0a0a0;
font-size: 18px;
margin: 0px 0px -34px 0px;
padding: 4px 0px 4px 0px
}
div.input {
border: none;
margin: 4px 0px 4px -8px;
}
input {
color: black;
background-color: rgba(0, 0, 0, 0.0);
font-size: 18px;
line-height: 200%;
vertical-align: center;
padding-left: 8px;
border-top: 1px solid #808080;
border-right: 1px solid rgba(0, 0, 0, 0.5);
border-bottom: 1px solid #808080;
border-left: 1px solid rgba(0, 0, 0, 0.5);
}
textarea {
color: black;
background-color: rgba(0, 0, 0, 0.0);
font-size: 18px;
line-height: 150%;
vertical-align: center;
padding-left: 8px;
border-top: 1px solid #808080;
border-right: 1px solid rgba(0, 0, 0, 0.5);
border-bottom: 1px solid #808080;
border-left: 1px solid rgba(0, 0, 0, 0.5);
}

View File

@ -0,0 +1,56 @@
<!--
/*
**
** Copyright 2014, 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.
*/
-->
body {
background-color: #212121;
}
div.placeholder {
color: #909090;
font-size: 18px;
margin: 0px 0px -34px 0px;
padding: 4px 0px 4px 0px
}
div.input {
border: none;
margin: 4px 0px 4px -8px;
}
input {
color: white;
background-color: rgba(0, 0, 0, 0.0);
font-size: 18px;
line-height: 180%;
vertical-align: center;
padding-left: 8px;
border-top: none;
border-right: none;
border-bottom: 1px solid #757575;
border-left: none;
}
textarea {
color: white;
background-color: rgba(0, 0, 0, 0.0);
font-size: 18px;
line-height: 150%;
vertical-align: center;
padding-left: 8px;
border-top: none;
border-right: none;
border-bottom: 1px solid #757575;
border-left: none;
}

View File

@ -0,0 +1,56 @@
<!--
/*
**
** Copyright 2014, 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.
*/
-->
body {
background-color: #FAFAFA;
}
div.placeholder {
color: #7D7D7D;
font-size: 18px;
margin: 0px 0px -34px 0px;
padding: 4px 0px 4px 0px
}
div.input {
border: none;
margin: 4px 0px 4px -8px;
}
input {
color: white;
background-color: rgba(0, 0, 0, 0.0);
font-size: 18px;
line-height: 180%;
vertical-align: center;
padding-left: 8px;
border-top: none;
border-right: none;
border-bottom: 1px solid #737373;
border-left: none;
}
textarea {
color: white;
background-color: rgba(0, 0, 0, 0.0);
font-size: 18px;
line-height: 150%;
vertical-align: center;
padding-left: 8px;
border-top: none;
border-right: none;
border-bottom: 1px solid #737373;
border-left: none;
}

View File

@ -0,0 +1,96 @@
<!--
/*
**
** Copyright 2011, 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.
*/
-->
<html>
<head>
<script type="text/javascript">
(function(d, name) {
var css = document.createElement('link');
css.rel = 'stylesheet';
css.href = name + ".css";
d.head.appendChild(css);
})(document, theme.name());
</script>
</head>
<body>
<div
class="input"
style="margin-top:-8px"
>
<input
type="text"
size="80%"
name="webtext"
placeholder="&lt;input type=&quot;text&quot;/&gt;" />
</div>
<div class="input">
<input
type="email"
size="80%"
name="webemail"
placeholder="&lt;input type=&quot;email&quot;/&gt;" />
</div>
<div class="input">
<input
type="password"
size="80%"
name="webpassword"
placeholder="&lt;input type=&quot;password&quot;/&gt;" />
</div>
<div class="input">
<input
type="url"
size="80%"
name="weburl"
placeholder="&lt;input type=&quot;url&quot;/&gt;" />
</div>
<div class="input">
<input
type="number"
size="80%"
name="webnumber"
placeholder="&lt;input type=&quot;number&quot;/&gt;" />
</div>
<div class="input">
<input
type="tel"
size="80%"
name="webtel"
placeholder="&lt;input type=&quot;tel&quot;/&gt;" />
</div>
<div class="input">
<input
type="search"
size="80%"
name="websearch"
placeholder="&lt;input type=&quot;search&quot;/&gt;" />
</div>
<div
class="input"
style="margin-bottom:-4px"
>
<textarea
rows="2"
cols="80%"
name="webtextarea"
placeholder="&lt;textarea&gt;&lt/textarea&gt;"
></textarea>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,298 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2010, 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.
*/
-->
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:id="@+id/edit_text_list"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<EditText
android:id="@+id/text_multi_lines_none"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine|textAutoCorrect"
android:imeOptions="actionUnspecified" />
<EditText
android:id="@+id/text_multi_lines_send"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine|textAutoCorrect"
android:imeOptions="actionSend" />
<view
class="com.android.inputmethod.tools.edittextvariations.MultiLineShortMessageEditText"
android:id="@+id/text_short_message_send_multi_lines"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textShortMessage|textMultiLine|textAutoCorrect|textCapSentences"
android:imeOptions="actionSend" />
<view
class="com.android.inputmethod.tools.edittextvariations.MultiLineShortMessageEditText"
android:id="@+id/text_multi_lines_search"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine|textAutoCorrect|textCapSentences"
android:imeOptions="actionSearch" />
<EditText
android:id="@+id/text_short_message_send"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textShortMessage|textAutoCorrect|textCapSentences"
android:imeOptions="actionSend" />
<EditText
android:id="@+id/text_autocap_none"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textAutoCorrect|textCapSentences"
android:imeOptions="actionNone" />
<EditText
android:id="@+id/text_autocap_send"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textAutoCorrect|textCapSentences"
android:imeOptions="actionSend" />
<EditText
android:id="@+id/text_uri_go"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textUri"
android:imeOptions="actionGo" />
<EditText
android:id="@+id/text_email_address_done"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:imeOptions="actionDone" />
<EditText
android:id="@+id/text_auto_correct_search"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textAutoCorrect"
android:imeOptions="actionSearch" />
<EditText
android:id="@+id/text_auto_correct_next"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textAutoCorrect"
android:imeOptions="actionNext" />
<EditText
android:id="@+id/text_auto_correct_previous"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textAutoCorrect" />
<EditText
android:id="@+id/text_auto_correct_custom"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textAutoCorrect"
android:imeActionLabel="@string/custom_action_label"
android:imeActionId="100" />
<EditText
android:id="@+id/phone"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="phone" />
<EditText
android:id="@+id/phone_no_action"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="phone"
android:imeOptions="actionNone" />
<EditText
android:id="@+id/number_send"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:imeOptions="actionSend" />
<EditText
android:id="@+id/number_no_action"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:imeOptions="actionNone" />
<EditText
android:id="@+id/text_password_next"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:imeOptions="actionNext" />
<EditText
android:id="@+id/text_visible_password_done"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textVisiblePassword"
android:imeOptions="actionDone" />
<EditText
android:id="@+id/number_password_send"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="numberPassword"
android:imeOptions="actionDone" />
<EditText
android:id="@+id/text_no_suggestions"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textNoSuggestions"
android:imeOptions="actionGo" />
<EditText
android:id="@+id/text_no_auto_correction"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textShortMessage"
android:imeOptions="actionDone" />
<WebView
android:id="@+id/web_view"
android:layout_width="fill_parent"
android:layout_height="380sp"
android:focusable="true" />
<EditText
android:id="@+id/text_cap_characters_with_auto_correction"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textCapCharacters|textAutoCorrect" />
<EditText
android:id="@+id/text_cap_words_with_auto_correction"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textCapWords|textAutoCorrect" />
<EditText
android:id="@+id/text_cap_sentences_with_auto_correction"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textCapSentences|textAutoCorrect" />
<EditText
android:id="@+id/text_cap_characters"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textCapCharacters" />
<EditText
android:id="@+id/text_cap_words"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textCapWords" />
<EditText
android:id="@+id/text_cap_sentences"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textCapSentences" />
<EditText
android:id="@+id/text_email_subject"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textEmailSubject" />
<EditText
android:id="@+id/text_personal_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName" />
<EditText
android:id="@+id/text_postal_address"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPostalAddress" />
<EditText
android:id="@+id/text_phonetic"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPhonetic" />
<EditText
android:id="@+id/number_signed"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="numberSigned" />
<EditText
android:id="@+id/number_decimal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal" />
<EditText
android:id="@+id/number_signed_decimal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="numberSigned|numberDecimal" />
<EditText
android:id="@+id/date_time"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="datetime" />
<EditText
android:id="@+id/date"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="date" />
<EditText
android:id="@+id/time"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="time" />
<EditText
android:id="@+id/text_no_extract_ui"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:imeOptions="flagNoExtractUi" />
<EditText
android:id="@+id/text_no_fullscreen"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textCapSentences"
android:imeOptions="flagNoFullscreen" />
<EditText
android:id="@+id/text_nm"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:privateImeOptions="nm" />
<EditText
android:id="@+id/text_force_ascii_flag"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="text" />
<AutoCompleteTextView
android:id="@+id/text_app_completion"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<AutoCompleteTextView
android:id="@+id/text_app_completion_no_fullscreen"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:imeOptions="flagNoFullscreen" />
<AutoCompleteTextView
android:id="@+id/text_app_compeletion_no_extract_ui"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:imeOptions="flagNoExtractUi" />
<EditText
android:id="@+id/text_restarting"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="text" />
<EditText
android:id="@+id/text_null"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="none" />
</LinearLayout>
</ScrollView>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2011, 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.
*/
-->
<resources>
<string name="default_theme">Theme_Holo_Light</string>
</resources>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2017, 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.
*/
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="defaultActivityTheme" parent="@android:style/Theme.DeviceDefault.Light" />
</resources>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2017, 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.
*/
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="defaultActivityTheme" parent="@android:style/Theme.DeviceDefault.Light">
<item name="android:navigationBarColor">@android:color/white</item>
<item name="android:navigationBarDividerColor">#1f000000</item>
<item name="android:windowLightNavigationBar">true</item>
</style>
</resources>

View File

@ -0,0 +1,263 @@
<?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.
*/
-->
<resources>
<!-- The list of country names. [CHAR LIMIT=100] -->
<string-array name="countries_array">
<item>Afghanistan</item>
<item>Albania</item>
<item>Algeria</item>
<item>American Samoa</item>
<item>Andorra</item>
<item>Angola</item>
<item>Anguilla</item>
<item>Antarctica</item>
<item>Antigua and Barbuda</item>
<item>Argentina</item>
<item>Armenia</item>
<item>Aruba</item>
<item>Australia</item>
<item>Austria</item>
<item>Azerbaijan</item>
<item>Bahrain</item>
<item>Bangladesh</item>
<item>Barbados</item>
<item>Belarus</item>
<item>Belgium</item>
<item>Belize</item>
<item>Benin</item>
<item>Bermuda</item>
<item>Bhutan</item>
<item>Bolivia</item>
<item>Bosnia and Herzegovina</item>
<item>Botswana</item>
<item>Bouvet Island</item>
<item>Brazil</item>
<item>British Indian Ocean Territory</item>
<item>British Virgin Islands</item>
<item>Brunei</item>
<item>Bulgaria</item>
<item>Burkina Faso</item>
<item>Burundi</item>
<item>"Cote d'Ivoire"</item>
<item>Cambodia</item>
<item>Cameroon</item>
<item>Canada</item>
<item>Cape Verde</item>
<item>Cayman Islands</item>
<item>Central African Republic</item>
<item>Chad</item>
<item>Chile</item>
<item>China</item>
<item>Christmas Island</item>
<item>Cocos (Keeling) Islands</item>
<item>Colombia</item>
<item>Comoros</item>
<item>Congo</item>
<item>Cook Islands</item>
<item>Costa Rica</item>
<item>Croatia</item>
<item>Cuba</item>
<item>Cyprus</item>
<item>Czech Republic</item>
<item>Democratic Republic of the Congo</item>
<item>Denmark</item>
<item>Djibouti</item>
<item>Dominica</item>
<item>Dominican Republic</item>
<item>East Timor</item>
<item>Ecuador</item>
<item>Egypt</item>
<item>El Salvador</item>
<item>Equatorial Guinea</item>
<item>Eritrea</item>
<item>Estonia</item>
<item>Ethiopia</item>
<item>Faeroe Islands</item>
<item>Falkland Islands</item>
<item>Fiji</item>
<item>Finland</item>
<item>Republic of Macedonia</item>
<item>France</item>
<item>French Guiana</item>
<item>French Polynesia</item>
<item>French Southern Territories</item>
<item>Gabon</item>
<item>Georgia</item>
<item>Germany</item>
<item>Ghana</item>
<item>Gibraltar</item>
<item>Greece</item>
<item>Greenland</item>
<item>Grenada</item>
<item>Guadeloupe</item>
<item>Guam</item>
<item>Guatemala</item>
<item>Guinea</item>
<item>Guinea-Bissau</item>
<item>Guyana</item>
<item>Haiti</item>
<item>Heard Island and McDonald Islands</item>
<item>Honduras</item>
<item>Hong Kong</item>
<item>Hungary</item>
<item>Iceland</item>
<item>India</item>
<item>Indonesia</item>
<item>Iran</item>
<item>Iraq</item>
<item>Ireland</item>
<item>Israel</item>
<item>Italy</item>
<item>Jamaica</item>
<item>Japan</item>
<item>Jordan</item>
<item>Kazakhstan</item>
<item>Kenya</item>
<item>Kiribati</item>
<item>Kuwait</item>
<item>Kyrgyzstan</item>
<item>Laos</item>
<item>Latvia</item>
<item>Lebanon</item>
<item>Lesotho</item>
<item>Liberia</item>
<item>Libya</item>
<item>Liechtenstein</item>
<item>Lithuania</item>
<item>Luxembourg</item>
<item>Macau</item>
<item>Madagascar</item>
<item>Malawi</item>
<item>Malaysia</item>
<item>Maldives</item>
<item>Mali</item>
<item>Malta</item>
<item>Marshall Islands</item>
<item>Martinique</item>
<item>Mauritania</item>
<item>Mauritius</item>
<item>Mayotte</item>
<item>Mexico</item>
<item>Micronesia</item>
<item>Moldova</item>
<item>Monaco</item>
<item>Mongolia</item>
<item>Montserrat</item>
<item>Morocco</item>
<item>Mozambique</item>
<item>Myanmar</item>
<item>Namibia</item>
<item>Nauru</item>
<item>Nepal</item>
<item>Netherlands</item>
<item>Netherlands Antilles</item>
<item>New Caledonia</item>
<item>New Zealand</item>
<item>Nicaragua</item>
<item>Niger</item>
<item>Nigeria</item>
<item>Niue</item>
<item>Norfolk Island</item>
<item>North Korea</item>
<item>Northern Marianas</item>
<item>Norway</item>
<item>Oman</item>
<item>Pakistan</item>
<item>Palau</item>
<item>Panama</item>
<item>Papua New Guinea</item>
<item>Paraguay</item>
<item>Peru</item>
<item>Philippines</item>
<item>Pitcairn Islands</item>
<item>Poland</item>
<item>Portugal</item>
<item>Puerto Rico</item>
<item>Qatar</item>
<item>Reunion</item>
<item>Romania</item>
<item>Russia</item>
<item>Rwanda</item>
<item>Sao Tome and Principe</item>
<item>Saint Helena</item>
<item>Saint Kitts and Nevis</item>
<item>Saint Lucia</item>
<item>Saint Pierre and Miquelon</item>
<item>Saint Vincent and the Grenadines</item>
<item>Samoa</item>
<item>San Marino</item>
<item>Saudi Arabia</item>
<item>Senegal</item>
<item>Seychelles</item>
<item>Sierra Leone</item>
<item>Singapore</item>
<item>Slovakia</item>
<item>Slovenia</item>
<item>Solomon Islands</item>
<item>Somalia</item>
<item>South Africa</item>
<item>South Georgia and the South Sandwich Islands</item>
<item>South Korea</item>
<item>Spain</item>
<item>Sri Lanka</item>
<item>Sudan</item>
<item>Suriname</item>
<item>Svalbard and Jan Mayen</item>
<item>Swaziland</item>
<item>Sweden</item>
<item>Switzerland</item>
<item>Syria</item>
<item>Taiwan</item>
<item>Tajikistan</item>
<item>Tanzania</item>
<item>Thailand</item>
<item>The Bahamas</item>
<item>The Gambia</item>
<item>Togo</item>
<item>Tokelau</item>
<item>Tonga</item>
<item>Trinidad and Tobago</item>
<item>Tunisia</item>
<item>Turkey</item>
<item>Turkmenistan</item>
<item>Turks and Caicos Islands</item>
<item>Tuvalu</item>
<item>Virgin Islands</item>
<item>Uganda</item>
<item>Ukraine</item>
<item>United Arab Emirates</item>
<item>United Kingdom</item>
<item>United States</item>
<item>United States Minor Outlying Islands</item>
<item>Uruguay</item>
<item>Uzbekistan</item>
<item>Vanuatu</item>
<item>Vatican City</item>
<item>Venezuela</item>
<item>Vietnam</item>
<item>Wallis and Futuna</item>
<item>Western Sahara</item>
<item>Yemen</item>
<item>Zambia</item>
<item>Zimbabwe</item>
<item>Yemen</item>
</string-array>
</resources>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2010, 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.
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- This test application name. -->
<string name="app_name" translatable="false">EditTextVariations</string>
<!-- The menu title to change color theme of this application. [CHAR LIMIT=20] -->
<string name="menu_change_theme">Change Theme</string>
<!-- The menu title to display the version name of this application. [CHAR LIMIT=20] -->
<string name="menu_version">Version <xliff:g id="VERSION_NAME" example="0.56">%s</xliff:g></string>
<!-- The menu title to turn on the text field focus navigation. [CHAR LIMIT=20] -->
<string name="menu_navigate_on" translatable="false">Navigate On</string>
<!-- The menu title to turn off the text field focus navigation. [CHAR LIMIT=20] -->
<string name="menu_navigate_off" translatable="false">Navigate Off</string>
<!-- The menu title to show software keyboard when the application is launched. [CHAR LIMIT=20] -->
<string name="menu_softinput_visible" translatable="false">Keyboard Visible</string>
<!-- The menu title to stay hidden software keyboard when the application is launched. [CHAR LIMIT=20] -->
<string name="menu_softinput_hidden" translatable="false">Keyboard Hidden</string>
<!-- The example of custom action key label. Must be short to fit on key. 5 chars or less is preferable. [CHAR LIMIT=7] -->
<string name="custom_action_label">Custom</string>
</resources>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2017, 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.
*/
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="defaultActivityTheme" parent="@android:style/Theme.Holo" />
</resources>

View File

@ -0,0 +1,86 @@
/*
* 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.tools.edittextvariations;
import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.widget.EditText;
import java.util.Locale;
final class EchoingTextWatcher implements TextWatcher {
private static final int SET_TEXT_DELAY = 500;
final EditText mEditText;
CharSequence mExpected;
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
@Override
public void handleMessage(final Message msg) {
final String toBeappended = (String) msg.obj;
final CharSequence current = mEditText.getText();
final CharSequence newText = TextUtils.concat(current, toBeappended);
mExpected = newText;
mEditText.setText(newText);
mEditText.setSelection(newText.length());
}
};
@SuppressWarnings("unused")
public static void attachTo(final EditText editText) {
final EchoingTextWatcher watcher = new EchoingTextWatcher(editText);
}
public EchoingTextWatcher(final EditText editText) {
mEditText = editText;
editText.addTextChangedListener(this);
}
@Override
public void afterTextChanged(final Editable ss) {
}
@Override
public void beforeTextChanged(final CharSequence s, final int start, final int count,
final int after) {
}
@Override
public void onTextChanged(final CharSequence s, final int start, final int before,
final int count) {
if (count == 0 || before > 0 || TextUtils.equals(s, mExpected)) {
return;
}
final int len = s.length();
if (len > 0) {
final String last = s.subSequence(len - 1, len).toString();
final char lastChar = last.charAt(0);
if (Character.isUpperCase(lastChar)) {
final String lowerCase = last.toLowerCase(Locale.getDefault());
mHandler.sendMessageDelayed(mHandler.obtainMessage(0, lowerCase), SET_TEXT_DELAY);
} else if (Character.isLowerCase(lastChar)) {
final String upperCase = last.toUpperCase(Locale.getDefault());
mHandler.sendMessageDelayed(mHandler.obtainMessage(0, upperCase), SET_TEXT_DELAY);
}
}
}
}

View File

@ -0,0 +1,473 @@
/*
* Copyright (C) 2010 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.tools.edittextvariations;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.InputType;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public final class EditTextVariations extends Activity implements TextView.OnEditorActionListener,
DialogInterface.OnClickListener {
private static final String TAG = EditTextVariations.class.getSimpleName();
private static final boolean DEBUG_INPUT_TEXT = false;
private static final int MENU_CHANGE_THEME = 0;
private static final int MENU_VERSION = 1;
private static final int MENU_NAVIGATE_ON = 2;
private static final int MENU_NAVIGATE_OFF = 3;
private static final int MENU_SOFTINPUT_VISIBLE = 4;
private static final int MENU_SOFTINPUT_HIDDEN = 5;
private static final String PREF_THEME = "theme";
private static final String PREF_NAVIGATE = "navigate";
private static final String PREF_SOFTINPUT = "softinput";
private SharedPreferences prefs;
private View[] fields;
private static final FinalClassField<Integer> ApplicationInfo_FLAG_SUPPORTS_RTL =
FinalClassField.newInstance(ApplicationInfo.class, "FLAG_SUPPORTS_RTL", 1 << 22);
// This flag should be defined IceCreamSandwich and later.
// Note that Froyo and Gingerbread have hidden IME_FLAG_NO_FULLSCREEN as
// value 0x80000000.
private static final FinalClassField<Integer> EditorInfo_IME_FLAG_FORCE_ASCII =
FinalClassField.newInstance(EditorInfo.class, "IME_FLAG_FORCE_ASCII",
Build.VERSION.SDK_INT >= /* ICE_CREAM_SANDWICH */14 ? 0x80000000 : 0);
private ArrayAdapter<String> mAutoCompleteAdapter;
/** Called when the activity is first created. */
@SuppressLint("SetJavaScriptEnabled")
@Override
public void onCreate(final Bundle savedInstanceState) {
getApplicationInfo().flags |= ApplicationInfo_FLAG_SUPPORTS_RTL.value;
prefs = PreferenceManager.getDefaultSharedPreferences(this);
loadTheme();
loadSoftInputMode();
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final String[] countries = getResources().getStringArray(R.array.countries_array);
mAutoCompleteAdapter = new ArrayAdapter<>(
this, android.R.layout.simple_dropdown_item_1line, countries);
final boolean navigateMode = getNavigateMode();
final ViewGroup vg = (ViewGroup) findViewById(R.id.edit_text_list);
final int n = vg.getChildCount();
fields = new View[n];
for (int i = 0; i < n; i++) {
final View v = vg.getChildAt(i);
if (v instanceof EditText) {
final int id = v.getId();
final EditText e = (EditText) v;
int inputType = e.getInputType();
int imeOptions = e.getImeOptions();
if (id == R.id.text_auto_correct_previous) {
imeOptions &= ~EditorInfo.IME_MASK_ACTION;
imeOptions |= EditorInfo.IME_ACTION_PREVIOUS;
}
if (id == R.id.text_force_ascii_flag) {
imeOptions |= EditorInfo_IME_FLAG_FORCE_ASCII.value;
}
if (id == R.id.text_null) {
inputType = InputType.TYPE_NULL;
}
if (id == R.id.text_restarting) {
EchoingTextWatcher.attachTo(e);
}
if (navigateMode && i > 0) {
imeOptions |= EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS;
}
if (navigateMode && i < n - 1) {
imeOptions |= EditorInfo.IME_FLAG_NAVIGATE_NEXT;
}
e.setInputType(inputType);
e.setImeOptions(imeOptions);
setupHintText(e);
if (navigateMode) {
e.setOnEditorActionListener(this);
}
}
if (v instanceof AutoCompleteTextView) {
final AutoCompleteTextView e = (AutoCompleteTextView) v;
e.setAdapter(mAutoCompleteAdapter);
e.setThreshold(1);
}
if (v instanceof WebView) {
final WebView wv = (WebView) v;
wv.getSettings().setJavaScriptEnabled(true);
wv.addJavascriptInterface(new Object() {
@JavascriptInterface
public String name() {
return getThemeName();
}
}, "theme");
wv.loadUrl("file:///android_asset/webview.html");
}
fields[i] = v;
}
}
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(Menu.NONE, MENU_NAVIGATE_ON, 0, getString(R.string.menu_navigate_on));
menu.add(Menu.NONE, MENU_NAVIGATE_OFF, 1, getString(R.string.menu_navigate_off));
menu.add(Menu.NONE, MENU_SOFTINPUT_VISIBLE, 2, getString(R.string.menu_softinput_visible));
menu.add(Menu.NONE, MENU_SOFTINPUT_HIDDEN, 3, getString(R.string.menu_softinput_hidden));
menu.add(Menu.NONE, MENU_CHANGE_THEME, 4, R.string.menu_change_theme);
try {
final PackageInfo pinfo = getPackageManager().getPackageInfo(getPackageName(), 0);
menu.add(Menu.NONE, MENU_VERSION, 5,
getString(R.string.menu_version, pinfo.versionName))
.setEnabled(false);
} catch (NameNotFoundException e) {
return false;
}
return true;
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
final int itemId = item.getItemId();
if (itemId == MENU_CHANGE_THEME) {
final List<CharSequence> items = new ArrayList<>();
for (final ThemeItem theme : ThemeItem.THEME_LIST) {
items.add(theme.name);
}
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.menu_change_theme);
builder.setCancelable(true);
builder.setNegativeButton(android.R.string.cancel, null);
builder.setItems(items.toArray(new CharSequence[items.size()]), this);
builder.show();
} else if (itemId == MENU_NAVIGATE_ON || itemId == MENU_NAVIGATE_OFF) {
saveNavigateMode(itemId == MENU_NAVIGATE_ON);
restartActivity();
} else if (itemId == MENU_SOFTINPUT_VISIBLE || itemId == MENU_SOFTINPUT_HIDDEN) {
saveSoftInputMode(itemId == MENU_SOFTINPUT_VISIBLE);
restartActivity();
}
return true;
}
@Override
public void onClick(final DialogInterface dialog, final int which) {
saveTheme(ThemeItem.THEME_LIST.get(which));
restartActivity();
}
private void restartActivity() {
final Intent intent = getIntent();
finish();
startActivity(intent);
}
private static void setupHintText(final EditText e) {
final int imeOptions = e.getImeOptions();
String hint = (e instanceof MultiLineShortMessageEditText) ? "*" : "";
hint += inputTypeToString(e.getInputType());
String text;
if (e.getImeActionLabel() != null) {
text = "actionLabel<" + e.getImeActionLabel() + ":" + e.getImeActionId() + ">";
} else {
text = actionName(imeOptions & EditorInfo.IME_MASK_ACTION);
}
text = appendFlagText(text,
(imeOptions & EditorInfo.IME_FLAG_NO_EXTRACT_UI) != 0, "flagNoExtractUi");
text = appendFlagText(text,
(imeOptions & EditorInfo.IME_FLAG_NO_FULLSCREEN) != 0, "flagNoFullscreen");
text = appendFlagText(text,
(imeOptions & EditorInfo_IME_FLAG_FORCE_ASCII.value) != 0, "flagForceAscii");
text = appendFlagText(text,
(imeOptions & EditorInfo.IME_FLAG_NAVIGATE_NEXT) != 0, ">");
text = appendFlagText(text,
(imeOptions & EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS) != 0, "<");
if (text.length() > 0)
hint += " " + text;
final String privateOptions = e.getPrivateImeOptions();
if (!TextUtils.isEmpty(privateOptions)) {
hint += " (";
String sep = "";
for (final String opt : privateOptions.trim().split(",")) {
final String[] elem = opt.trim().split("\\.");
hint += sep + elem[elem.length - 1];
sep = ",";
}
hint += ")";
}
if (DEBUG_INPUT_TEXT) {
Log.d(TAG, String.format("class=0x%08x variation=0x%08x flags=0x%08x hint=%s",
e.getInputType() & InputType.TYPE_MASK_CLASS,
e.getInputType() & InputType.TYPE_MASK_VARIATION,
e.getInputType() & InputType.TYPE_MASK_FLAGS, hint));
}
if (e.getId() == R.id.text_restarting) {
hint += " restarting";
}
e.setHint(hint);
}
private void saveBooleanPreference(final String key, final boolean value) {
final SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(key, value);
editor.apply();
}
private void saveStringPreference(final String key, final String value) {
final SharedPreferences.Editor editor = prefs.edit();
editor.putString(key, value);
editor.apply();
}
private void saveNavigateMode(final boolean enabled) {
saveBooleanPreference(PREF_NAVIGATE, enabled);
}
private boolean getNavigateMode() {
return prefs.getBoolean(PREF_NAVIGATE, false);
}
private void saveSoftInputMode(final boolean visible) {
saveBooleanPreference(PREF_SOFTINPUT, visible);
}
private void loadSoftInputMode() {
final boolean visible = prefs.getBoolean(PREF_SOFTINPUT, false);
final Window w = getWindow();
w.setSoftInputMode(visible
? WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
: WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
}
private void saveTheme(final ThemeItem theme) {
saveStringPreference(PREF_THEME, theme.name);
}
String getThemeName() {
return prefs.getString(PREF_THEME, ThemeItem.getDefaultThemeName());
}
private void loadTheme() {
final String themeName = getThemeName();
for (final ThemeItem theme : ThemeItem.THEME_LIST) {
if (themeName.equals(theme.name)) {
setTheme(theme.id);
return;
}
}
}
@Override
public boolean onEditorAction(final TextView v, final int action, final KeyEvent event) {
for (int i = 0; i < fields.length; i++) {
if (v == fields[i]) {
final int direction;
if (action == EditorInfo.IME_ACTION_PREVIOUS) {
direction = -1;
} else {
direction = +1;
}
final int target = i + direction;
if (target < 0 || target >= fields.length)
return false;
final View targetView = fields[target];
targetView.requestFocus();
return true;
}
}
return false;
}
private static String actionName(final int action) {
switch (action & EditorInfo.IME_MASK_ACTION) {
case EditorInfo.IME_ACTION_UNSPECIFIED:
return "actionUnspecified";
case EditorInfo.IME_ACTION_NONE:
return "actionNone";
case EditorInfo.IME_ACTION_GO:
return "actionGo";
case EditorInfo.IME_ACTION_SEARCH:
return "actionSearch";
case EditorInfo.IME_ACTION_SEND:
return "actionSend";
case EditorInfo.IME_ACTION_NEXT:
return "actionNext";
case EditorInfo.IME_ACTION_DONE:
return "actionDone";
case EditorInfo.IME_ACTION_PREVIOUS:
return "actionPrevious";
default:
return "actionUnknown(" + action + ")";
}
}
private static String inputTypeToString(final int inputType) {
if (inputType == InputType.TYPE_NULL) {
return "TYPE_NULL";
}
final int clazz = inputType & InputType.TYPE_MASK_CLASS;
final int variation = inputType & InputType.TYPE_MASK_VARIATION;
final int flags = inputType & InputType.TYPE_MASK_FLAGS;
String base = "unknown(class=" + clazz + " variation=" + variation + " flag=0x"
+ Integer.toHexString(flags);
switch (clazz) {
case InputType.TYPE_CLASS_TEXT:
switch (variation) {
case InputType.TYPE_TEXT_VARIATION_NORMAL:
base = "text";
break;
case InputType.TYPE_TEXT_VARIATION_URI:
base = "textUri";
break;
case InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS:
base = "textEmailAddress";
break;
case InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT:
base = "textEmailSubject";
break;
case InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE:
base = "textShortMessage";
break;
case InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE:
base = "textLongMessage";
break;
case InputType.TYPE_TEXT_VARIATION_PERSON_NAME:
base = "textPersonName";
break;
case InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS:
base = "textPostalAddress";
break;
case InputType.TYPE_TEXT_VARIATION_PASSWORD:
base = "textPassword";
break;
case InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD:
base = "textVisiblePassword";
break;
case InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT:
base = "textWebEditText";
break;
case InputType.TYPE_TEXT_VARIATION_FILTER:
base = "textFilter";
break;
case InputType.TYPE_TEXT_VARIATION_PHONETIC:
base = "textPhonetic";
break;
case InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS:
base = "textWebEmailAddress";
break;
case InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD:
base = "textWebPassword";
break;
}
base = appendFlagText(base, (flags & InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS) != 0,
"textCapCharacters");
base = appendFlagText(base, (flags & InputType.TYPE_TEXT_FLAG_CAP_WORDS) != 0,
"textCapWords");
base = appendFlagText(base, (flags & InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) != 0,
"textCapSentences");
base = appendFlagText(base, (flags & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) != 0,
"textAutoCorrect");
base = appendFlagText(base, (flags & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0,
"textAutoComplete");
base = appendFlagText(base, (flags & InputType.TYPE_TEXT_FLAG_MULTI_LINE) != 0,
"textMultiLine");
base = appendFlagText(base, (flags & InputType.TYPE_TEXT_FLAG_IME_MULTI_LINE) != 0,
"textImeMultiLine");
base = appendFlagText(base, (flags & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0,
"textNoSuggestions");
break;
case InputType.TYPE_CLASS_NUMBER:
if (variation == InputType.TYPE_NUMBER_VARIATION_NORMAL) {
base = "number";
} else if (variation == InputType.TYPE_NUMBER_VARIATION_PASSWORD) {
base = "numberPassword";
}
base = appendFlagText(base, (flags & InputType.TYPE_NUMBER_FLAG_SIGNED) != 0,
"numberSigned");
base = appendFlagText(base, (flags & InputType.TYPE_NUMBER_FLAG_DECIMAL) != 0,
"numberDecimal");
break;
case InputType.TYPE_CLASS_PHONE:
base = "phone";
break;
case InputType.TYPE_CLASS_DATETIME:
switch (variation) {
case InputType.TYPE_DATETIME_VARIATION_NORMAL:
base = "datetime";
break;
case InputType.TYPE_DATETIME_VARIATION_DATE:
base = "date";
break;
case InputType.TYPE_DATETIME_VARIATION_TIME:
base = "time";
break;
}
break;
}
return base;
}
private static String appendFlagText(final String text, final boolean flag, final String name) {
if (flag) {
if (text.length() == 0 || name.startsWith(text))
return name;
return text + "|" + name;
}
return text;
}
}

View File

@ -0,0 +1,64 @@
/*
* 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.tools.edittextvariations;
import java.lang.reflect.Field;
public final class FinalClassField<T> {
public final boolean defined;
public final String name;
public final String className;
public final T value;
@SuppressWarnings("unchecked")
private FinalClassField(final Field field, final String className, final String fieldName,
final T compatValue) {
this.defined = field != null;
this.name = fieldName;
this.className = className;
T v = null;
try {
final Object obj = field.get(null);
v = (T) obj;
} catch (final Exception e) {
v = compatValue;
}
this.value = v;
}
public static <T> FinalClassField<T> newInstance(final Class<?> definedClass, final String name,
final T compatValue) {
if (definedClass == null)
throw new NullPointerException("defined class");
String className = definedClass.getCanonicalName();
try {
return new FinalClassField<>(
definedClass.getField(name), className, name, compatValue);
} catch (Exception e) {
return new FinalClassField<>(null, className, name, compatValue);
}
}
public static <T> FinalClassField<T> newInstance(final String className, final String fieldName,
final T compatValue) {
try {
return newInstance(Class.forName(className), fieldName, compatValue);
} catch (ClassNotFoundException e) {
return new FinalClassField<>(null, className, fieldName, compatValue);
}
}
}

View File

@ -0,0 +1,83 @@
/*
* Copyright (C) 2011 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.tools.edittextvariations;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public final class InstanceMethod {
public final boolean defined;
public final String name;
public final String className;
private final Class<?> clazz;
private final Method method;
private InstanceMethod(final Class<?> receiverClass, final Method instanceMethod,
final String receiverName, final String methodName) {
this.defined = instanceMethod != null;
this.clazz = receiverClass;
this.method = instanceMethod;
this.name = methodName;
this.className = receiverName;
}
public Object invoke(final Object receiverObject, final Object... args) {
if (!defined)
throw new RuntimeException("method " + name + " not defined");
if (receiverObject == null)
throw new NullPointerException("receiver object");
if (clazz.isInstance(receiverObject)) {
try {
if (args.length == 0) {
return method.invoke(receiverObject);
}
return method.invoke(clazz, args);
} catch (IllegalArgumentException e) {
throw new RuntimeException("IllegalArgumentException");
} catch (IllegalAccessException e) {
throw new RuntimeException("IllegalAccessException");
} catch (InvocationTargetException e) {
throw new RuntimeException("InvocationTargetException");
}
}
throw new RuntimeException("receiver type not matched: method=" + name
+ " actual receiver=" + receiverObject.getClass().getCanonicalName());
}
public static InstanceMethod newInstance(final Class<?> receiverClass, final String methodName,
final Class<?>... parameterTypes) {
if (receiverClass == null)
throw new NullPointerException("receiver class");
final String className = receiverClass.getCanonicalName();
try {
return new InstanceMethod(receiverClass,
receiverClass.getMethod(methodName, parameterTypes), className, methodName);
} catch (Exception e) {
return new InstanceMethod(receiverClass, null, className, methodName);
}
}
public static InstanceMethod newInstance(final String className, final String methodName,
final Class<?>... parameterTypes) {
try {
return newInstance(Class.forName(className), methodName, parameterTypes);
} catch (ClassNotFoundException e) {
return new InstanceMethod(null, null, className, methodName);
}
}
}

View File

@ -0,0 +1,46 @@
/*
* 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.tools.edittextvariations;
import android.content.Context;
import android.util.AttributeSet;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.EditText;
public final class MultiLineShortMessageEditText extends EditText {
public MultiLineShortMessageEditText(final Context context) {
super(context);
}
public MultiLineShortMessageEditText(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public MultiLineShortMessageEditText(final Context context, final AttributeSet attrs,
final int defStyle) {
super(context, attrs, defStyle);
}
@Override
public InputConnection onCreateInputConnection(final EditorInfo outAttrs) {
final InputConnection ic = super.onCreateInputConnection(outAttrs);
outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
return ic;
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (C) 2011 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.tools.edittextvariations;
import android.os.Build;
import com.android.inputmethod.tools.edittextvariations.R;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public final class ThemeItem {
public final int id;
public final String name;
private ThemeItem(final String name, final int resId) {
this.id = resId;
this.name = name;
}
private static final String THEME_DEFAULT = "Default";
private static final String THEME_HOLO = "Theme_Holo";
private static final String THEME_HOLO_LIGHT = "Theme_Holo_Light";
private static final String THEME_DEVICE_DEFAULT = "Theme_DeviceDefault";
private static final String THEME_DEVICE_DEFAULT_LIGHT = "Theme_DeviceDefault_Light";
private static final String THEME_MATERIAL = "Theme_Material";
private static final String THEME_MATERIAL_LIGHT = "Theme_Material_Light";
public static String getDefaultThemeName() {
return THEME_DEFAULT;
}
public static final List<ThemeItem> THEME_LIST = createThemeList(
THEME_HOLO, THEME_HOLO_LIGHT, THEME_DEVICE_DEFAULT, THEME_DEVICE_DEFAULT_LIGHT,
THEME_MATERIAL, THEME_MATERIAL_LIGHT);
private static List<ThemeItem> createThemeList(final String... candidateList) {
final ArrayList<ThemeItem> list = new ArrayList<>();
// Default theme is always available as it's defined in our resource.
list.add(new ThemeItem(THEME_DEFAULT, R.style.defaultActivityTheme));
for (final String name : candidateList) {
final FinalClassField<Integer> constant =
FinalClassField.newInstance(android.R.style.class, name, 0);
if (constant.defined) {
list.add(new ThemeItem(name, constant.value));
}
}
return Collections.unmodifiableList(list);
}
}