blob: 219d84cd978aadcfb2baf23cfbbaa5cbddb9737e [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 *
The Android Open Source Project9d9730a2009-03-03 19:32:37 -08004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
Wink Saville79085fc2009-06-09 10:27:23 -07007 *
The Android Open Source Project9d9730a2009-03-03 19:32:37 -08008 * 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
19import android.app.Activity;
20import android.content.Context;
21import android.content.Intent;
22import android.graphics.drawable.BitmapDrawable;
23import android.os.Bundle;
24import android.os.Handler;
25import android.os.Message;
26import android.text.Editable;
27import android.text.InputFilter;
duho.roee36b6f2013-09-03 15:15:16 +090028import android.text.InputType;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080029import android.text.TextWatcher;
30import android.text.method.PasswordTransformationMethod;
31import android.view.KeyEvent;
32import android.view.MenuItem;
33import android.view.View;
34import android.view.Window;
35import android.widget.Button;
36import android.widget.TextView;
37import android.widget.EditText;
38import android.widget.TextView.BufferType;
Wink Savillee68857d2014-10-17 15:23:05 -070039import com.android.internal.telephony.cat.CatLog;
Alex Yakavenkad41f1d92010-07-12 14:13:13 -070040import com.android.internal.telephony.cat.FontSize;
41import com.android.internal.telephony.cat.Input;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080042
43/**
44 * Display a request for a text input a long with a text edit form.
45 */
46public class StkInputActivity extends Activity implements View.OnClickListener,
47 TextWatcher {
48
49 // Members
50 private int mState;
51 private Context mContext;
52 private EditText mTextIn = null;
53 private TextView mPromptView = null;
54 private View mYesNoLayout = null;
55 private View mNormalLayout = null;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080056
57 // Constants
Wink Savillee68857d2014-10-17 15:23:05 -070058 private static final String className = new Object(){}.getClass().getEnclosingClass().getName();
59 private static final String LOG_TAG = className.substring(className.lastIndexOf('.') + 1);
60
61 private Input mStkInput = null;
62 private boolean mAcceptUsersInput = true;
63 // Constants
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080064 private static final int STATE_TEXT = 1;
65 private static final int STATE_YES_NO = 2;
66
67 static final String YES_STR_RESPONSE = "YES";
68 static final String NO_STR_RESPONSE = "NO";
69
70 // Font size factor values.
71 static final float NORMAL_FONT_FACTOR = 1;
72 static final float LARGE_FONT_FACTOR = 2;
73 static final float SMALL_FONT_FACTOR = (1 / 2);
74
Wink Saville79085fc2009-06-09 10:27:23 -070075 // message id for time out
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080076 private static final int MSG_ID_TIMEOUT = 1;
Wink Savillee68857d2014-10-17 15:23:05 -070077 private StkAppService appService = StkAppService.getInstance();
78
79 private boolean mIsResponseSent = false;
80 private int mSlotId = -1;
81 Activity mInstance = null;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080082
83 Handler mTimeoutHandler = new Handler() {
84 @Override
85 public void handleMessage(Message msg) {
86 switch(msg.what) {
87 case MSG_ID_TIMEOUT:
Wink Savillee68857d2014-10-17 15:23:05 -070088 CatLog.d(LOG_TAG, "Msg timeout.");
89 mAcceptUsersInput = false;
90 appService.getStkContext(mSlotId).setPendingActivityInstance(mInstance);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080091 sendResponse(StkAppService.RES_ID_TIMEOUT);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080092 break;
93 }
94 }
95 };
96
97 // Click listener to handle buttons press..
98 public void onClick(View v) {
99 String input = null;
Wink Savillee68857d2014-10-17 15:23:05 -0700100 if (!mAcceptUsersInput) {
101 CatLog.d(LOG_TAG, "mAcceptUsersInput:false");
102 return;
103 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800104
105 switch (v.getId()) {
106 case R.id.button_ok:
107 // Check that text entered is valid .
108 if (!verfiyTypedText()) {
Wink Savillee68857d2014-10-17 15:23:05 -0700109 CatLog.d(LOG_TAG, "handleClick, invalid text");
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800110 return;
111 }
Wink Savillee68857d2014-10-17 15:23:05 -0700112 mAcceptUsersInput = false;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800113 input = mTextIn.getText().toString();
114 break;
115 // Yes/No layout buttons.
116 case R.id.button_yes:
Wink Savillee68857d2014-10-17 15:23:05 -0700117 mAcceptUsersInput = false;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800118 input = YES_STR_RESPONSE;
119 break;
120 case R.id.button_no:
Wink Savillee68857d2014-10-17 15:23:05 -0700121 mAcceptUsersInput = false;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800122 input = NO_STR_RESPONSE;
123 break;
124 }
Wink Savillee68857d2014-10-17 15:23:05 -0700125 CatLog.d(LOG_TAG, "handleClick, ready to response");
Preeti Ahuja03be6672012-08-30 19:21:25 +0530126 cancelTimeOut();
Wink Savillee68857d2014-10-17 15:23:05 -0700127 appService.getStkContext(mSlotId).setPendingActivityInstance(this);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800128 sendResponse(StkAppService.RES_ID_INPUT, input, false);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800129 }
130
131 @Override
132 public void onCreate(Bundle icicle) {
133 super.onCreate(icicle);
134
Wink Savillee68857d2014-10-17 15:23:05 -0700135 CatLog.d(LOG_TAG, "onCreate - mIsResponseSent[" + mIsResponseSent + "]");
136
Ryuto Sawadaba9b86b2016-10-03 14:03:16 +0900137 // appService can be null if this activity is automatically recreated by the system
138 // with the saved instance state right after the phone process is killed.
139 if (appService == null) {
140 CatLog.d(LOG_TAG, "onCreate - appService is null");
141 finish();
142 return;
143 }
144
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800145 // Set the layout for this activity.
Wink Savillee68857d2014-10-17 15:23:05 -0700146 requestWindowFeature(Window.FEATURE_LEFT_ICON);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800147 setContentView(R.layout.stk_input);
148
149 // Initialize members
150 mTextIn = (EditText) this.findViewById(R.id.in_text);
151 mPromptView = (TextView) this.findViewById(R.id.prompt);
Wink Savillee68857d2014-10-17 15:23:05 -0700152 mInstance = this;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800153 // Set buttons listeners.
Wink Saville79085fc2009-06-09 10:27:23 -0700154 Button okButton = (Button) findViewById(R.id.button_ok);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800155 Button yesButton = (Button) findViewById(R.id.button_yes);
156 Button noButton = (Button) findViewById(R.id.button_no);
157
158 okButton.setOnClickListener(this);
159 yesButton.setOnClickListener(this);
160 noButton.setOnClickListener(this);
161
162 mYesNoLayout = findViewById(R.id.yes_no_layout);
163 mNormalLayout = findViewById(R.id.normal_layout);
Wink Savillee68857d2014-10-17 15:23:05 -0700164 initFromIntent(getIntent());
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800165 mContext = getBaseContext();
Wink Savillee68857d2014-10-17 15:23:05 -0700166 mAcceptUsersInput = true;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800167 }
168
169 @Override
170 protected void onPostCreate(Bundle savedInstanceState) {
171 super.onPostCreate(savedInstanceState);
172
173 mTextIn.addTextChangedListener(this);
174 }
175
176 @Override
177 public void onResume() {
178 super.onResume();
Wink Savillee68857d2014-10-17 15:23:05 -0700179 CatLog.d(LOG_TAG, "onResume - mIsResponseSent[" + mIsResponseSent +
180 "], slot id: " + mSlotId);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800181 startTimeOut();
Wink Savillee68857d2014-10-17 15:23:05 -0700182 appService.getStkContext(mSlotId).setPendingActivityInstance(null);
hoonsung.parkcba29962015-07-06 23:17:38 +0900183 if (mIsResponseSent) {
184 cancelTimeOut();
185 finish();
186 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800187 }
188
189 @Override
190 public void onPause() {
191 super.onPause();
Wink Savillee68857d2014-10-17 15:23:05 -0700192 CatLog.d(LOG_TAG, "onPause - mIsResponseSent[" + mIsResponseSent + "]");
193 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800194
Wink Savillee68857d2014-10-17 15:23:05 -0700195 @Override
196 public void onStop() {
197 super.onStop();
198 CatLog.d(LOG_TAG, "onStop - mIsResponseSent[" + mIsResponseSent + "]");
199 if (mIsResponseSent) {
200 cancelTimeOut();
201 finish();
202 } else {
203 appService.getStkContext(mSlotId).setPendingActivityInstance(this);
204 }
205 }
206
207 @Override
208 public void onDestroy() {
209 super.onDestroy();
210 CatLog.d(LOG_TAG, "onDestroy - before Send End Session mIsResponseSent[" +
211 mIsResponseSent + " , " + mSlotId + "]");
Ryuto Sawadaba9b86b2016-10-03 14:03:16 +0900212 if (appService == null) {
213 return;
214 }
Wink Savillee68857d2014-10-17 15:23:05 -0700215 //If the input activity is finished by stkappservice
216 //when receiving OP_LAUNCH_APP from the other SIM, we can not send TR here
217 //, since the input cmd is waiting user to process.
218 if (!mIsResponseSent && !appService.isInputPending(mSlotId)) {
219 CatLog.d(LOG_TAG, "handleDestroy - Send End Session");
220 sendResponse(StkAppService.RES_ID_END_SESSION);
221 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800222 cancelTimeOut();
223 }
224
225 @Override
226 public boolean onKeyDown(int keyCode, KeyEvent event) {
Wink Savillee68857d2014-10-17 15:23:05 -0700227 if (!mAcceptUsersInput) {
228 CatLog.d(LOG_TAG, "mAcceptUsersInput:false");
229 return true;
230 }
231
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800232 switch (keyCode) {
233 case KeyEvent.KEYCODE_BACK:
Wink Savillee68857d2014-10-17 15:23:05 -0700234 CatLog.d(LOG_TAG, "onKeyDown - KEYCODE_BACK");
235 mAcceptUsersInput = false;
Preeti Ahuja03be6672012-08-30 19:21:25 +0530236 cancelTimeOut();
Wink Savillee68857d2014-10-17 15:23:05 -0700237 appService.getStkContext(mSlotId).setPendingActivityInstance(this);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800238 sendResponse(StkAppService.RES_ID_BACKWARD, null, false);
Wink Savillee68857d2014-10-17 15:23:05 -0700239 return true;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800240 }
241 return super.onKeyDown(keyCode, event);
242 }
243
Wink Savillee68857d2014-10-17 15:23:05 -0700244 void sendResponse(int resId) {
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800245 sendResponse(resId, null, false);
246 }
247
Wink Savillee68857d2014-10-17 15:23:05 -0700248 void sendResponse(int resId, String input, boolean help) {
249 if (mSlotId == -1) {
250 CatLog.d(LOG_TAG, "slot id is invalid");
251 return;
252 }
253
254 if (StkAppService.getInstance() == null) {
255 CatLog.d(LOG_TAG, "StkAppService is null, Ignore response: id is " + resId);
256 return;
257 }
258
Cuihtlauac ALVARADObde7f032015-05-29 16:25:12 +0200259 CatLog.d(LOG_TAG, "sendResponse resID[" + resId + "] input[*****] help["
260 + help + "]");
Wink Savillee68857d2014-10-17 15:23:05 -0700261 mIsResponseSent = true;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800262 Bundle args = new Bundle();
263 args.putInt(StkAppService.OPCODE, StkAppService.OP_RESPONSE);
Wink Savillee68857d2014-10-17 15:23:05 -0700264 args.putInt(StkAppService.SLOT_ID, mSlotId);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800265 args.putInt(StkAppService.RES_ID, resId);
266 if (input != null) {
267 args.putString(StkAppService.INPUT, input);
268 }
269 args.putBoolean(StkAppService.HELP, help);
270 mContext.startService(new Intent(mContext, StkAppService.class)
271 .putExtras(args));
272 }
273
274 @Override
275 public boolean onCreateOptionsMenu(android.view.Menu menu) {
276 super.onCreateOptionsMenu(menu);
277 menu.add(android.view.Menu.NONE, StkApp.MENU_ID_END_SESSION, 1,
278 R.string.menu_end_session);
279 menu.add(0, StkApp.MENU_ID_HELP, 2, R.string.help);
280
281 return true;
282 }
283
284 @Override
285 public boolean onPrepareOptionsMenu(android.view.Menu menu) {
286 super.onPrepareOptionsMenu(menu);
287 menu.findItem(StkApp.MENU_ID_END_SESSION).setVisible(true);
288 menu.findItem(StkApp.MENU_ID_HELP).setVisible(mStkInput.helpAvailable);
289
290 return true;
291 }
292
293 @Override
294 public boolean onOptionsItemSelected(MenuItem item) {
Wink Savillee68857d2014-10-17 15:23:05 -0700295 if (!mAcceptUsersInput) {
296 CatLog.d(LOG_TAG, "mAcceptUsersInput:false");
297 return true;
298 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800299 switch (item.getItemId()) {
300 case StkApp.MENU_ID_END_SESSION:
Wink Savillee68857d2014-10-17 15:23:05 -0700301 mAcceptUsersInput = false;
302 cancelTimeOut();
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800303 sendResponse(StkAppService.RES_ID_END_SESSION);
304 finish();
305 return true;
306 case StkApp.MENU_ID_HELP:
Wink Savillee68857d2014-10-17 15:23:05 -0700307 mAcceptUsersInput = false;
308 cancelTimeOut();
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800309 sendResponse(StkAppService.RES_ID_INPUT, "", true);
310 finish();
311 return true;
312 }
313 return super.onOptionsItemSelected(item);
314 }
315
Wink Savillee68857d2014-10-17 15:23:05 -0700316 @Override
317 protected void onSaveInstanceState(Bundle outState) {
318 CatLog.d(LOG_TAG, "onSaveInstanceState: " + mSlotId);
319 outState.putBoolean("ACCEPT_USERS_INPUT", mAcceptUsersInput);
320 }
321
322 @Override
323 protected void onRestoreInstanceState(Bundle savedInstanceState) {
324 CatLog.d(LOG_TAG, "onRestoreInstanceState: " + mSlotId);
325 mAcceptUsersInput = savedInstanceState.getBoolean("ACCEPT_USERS_INPUT");
326 }
327
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800328 public void beforeTextChanged(CharSequence s, int start, int count,
329 int after) {
330 }
331
332 public void onTextChanged(CharSequence s, int start, int before, int count) {
333 // Reset timeout.
334 startTimeOut();
335 }
336
337 public void afterTextChanged(Editable s) {
338 }
339
340 private boolean verfiyTypedText() {
341 // If not enough input was typed in stay on the edit screen.
342 if (mTextIn.getText().length() < mStkInput.minLen) {
343 return false;
344 }
345
346 return true;
347 }
348
349 private void cancelTimeOut() {
350 mTimeoutHandler.removeMessages(MSG_ID_TIMEOUT);
351 }
352
353 private void startTimeOut() {
Abhishek Adappac7c3a462013-02-14 13:36:57 -0800354 int duration = StkApp.calculateDurationInMilis(mStkInput.duration);
355
356 if (duration <= 0) {
357 duration = StkApp.UI_TIMEOUT;
358 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800359 cancelTimeOut();
360 mTimeoutHandler.sendMessageDelayed(mTimeoutHandler
Abhishek Adappac7c3a462013-02-14 13:36:57 -0800361 .obtainMessage(MSG_ID_TIMEOUT), duration);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800362 }
363
364 private void configInputDisplay() {
365 TextView numOfCharsView = (TextView) findViewById(R.id.num_of_chars);
366 TextView inTypeView = (TextView) findViewById(R.id.input_type);
367
368 int inTypeId = R.string.alphabet;
369
370 // set the prompt.
Takeshi Shinoharac6589002013-05-27 11:01:06 +0900371 if (mStkInput.iconSelfExplanatory && mStkInput.icon != null) {
372 mPromptView.setVisibility(View.GONE);
373 } else {
374 mPromptView.setText(mStkInput.text);
375 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800376
Wink Saville79085fc2009-06-09 10:27:23 -0700377 // Set input type (alphabet/digit) info close to the InText form.
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800378 if (mStkInput.digitOnly) {
379 mTextIn.setKeyListener(StkDigitsKeyListener.getInstance());
380 inTypeId = R.string.digits;
381 }
382 inTypeView.setText(inTypeId);
383
384 if (mStkInput.icon != null) {
385 setFeatureDrawable(Window.FEATURE_LEFT_ICON, new BitmapDrawable(
386 mStkInput.icon));
387 }
388
389 // Handle specific global and text attributes.
390 switch (mState) {
Wink Saville79085fc2009-06-09 10:27:23 -0700391 case STATE_TEXT:
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800392 int maxLen = mStkInput.maxLen;
393 int minLen = mStkInput.minLen;
394 mTextIn.setFilters(new InputFilter[] {new InputFilter.LengthFilter(
395 maxLen)});
Wink Saville79085fc2009-06-09 10:27:23 -0700396
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800397 // Set number of chars info.
398 String lengthLimit = String.valueOf(minLen);
399 if (maxLen != minLen) {
400 lengthLimit = minLen + " - " + maxLen;
401 }
402 numOfCharsView.setText(lengthLimit);
403
404 if (!mStkInput.echo) {
Yujing Gu6b9716c2014-04-23 13:50:50 +0800405 mTextIn.setTransformationMethod(PasswordTransformationMethod
406 .getInstance());
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800407 }
408 // Set default text if present.
409 if (mStkInput.defaultText != null) {
410 mTextIn.setText(mStkInput.defaultText);
411 } else {
412 // make sure the text is cleared
413 mTextIn.setText("", BufferType.EDITABLE);
414 }
415
416 break;
417 case STATE_YES_NO:
418 // Set display mode - normal / yes-no layout
419 mYesNoLayout.setVisibility(View.VISIBLE);
420 mNormalLayout.setVisibility(View.GONE);
421 break;
422 }
423 }
424
425 private float getFontSizeFactor(FontSize size) {
Wink Saville79085fc2009-06-09 10:27:23 -0700426 final float[] fontSizes =
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800427 {NORMAL_FONT_FACTOR, LARGE_FONT_FACTOR, SMALL_FONT_FACTOR};
428
429 return fontSizes[size.ordinal()];
430 }
Wink Savillee68857d2014-10-17 15:23:05 -0700431
432 private void initFromIntent(Intent intent) {
433 // Get the calling intent type: text/key, and setup the
434 // display parameters.
435 CatLog.d(LOG_TAG, "initFromIntent - slot id: " + mSlotId);
436 if (intent != null) {
437 mStkInput = intent.getParcelableExtra("INPUT");
438 mSlotId = intent.getIntExtra(StkAppService.SLOT_ID, -1);
439 CatLog.d(LOG_TAG, "onCreate - slot id: " + mSlotId);
440 if (mStkInput == null) {
441 finish();
442 } else {
443 mState = mStkInput.yesNo ? STATE_YES_NO :
444 STATE_TEXT;
445 configInputDisplay();
446 }
447 } else {
448 finish();
449 }
450 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800451}