blob: da80f9a66fa934ea778048038a5621751d8e5c52 [file] [log] [blame]
The Android Open Source Project9d9730a2009-03-03 19:32:37 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
Wink Saville79085fc2009-06-09 10:27:23 -07003 *
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +09004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Wink Saville79085fc2009-06-09 10:27:23 -07007 *
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +09008 * http://www.apache.org/licenses/LICENSE-2.0
Wink Saville79085fc2009-06-09 10:27:23 -07009 *
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080010 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.stk;
18
Takanori Nakano48544352016-12-02 18:32:59 +090019import android.app.ActionBar;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080020import android.app.Activity;
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +090021import android.app.AlarmManager;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080022import android.content.Context;
23import android.content.Intent;
Yoshiaki Naka28313ba2017-08-04 12:20:53 +090024import android.content.res.Configuration;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080025import android.os.Bundle;
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +090026import android.os.SystemClock;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080027import android.text.Editable;
28import android.text.InputFilter;
Yoshiaki Nakadd0dbb12017-08-03 21:20:38 +090029import android.text.TextUtils;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080030import android.text.TextWatcher;
31import android.text.method.PasswordTransformationMethod;
32import android.view.KeyEvent;
Yoshiaki Naka28313ba2017-08-04 12:20:53 +090033import android.view.Menu;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080034import android.view.MenuItem;
35import android.view.View;
Kazuhiro Uto12870912018-07-18 17:43:56 +090036import android.view.WindowManager;
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +090037import android.view.inputmethod.EditorInfo;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080038import android.widget.Button;
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +090039import android.widget.EditText;
Takanori Nakano48544352016-12-02 18:32:59 +090040import android.widget.ImageView;
Yoshiaki Naka28313ba2017-08-04 12:20:53 +090041import android.widget.PopupMenu;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080042import android.widget.TextView;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080043import android.widget.TextView.BufferType;
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +090044
Yoshiaki Nakac1efd352019-02-21 17:13:38 +090045import androidx.appcompat.app.AppCompatActivity;
46import androidx.appcompat.widget.Toolbar;
47
Wink Savillee68857d2014-10-17 15:23:05 -070048import com.android.internal.telephony.cat.CatLog;
Alex Yakavenkad41f1d92010-07-12 14:13:13 -070049import com.android.internal.telephony.cat.Input;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080050
Yoshiaki Nakac1efd352019-02-21 17:13:38 +090051import com.google.android.material.textfield.TextInputLayout;
52
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080053/**
54 * Display a request for a text input a long with a text edit form.
55 */
Yoshiaki Nakac1efd352019-02-21 17:13:38 +090056public class StkInputActivity extends AppCompatActivity implements View.OnClickListener,
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080057 TextWatcher {
58
59 // Members
60 private int mState;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080061 private EditText mTextIn = null;
62 private TextView mPromptView = null;
Yoshiaki Naka28313ba2017-08-04 12:20:53 +090063 private View mMoreOptions = null;
64 private PopupMenu mPopupMenu = null;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080065 private View mYesNoLayout = null;
66 private View mNormalLayout = null;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080067
68 // Constants
Wink Savillee68857d2014-10-17 15:23:05 -070069 private static final String className = new Object(){}.getClass().getEnclosingClass().getName();
70 private static final String LOG_TAG = className.substring(className.lastIndexOf('.') + 1);
71
72 private Input mStkInput = null;
Wink Savillee68857d2014-10-17 15:23:05 -070073 // Constants
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080074 private static final int STATE_TEXT = 1;
75 private static final int STATE_YES_NO = 2;
76
77 static final String YES_STR_RESPONSE = "YES";
78 static final String NO_STR_RESPONSE = "NO";
79
80 // Font size factor values.
81 static final float NORMAL_FONT_FACTOR = 1;
82 static final float LARGE_FONT_FACTOR = 2;
83 static final float SMALL_FONT_FACTOR = (1 / 2);
84
Takanori Nakano1a672e62017-10-19 19:49:38 +090085 // Keys for saving the state of the activity in the bundle
Takanori Nakano1a672e62017-10-19 19:49:38 +090086 private static final String RESPONSE_SENT_KEY = "response_sent";
87 private static final String INPUT_STRING_KEY = "input_string";
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +090088 private static final String ALARM_TIME_KEY = "alarm_time";
Yoshiaki Naka03a79d92018-08-09 18:41:31 +090089 private static final String PENDING = "pending";
Takanori Nakano1a672e62017-10-19 19:49:38 +090090
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +090091 private static final String INPUT_ALARM_TAG = LOG_TAG;
92 private static final long NO_INPUT_ALARM = -1;
93 private long mAlarmTime = NO_INPUT_ALARM;
94
Wink Savillee68857d2014-10-17 15:23:05 -070095 private StkAppService appService = StkAppService.getInstance();
96
97 private boolean mIsResponseSent = false;
Yoshiaki Naka03a79d92018-08-09 18:41:31 +090098 // Determines whether this is in the pending state.
99 private boolean mIsPending = false;
Wink Savillee68857d2014-10-17 15:23:05 -0700100 private int mSlotId = -1;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800101
102 // Click listener to handle buttons press..
103 public void onClick(View v) {
104 String input = null;
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +0900105 if (mIsResponseSent) {
106 CatLog.d(LOG_TAG, "Already responded");
Wink Savillee68857d2014-10-17 15:23:05 -0700107 return;
108 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800109
110 switch (v.getId()) {
111 case R.id.button_ok:
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800112 input = mTextIn.getText().toString();
113 break;
Takanori Nakano260df9a2017-12-05 22:26:30 +0900114 case R.id.button_cancel:
Takanori Nakano260df9a2017-12-05 22:26:30 +0900115 sendResponse(StkAppService.RES_ID_END_SESSION);
Yoshiaki Naka03a79d92018-08-09 18:41:31 +0900116 finish();
Takanori Nakano260df9a2017-12-05 22:26:30 +0900117 return;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800118 // Yes/No layout buttons.
119 case R.id.button_yes:
120 input = YES_STR_RESPONSE;
121 break;
122 case R.id.button_no:
123 input = NO_STR_RESPONSE;
124 break;
Yoshiaki Naka28313ba2017-08-04 12:20:53 +0900125 case R.id.more:
126 if (mPopupMenu == null) {
127 mPopupMenu = new PopupMenu(this, v);
128 Menu menu = mPopupMenu.getMenu();
129 createOptionsMenuInternal(menu);
130 prepareOptionsMenuInternal(menu);
131 mPopupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
132 public boolean onMenuItemClick(MenuItem item) {
133 optionsItemSelectedInternal(item);
134 return true;
135 }
136 });
137 mPopupMenu.setOnDismissListener(new PopupMenu.OnDismissListener() {
138 public void onDismiss(PopupMenu menu) {
139 mPopupMenu = null;
140 }
141 });
142 mPopupMenu.show();
143 }
144 return;
145 default:
146 break;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800147 }
Wink Savillee68857d2014-10-17 15:23:05 -0700148 CatLog.d(LOG_TAG, "handleClick, ready to response");
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800149 sendResponse(StkAppService.RES_ID_INPUT, input, false);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800150 }
151
152 @Override
Takanori Nakano1a672e62017-10-19 19:49:38 +0900153 public void onCreate(Bundle savedInstanceState) {
154 super.onCreate(savedInstanceState);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800155
Wink Savillee68857d2014-10-17 15:23:05 -0700156 CatLog.d(LOG_TAG, "onCreate - mIsResponseSent[" + mIsResponseSent + "]");
157
Ryuto Sawadaba9b86b2016-10-03 14:03:16 +0900158 // appService can be null if this activity is automatically recreated by the system
159 // with the saved instance state right after the phone process is killed.
160 if (appService == null) {
161 CatLog.d(LOG_TAG, "onCreate - appService is null");
162 finish();
163 return;
164 }
165
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800166 // Set the layout for this activity.
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800167 setContentView(R.layout.stk_input);
Yoshiaki Nakac1efd352019-02-21 17:13:38 +0900168 setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800169
Yoshiaki Nakac1efd352019-02-21 17:13:38 +0900170 if (getResources().getBoolean(R.bool.show_menu_title_only_on_menu)) {
171 getSupportActionBar().hide();
172
Yoshiaki Naka28313ba2017-08-04 12:20:53 +0900173 mMoreOptions = findViewById(R.id.more);
174 mMoreOptions.setVisibility(View.VISIBLE);
175 mMoreOptions.setOnClickListener(this);
176 }
177
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800178 // Initialize members
179 mTextIn = (EditText) this.findViewById(R.id.in_text);
180 mPromptView = (TextView) this.findViewById(R.id.prompt);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800181 // Set buttons listeners.
Wink Saville79085fc2009-06-09 10:27:23 -0700182 Button okButton = (Button) findViewById(R.id.button_ok);
Takanori Nakano260df9a2017-12-05 22:26:30 +0900183 Button cancelButton = (Button) findViewById(R.id.button_cancel);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800184 Button yesButton = (Button) findViewById(R.id.button_yes);
185 Button noButton = (Button) findViewById(R.id.button_no);
186
187 okButton.setOnClickListener(this);
Takanori Nakano260df9a2017-12-05 22:26:30 +0900188 cancelButton.setOnClickListener(this);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800189 yesButton.setOnClickListener(this);
190 noButton.setOnClickListener(this);
191
192 mYesNoLayout = findViewById(R.id.yes_no_layout);
193 mNormalLayout = findViewById(R.id.normal_layout);
Wink Savillee68857d2014-10-17 15:23:05 -0700194 initFromIntent(getIntent());
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800195 }
196
197 @Override
198 protected void onPostCreate(Bundle savedInstanceState) {
199 super.onPostCreate(savedInstanceState);
200
201 mTextIn.addTextChangedListener(this);
202 }
203
204 @Override
205 public void onResume() {
206 super.onResume();
Wink Savillee68857d2014-10-17 15:23:05 -0700207 CatLog.d(LOG_TAG, "onResume - mIsResponseSent[" + mIsResponseSent +
208 "], slot id: " + mSlotId);
Yoshiaki Naka03a79d92018-08-09 18:41:31 +0900209 // If the terminal has already sent response to the card when this activity is resumed,
210 // keep this as a pending activity as this should be finished when the session ends.
211 if (!mIsResponseSent) {
212 setPendingState(false);
213 }
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +0900214
215 if (mAlarmTime == NO_INPUT_ALARM) {
216 startTimeOut();
217 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800218 }
219
220 @Override
221 public void onPause() {
222 super.onPause();
Wink Savillee68857d2014-10-17 15:23:05 -0700223 CatLog.d(LOG_TAG, "onPause - mIsResponseSent[" + mIsResponseSent + "]");
Yoshiaki Naka28313ba2017-08-04 12:20:53 +0900224 if (mPopupMenu != null) {
225 mPopupMenu.dismiss();
226 }
Wink Savillee68857d2014-10-17 15:23:05 -0700227 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800228
Wink Savillee68857d2014-10-17 15:23:05 -0700229 @Override
230 public void onStop() {
231 super.onStop();
232 CatLog.d(LOG_TAG, "onStop - mIsResponseSent[" + mIsResponseSent + "]");
Takanori Nakano1a672e62017-10-19 19:49:38 +0900233
Yoshiaki Naka03a79d92018-08-09 18:41:31 +0900234 // Nothing should be done here if this activity is being finished or restarted now.
235 if (isFinishing() || isChangingConfigurations()) {
Takanori Nakano1a672e62017-10-19 19:49:38 +0900236 return;
237 }
238
Yoshiaki Naka9de7afa2018-08-15 19:07:35 +0900239 if (mIsResponseSent) {
240 // It is unnecessary to keep this activity if the response was already sent and
241 // the dialog activity is NOT on the top of this activity.
242 if (!appService.isStkDialogActivated()) {
243 finish();
244 }
Wink Savillee68857d2014-10-17 15:23:05 -0700245 } else {
Yoshiaki Naka03a79d92018-08-09 18:41:31 +0900246 // This should be registered as the pending activity here
Yoshiaki Naka9de7afa2018-08-15 19:07:35 +0900247 // only when no response has been sent back to the card.
Yoshiaki Naka03a79d92018-08-09 18:41:31 +0900248 setPendingState(true);
Wink Savillee68857d2014-10-17 15:23:05 -0700249 }
250 }
251
252 @Override
253 public void onDestroy() {
254 super.onDestroy();
255 CatLog.d(LOG_TAG, "onDestroy - before Send End Session mIsResponseSent[" +
256 mIsResponseSent + " , " + mSlotId + "]");
Ryuto Sawadaba9b86b2016-10-03 14:03:16 +0900257 if (appService == null) {
258 return;
259 }
Takanori Nakano1a672e62017-10-19 19:49:38 +0900260 // Avoid sending the terminal response while the activty is being restarted
261 // due to some kind of configuration change.
262 if (!isChangingConfigurations()) {
263 // If the input activity is finished by stkappservice
264 // when receiving OP_LAUNCH_APP from the other SIM, we can not send TR here,
265 // since the input cmd is waiting user to process.
266 if (!mIsResponseSent && !appService.isInputPending(mSlotId)) {
267 CatLog.d(LOG_TAG, "handleDestroy - Send End Session");
268 sendResponse(StkAppService.RES_ID_END_SESSION);
269 }
Wink Savillee68857d2014-10-17 15:23:05 -0700270 }
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +0900271 cancelTimeOut();
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800272 }
273
274 @Override
Yoshiaki Naka28313ba2017-08-04 12:20:53 +0900275 public void onConfigurationChanged(Configuration newConfig) {
276 super.onConfigurationChanged(newConfig);
277 if (mPopupMenu != null) {
278 mPopupMenu.dismiss();
279 }
280 }
281
282 @Override
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800283 public boolean onKeyDown(int keyCode, KeyEvent event) {
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +0900284 if (mIsResponseSent) {
285 CatLog.d(LOG_TAG, "Already responded");
Wink Savillee68857d2014-10-17 15:23:05 -0700286 return true;
287 }
288
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800289 switch (keyCode) {
290 case KeyEvent.KEYCODE_BACK:
Wink Savillee68857d2014-10-17 15:23:05 -0700291 CatLog.d(LOG_TAG, "onKeyDown - KEYCODE_BACK");
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800292 sendResponse(StkAppService.RES_ID_BACKWARD, null, false);
Wink Savillee68857d2014-10-17 15:23:05 -0700293 return true;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800294 }
295 return super.onKeyDown(keyCode, event);
296 }
297
Wink Savillee68857d2014-10-17 15:23:05 -0700298 void sendResponse(int resId) {
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800299 sendResponse(resId, null, false);
300 }
301
Wink Savillee68857d2014-10-17 15:23:05 -0700302 void sendResponse(int resId, String input, boolean help) {
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +0900303 cancelTimeOut();
304
Wink Savillee68857d2014-10-17 15:23:05 -0700305 if (mSlotId == -1) {
306 CatLog.d(LOG_TAG, "slot id is invalid");
307 return;
308 }
309
310 if (StkAppService.getInstance() == null) {
311 CatLog.d(LOG_TAG, "StkAppService is null, Ignore response: id is " + resId);
312 return;
313 }
314
Yoshiaki Naka28313ba2017-08-04 12:20:53 +0900315 if (mMoreOptions != null) {
316 mMoreOptions.setVisibility(View.INVISIBLE);
317 }
318
Cuihtlauac ALVARADObde7f032015-05-29 16:25:12 +0200319 CatLog.d(LOG_TAG, "sendResponse resID[" + resId + "] input[*****] help["
320 + help + "]");
Wink Savillee68857d2014-10-17 15:23:05 -0700321 mIsResponseSent = true;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800322 Bundle args = new Bundle();
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800323 args.putInt(StkAppService.RES_ID, resId);
324 if (input != null) {
325 args.putString(StkAppService.INPUT, input);
326 }
327 args.putBoolean(StkAppService.HELP, help);
Takanori Nakano43dacc02018-07-26 11:27:39 +0900328 appService.sendResponse(args, mSlotId);
Yoshiaki Naka03a79d92018-08-09 18:41:31 +0900329
330 // This instance should be set as a pending activity and finished by the service
331 if (resId != StkAppService.RES_ID_END_SESSION) {
332 setPendingState(true);
333 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800334 }
335
336 @Override
337 public boolean onCreateOptionsMenu(android.view.Menu menu) {
338 super.onCreateOptionsMenu(menu);
Yoshiaki Naka28313ba2017-08-04 12:20:53 +0900339 createOptionsMenuInternal(menu);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800340 return true;
341 }
342
Yoshiaki Naka28313ba2017-08-04 12:20:53 +0900343 private void createOptionsMenuInternal(Menu menu) {
344 menu.add(Menu.NONE, StkApp.MENU_ID_END_SESSION, 1, R.string.menu_end_session);
345 menu.add(0, StkApp.MENU_ID_HELP, 2, R.string.help);
346 }
347
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800348 @Override
349 public boolean onPrepareOptionsMenu(android.view.Menu menu) {
350 super.onPrepareOptionsMenu(menu);
Yoshiaki Naka28313ba2017-08-04 12:20:53 +0900351 prepareOptionsMenuInternal(menu);
352 return true;
353 }
354
355 private void prepareOptionsMenuInternal(Menu menu) {
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800356 menu.findItem(StkApp.MENU_ID_END_SESSION).setVisible(true);
357 menu.findItem(StkApp.MENU_ID_HELP).setVisible(mStkInput.helpAvailable);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800358 }
359
360 @Override
361 public boolean onOptionsItemSelected(MenuItem item) {
Yoshiaki Naka28313ba2017-08-04 12:20:53 +0900362 if (optionsItemSelectedInternal(item)) {
363 return true;
364 }
365 return super.onOptionsItemSelected(item);
366 }
367
368 private boolean optionsItemSelectedInternal(MenuItem item) {
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +0900369 if (mIsResponseSent) {
370 CatLog.d(LOG_TAG, "Already responded");
Wink Savillee68857d2014-10-17 15:23:05 -0700371 return true;
372 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800373 switch (item.getItemId()) {
374 case StkApp.MENU_ID_END_SESSION:
375 sendResponse(StkAppService.RES_ID_END_SESSION);
376 finish();
377 return true;
378 case StkApp.MENU_ID_HELP:
379 sendResponse(StkAppService.RES_ID_INPUT, "", true);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800380 return true;
381 }
Yoshiaki Naka28313ba2017-08-04 12:20:53 +0900382 return false;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800383 }
384
Wink Savillee68857d2014-10-17 15:23:05 -0700385 @Override
386 protected void onSaveInstanceState(Bundle outState) {
387 CatLog.d(LOG_TAG, "onSaveInstanceState: " + mSlotId);
Takanori Nakano1a672e62017-10-19 19:49:38 +0900388 outState.putBoolean(RESPONSE_SENT_KEY, mIsResponseSent);
389 outState.putString(INPUT_STRING_KEY, mTextIn.getText().toString());
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +0900390 outState.putLong(ALARM_TIME_KEY, mAlarmTime);
Yoshiaki Naka03a79d92018-08-09 18:41:31 +0900391 outState.putBoolean(PENDING, mIsPending);
Wink Savillee68857d2014-10-17 15:23:05 -0700392 }
393
394 @Override
395 protected void onRestoreInstanceState(Bundle savedInstanceState) {
396 CatLog.d(LOG_TAG, "onRestoreInstanceState: " + mSlotId);
Takanori Nakano1a672e62017-10-19 19:49:38 +0900397
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +0900398 mIsResponseSent = savedInstanceState.getBoolean(RESPONSE_SENT_KEY);
399 if (mIsResponseSent && (mMoreOptions != null)) {
Yoshiaki Naka28313ba2017-08-04 12:20:53 +0900400 mMoreOptions.setVisibility(View.INVISIBLE);
401 }
Takanori Nakano1a672e62017-10-19 19:49:38 +0900402
Takanori Nakano1a672e62017-10-19 19:49:38 +0900403 String savedString = savedInstanceState.getString(INPUT_STRING_KEY);
Miyu Iijima1e28c652018-11-14 10:08:05 +0900404 mTextIn.setText(savedString);
405 updateButton();
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +0900406
407 mAlarmTime = savedInstanceState.getLong(ALARM_TIME_KEY, NO_INPUT_ALARM);
408 if (mAlarmTime != NO_INPUT_ALARM) {
409 startTimeOut();
410 }
Yoshiaki Naka03a79d92018-08-09 18:41:31 +0900411
412 if (!mIsResponseSent && !savedInstanceState.getBoolean(PENDING)) {
413 // If this is in the foreground and no response has been sent to the card,
414 // this must not be registered as pending activity by the previous instance.
415 // No need to renew nor clear pending activity in this case.
416 } else {
417 // Renew the instance of the pending activity.
418 setPendingState(true);
419 }
420 }
421
422 private void setPendingState(boolean on) {
423 if (mIsPending != on) {
424 appService.getStkContext(mSlotId).setPendingActivityInstance(on ? this : null);
425 mIsPending = on;
426 }
Wink Savillee68857d2014-10-17 15:23:05 -0700427 }
428
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800429 public void beforeTextChanged(CharSequence s, int start, int count,
430 int after) {
431 }
432
433 public void onTextChanged(CharSequence s, int start, int before, int count) {
434 // Reset timeout.
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +0900435 cancelTimeOut();
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800436 startTimeOut();
Miyu Iijimac9a17202018-10-17 19:17:14 +0900437 updateButton();
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800438 }
439
440 public void afterTextChanged(Editable s) {
441 }
442
Miyu Iijimac9a17202018-10-17 19:17:14 +0900443 private void updateButton() {
444 // Disable the button if the length of the input text does not meet the expectation.
445 Button okButton = (Button) findViewById(R.id.button_ok);
446 okButton.setEnabled((mTextIn.getText().length() < mStkInput.minLen) ? false : true);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800447 }
448
449 private void cancelTimeOut() {
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +0900450 if (mAlarmTime != NO_INPUT_ALARM) {
451 CatLog.d(LOG_TAG, "cancelTimeOut - slot id: " + mSlotId);
452 AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
453 am.cancel(mAlarmListener);
454 mAlarmTime = NO_INPUT_ALARM;
455 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800456 }
457
458 private void startTimeOut() {
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +0900459 // No need to set alarm if device sent TERMINAL RESPONSE already.
460 if (mIsResponseSent) {
461 return;
Abhishek Adappac7c3a462013-02-14 13:36:57 -0800462 }
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +0900463
464 if (mAlarmTime == NO_INPUT_ALARM) {
465 int duration = StkApp.calculateDurationInMilis(mStkInput.duration);
466 if (duration <= 0) {
467 duration = StkApp.UI_TIMEOUT;
468 }
469 mAlarmTime = SystemClock.elapsedRealtime() + duration;
470 }
471
472 CatLog.d(LOG_TAG, "startTimeOut: " + mAlarmTime + "ms, slot id: " + mSlotId);
473 AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
474 am.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, mAlarmTime, INPUT_ALARM_TAG,
475 mAlarmListener, null);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800476 }
477
478 private void configInputDisplay() {
Yoshiaki Nakac1efd352019-02-21 17:13:38 +0900479 TextInputLayout textInput = (TextInputLayout) findViewById(R.id.text_input_layout);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800480
481 int inTypeId = R.string.alphabet;
482
483 // set the prompt.
Yoshiaki Nakadd0dbb12017-08-03 21:20:38 +0900484 if ((mStkInput.icon == null || !mStkInput.iconSelfExplanatory)
485 && !TextUtils.isEmpty(mStkInput.text)) {
Takeshi Shinoharac6589002013-05-27 11:01:06 +0900486 mPromptView.setText(mStkInput.text);
Yoshiaki Nakadd0dbb12017-08-03 21:20:38 +0900487 mPromptView.setVisibility(View.VISIBLE);
Takeshi Shinoharac6589002013-05-27 11:01:06 +0900488 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800489
Wink Saville79085fc2009-06-09 10:27:23 -0700490 // Set input type (alphabet/digit) info close to the InText form.
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800491 if (mStkInput.digitOnly) {
492 mTextIn.setKeyListener(StkDigitsKeyListener.getInstance());
493 inTypeId = R.string.digits;
494 }
Yoshiaki Nakac1efd352019-02-21 17:13:38 +0900495 textInput.setHelperText(getResources().getString(inTypeId));
496 textInput.setHelperTextEnabled(true);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800497
Yoshiaki Naka28313ba2017-08-04 12:20:53 +0900498 setTitle(R.string.app_name);
Takanori Nakano48544352016-12-02 18:32:59 +0900499
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800500 if (mStkInput.icon != null) {
Yoshiaki Nakadd0dbb12017-08-03 21:20:38 +0900501 ImageView imageView = (ImageView) findViewById(R.id.icon);
Takanori Nakano48544352016-12-02 18:32:59 +0900502 imageView.setImageBitmap(mStkInput.icon);
503 imageView.setVisibility(View.VISIBLE);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800504 }
505
506 // Handle specific global and text attributes.
507 switch (mState) {
Wink Saville79085fc2009-06-09 10:27:23 -0700508 case STATE_TEXT:
Yoshiaki Nakac1efd352019-02-21 17:13:38 +0900509 mTextIn.setFilters(new InputFilter[] {new InputFilter.LengthFilter(mStkInput.maxLen)});
Wink Saville79085fc2009-06-09 10:27:23 -0700510
Yoshiaki Nakac1efd352019-02-21 17:13:38 +0900511 textInput.setCounterMaxLength(mStkInput.maxLen);
512 textInput.setCounterEnabled(true);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800513
514 if (!mStkInput.echo) {
Yujing Gu6b9716c2014-04-23 13:50:50 +0800515 mTextIn.setTransformationMethod(PasswordTransformationMethod
516 .getInstance());
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800517 }
Srikanth Chintalaa091b732016-02-04 14:46:43 +0530518 mTextIn.setImeOptions(EditorInfo.IME_FLAG_NO_FULLSCREEN);
Kazuhiro Uto12870912018-07-18 17:43:56 +0900519 // Request the initial focus on the edit box and show the software keyboard.
520 mTextIn.requestFocus();
521 getWindow().setSoftInputMode(
522 WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800523 // Set default text if present.
524 if (mStkInput.defaultText != null) {
525 mTextIn.setText(mStkInput.defaultText);
526 } else {
527 // make sure the text is cleared
528 mTextIn.setText("", BufferType.EDITABLE);
529 }
Miyu Iijimac9a17202018-10-17 19:17:14 +0900530 updateButton();
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800531
532 break;
533 case STATE_YES_NO:
534 // Set display mode - normal / yes-no layout
535 mYesNoLayout.setVisibility(View.VISIBLE);
536 mNormalLayout.setVisibility(View.GONE);
537 break;
538 }
539 }
540
Wink Savillee68857d2014-10-17 15:23:05 -0700541 private void initFromIntent(Intent intent) {
542 // Get the calling intent type: text/key, and setup the
543 // display parameters.
544 CatLog.d(LOG_TAG, "initFromIntent - slot id: " + mSlotId);
545 if (intent != null) {
546 mStkInput = intent.getParcelableExtra("INPUT");
547 mSlotId = intent.getIntExtra(StkAppService.SLOT_ID, -1);
548 CatLog.d(LOG_TAG, "onCreate - slot id: " + mSlotId);
549 if (mStkInput == null) {
550 finish();
551 } else {
552 mState = mStkInput.yesNo ? STATE_YES_NO :
553 STATE_TEXT;
554 configInputDisplay();
555 }
556 } else {
557 finish();
558 }
559 }
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +0900560
561 private final AlarmManager.OnAlarmListener mAlarmListener =
562 new AlarmManager.OnAlarmListener() {
563 @Override
564 public void onAlarm() {
565 CatLog.d(LOG_TAG, "The alarm time is reached");
566 mAlarmTime = NO_INPUT_ALARM;
Yoshiaki Nakaa95f5c82016-09-02 11:27:05 +0900567 sendResponse(StkAppService.RES_ID_TIMEOUT);
568 }
569 };
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800570}