blob: 9a066ec4f3883efd4dedeeacdb94bfdb14bc24c9 [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
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;
21import android.content.Context;
22import android.content.Intent;
23import android.graphics.drawable.BitmapDrawable;
24import android.os.Bundle;
25import android.os.Handler;
26import android.os.Message;
27import android.text.Editable;
28import android.text.InputFilter;
duho.roee36b6f2013-09-03 15:15:16 +090029import android.text.InputType;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080030import android.text.TextWatcher;
31import android.text.method.PasswordTransformationMethod;
32import android.view.KeyEvent;
33import android.view.MenuItem;
34import android.view.View;
35import android.view.Window;
36import android.widget.Button;
Takanori Nakano48544352016-12-02 18:32:59 +090037import android.widget.ImageView;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080038import android.widget.TextView;
39import android.widget.EditText;
40import android.widget.TextView.BufferType;
Wink Savillee68857d2014-10-17 15:23:05 -070041import com.android.internal.telephony.cat.CatLog;
Alex Yakavenkad41f1d92010-07-12 14:13:13 -070042import com.android.internal.telephony.cat.FontSize;
43import com.android.internal.telephony.cat.Input;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080044
45/**
46 * Display a request for a text input a long with a text edit form.
47 */
48public class StkInputActivity extends Activity implements View.OnClickListener,
49 TextWatcher {
50
51 // Members
52 private int mState;
53 private Context mContext;
54 private EditText mTextIn = null;
55 private TextView mPromptView = null;
56 private View mYesNoLayout = null;
57 private View mNormalLayout = null;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080058
59 // Constants
Wink Savillee68857d2014-10-17 15:23:05 -070060 private static final String className = new Object(){}.getClass().getEnclosingClass().getName();
61 private static final String LOG_TAG = className.substring(className.lastIndexOf('.') + 1);
62
63 private Input mStkInput = null;
64 private boolean mAcceptUsersInput = true;
65 // Constants
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080066 private static final int STATE_TEXT = 1;
67 private static final int STATE_YES_NO = 2;
68
69 static final String YES_STR_RESPONSE = "YES";
70 static final String NO_STR_RESPONSE = "NO";
71
72 // Font size factor values.
73 static final float NORMAL_FONT_FACTOR = 1;
74 static final float LARGE_FONT_FACTOR = 2;
75 static final float SMALL_FONT_FACTOR = (1 / 2);
76
Wink Saville79085fc2009-06-09 10:27:23 -070077 // message id for time out
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080078 private static final int MSG_ID_TIMEOUT = 1;
Wink Savillee68857d2014-10-17 15:23:05 -070079 private StkAppService appService = StkAppService.getInstance();
80
81 private boolean mIsResponseSent = false;
82 private int mSlotId = -1;
83 Activity mInstance = null;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080084
85 Handler mTimeoutHandler = new Handler() {
86 @Override
87 public void handleMessage(Message msg) {
88 switch(msg.what) {
89 case MSG_ID_TIMEOUT:
Wink Savillee68857d2014-10-17 15:23:05 -070090 CatLog.d(LOG_TAG, "Msg timeout.");
91 mAcceptUsersInput = false;
92 appService.getStkContext(mSlotId).setPendingActivityInstance(mInstance);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080093 sendResponse(StkAppService.RES_ID_TIMEOUT);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -080094 break;
95 }
96 }
97 };
98
99 // Click listener to handle buttons press..
100 public void onClick(View v) {
101 String input = null;
Wink Savillee68857d2014-10-17 15:23:05 -0700102 if (!mAcceptUsersInput) {
103 CatLog.d(LOG_TAG, "mAcceptUsersInput:false");
104 return;
105 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800106
107 switch (v.getId()) {
108 case R.id.button_ok:
109 // Check that text entered is valid .
110 if (!verfiyTypedText()) {
Wink Savillee68857d2014-10-17 15:23:05 -0700111 CatLog.d(LOG_TAG, "handleClick, invalid text");
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800112 return;
113 }
Wink Savillee68857d2014-10-17 15:23:05 -0700114 mAcceptUsersInput = false;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800115 input = mTextIn.getText().toString();
116 break;
117 // Yes/No layout buttons.
118 case R.id.button_yes:
Wink Savillee68857d2014-10-17 15:23:05 -0700119 mAcceptUsersInput = false;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800120 input = YES_STR_RESPONSE;
121 break;
122 case R.id.button_no:
Wink Savillee68857d2014-10-17 15:23:05 -0700123 mAcceptUsersInput = false;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800124 input = NO_STR_RESPONSE;
125 break;
126 }
Wink Savillee68857d2014-10-17 15:23:05 -0700127 CatLog.d(LOG_TAG, "handleClick, ready to response");
Preeti Ahuja03be6672012-08-30 19:21:25 +0530128 cancelTimeOut();
Wink Savillee68857d2014-10-17 15:23:05 -0700129 appService.getStkContext(mSlotId).setPendingActivityInstance(this);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800130 sendResponse(StkAppService.RES_ID_INPUT, input, false);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800131 }
132
133 @Override
134 public void onCreate(Bundle icicle) {
135 super.onCreate(icicle);
136
Wink Savillee68857d2014-10-17 15:23:05 -0700137 CatLog.d(LOG_TAG, "onCreate - mIsResponseSent[" + mIsResponseSent + "]");
138
Ryuto Sawadaba9b86b2016-10-03 14:03:16 +0900139 // appService can be null if this activity is automatically recreated by the system
140 // with the saved instance state right after the phone process is killed.
141 if (appService == null) {
142 CatLog.d(LOG_TAG, "onCreate - appService is null");
143 finish();
144 return;
145 }
146
Takanori Nakano48544352016-12-02 18:32:59 +0900147 ActionBar actionBar = getActionBar();
148 actionBar.setCustomView(R.layout.stk_title);
149 actionBar.setDisplayShowCustomEnabled(true);
150
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800151 // Set the layout for this activity.
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800152 setContentView(R.layout.stk_input);
153
154 // Initialize members
155 mTextIn = (EditText) this.findViewById(R.id.in_text);
156 mPromptView = (TextView) this.findViewById(R.id.prompt);
Wink Savillee68857d2014-10-17 15:23:05 -0700157 mInstance = this;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800158 // Set buttons listeners.
Wink Saville79085fc2009-06-09 10:27:23 -0700159 Button okButton = (Button) findViewById(R.id.button_ok);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800160 Button yesButton = (Button) findViewById(R.id.button_yes);
161 Button noButton = (Button) findViewById(R.id.button_no);
162
163 okButton.setOnClickListener(this);
164 yesButton.setOnClickListener(this);
165 noButton.setOnClickListener(this);
166
167 mYesNoLayout = findViewById(R.id.yes_no_layout);
168 mNormalLayout = findViewById(R.id.normal_layout);
Wink Savillee68857d2014-10-17 15:23:05 -0700169 initFromIntent(getIntent());
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800170 mContext = getBaseContext();
Wink Savillee68857d2014-10-17 15:23:05 -0700171 mAcceptUsersInput = true;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800172 }
173
174 @Override
175 protected void onPostCreate(Bundle savedInstanceState) {
176 super.onPostCreate(savedInstanceState);
177
178 mTextIn.addTextChangedListener(this);
179 }
180
181 @Override
182 public void onResume() {
183 super.onResume();
Wink Savillee68857d2014-10-17 15:23:05 -0700184 CatLog.d(LOG_TAG, "onResume - mIsResponseSent[" + mIsResponseSent +
185 "], slot id: " + mSlotId);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800186 startTimeOut();
Wink Savillee68857d2014-10-17 15:23:05 -0700187 appService.getStkContext(mSlotId).setPendingActivityInstance(null);
hoonsung.parkcba29962015-07-06 23:17:38 +0900188 if (mIsResponseSent) {
189 cancelTimeOut();
190 finish();
191 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800192 }
193
194 @Override
195 public void onPause() {
196 super.onPause();
Wink Savillee68857d2014-10-17 15:23:05 -0700197 CatLog.d(LOG_TAG, "onPause - mIsResponseSent[" + mIsResponseSent + "]");
198 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800199
Wink Savillee68857d2014-10-17 15:23:05 -0700200 @Override
201 public void onStop() {
202 super.onStop();
203 CatLog.d(LOG_TAG, "onStop - mIsResponseSent[" + mIsResponseSent + "]");
204 if (mIsResponseSent) {
205 cancelTimeOut();
206 finish();
207 } else {
208 appService.getStkContext(mSlotId).setPendingActivityInstance(this);
209 }
210 }
211
212 @Override
213 public void onDestroy() {
214 super.onDestroy();
215 CatLog.d(LOG_TAG, "onDestroy - before Send End Session mIsResponseSent[" +
216 mIsResponseSent + " , " + mSlotId + "]");
Ryuto Sawadaba9b86b2016-10-03 14:03:16 +0900217 if (appService == null) {
218 return;
219 }
Wink Savillee68857d2014-10-17 15:23:05 -0700220 //If the input activity is finished by stkappservice
221 //when receiving OP_LAUNCH_APP from the other SIM, we can not send TR here
222 //, since the input cmd is waiting user to process.
223 if (!mIsResponseSent && !appService.isInputPending(mSlotId)) {
224 CatLog.d(LOG_TAG, "handleDestroy - Send End Session");
225 sendResponse(StkAppService.RES_ID_END_SESSION);
226 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800227 cancelTimeOut();
228 }
229
230 @Override
231 public boolean onKeyDown(int keyCode, KeyEvent event) {
Wink Savillee68857d2014-10-17 15:23:05 -0700232 if (!mAcceptUsersInput) {
233 CatLog.d(LOG_TAG, "mAcceptUsersInput:false");
234 return true;
235 }
236
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800237 switch (keyCode) {
238 case KeyEvent.KEYCODE_BACK:
Wink Savillee68857d2014-10-17 15:23:05 -0700239 CatLog.d(LOG_TAG, "onKeyDown - KEYCODE_BACK");
240 mAcceptUsersInput = false;
Preeti Ahuja03be6672012-08-30 19:21:25 +0530241 cancelTimeOut();
Wink Savillee68857d2014-10-17 15:23:05 -0700242 appService.getStkContext(mSlotId).setPendingActivityInstance(this);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800243 sendResponse(StkAppService.RES_ID_BACKWARD, null, false);
Wink Savillee68857d2014-10-17 15:23:05 -0700244 return true;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800245 }
246 return super.onKeyDown(keyCode, event);
247 }
248
Wink Savillee68857d2014-10-17 15:23:05 -0700249 void sendResponse(int resId) {
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800250 sendResponse(resId, null, false);
251 }
252
Wink Savillee68857d2014-10-17 15:23:05 -0700253 void sendResponse(int resId, String input, boolean help) {
254 if (mSlotId == -1) {
255 CatLog.d(LOG_TAG, "slot id is invalid");
256 return;
257 }
258
259 if (StkAppService.getInstance() == null) {
260 CatLog.d(LOG_TAG, "StkAppService is null, Ignore response: id is " + resId);
261 return;
262 }
263
Cuihtlauac ALVARADObde7f032015-05-29 16:25:12 +0200264 CatLog.d(LOG_TAG, "sendResponse resID[" + resId + "] input[*****] help["
265 + help + "]");
Wink Savillee68857d2014-10-17 15:23:05 -0700266 mIsResponseSent = true;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800267 Bundle args = new Bundle();
268 args.putInt(StkAppService.OPCODE, StkAppService.OP_RESPONSE);
Wink Savillee68857d2014-10-17 15:23:05 -0700269 args.putInt(StkAppService.SLOT_ID, mSlotId);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800270 args.putInt(StkAppService.RES_ID, resId);
271 if (input != null) {
272 args.putString(StkAppService.INPUT, input);
273 }
274 args.putBoolean(StkAppService.HELP, help);
275 mContext.startService(new Intent(mContext, StkAppService.class)
276 .putExtras(args));
277 }
278
279 @Override
280 public boolean onCreateOptionsMenu(android.view.Menu menu) {
281 super.onCreateOptionsMenu(menu);
282 menu.add(android.view.Menu.NONE, StkApp.MENU_ID_END_SESSION, 1,
283 R.string.menu_end_session);
284 menu.add(0, StkApp.MENU_ID_HELP, 2, R.string.help);
285
286 return true;
287 }
288
289 @Override
290 public boolean onPrepareOptionsMenu(android.view.Menu menu) {
291 super.onPrepareOptionsMenu(menu);
292 menu.findItem(StkApp.MENU_ID_END_SESSION).setVisible(true);
293 menu.findItem(StkApp.MENU_ID_HELP).setVisible(mStkInput.helpAvailable);
294
295 return true;
296 }
297
298 @Override
299 public boolean onOptionsItemSelected(MenuItem item) {
Wink Savillee68857d2014-10-17 15:23:05 -0700300 if (!mAcceptUsersInput) {
301 CatLog.d(LOG_TAG, "mAcceptUsersInput:false");
302 return true;
303 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800304 switch (item.getItemId()) {
305 case StkApp.MENU_ID_END_SESSION:
Wink Savillee68857d2014-10-17 15:23:05 -0700306 mAcceptUsersInput = false;
307 cancelTimeOut();
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800308 sendResponse(StkAppService.RES_ID_END_SESSION);
309 finish();
310 return true;
311 case StkApp.MENU_ID_HELP:
Wink Savillee68857d2014-10-17 15:23:05 -0700312 mAcceptUsersInput = false;
313 cancelTimeOut();
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800314 sendResponse(StkAppService.RES_ID_INPUT, "", true);
315 finish();
316 return true;
317 }
318 return super.onOptionsItemSelected(item);
319 }
320
Wink Savillee68857d2014-10-17 15:23:05 -0700321 @Override
322 protected void onSaveInstanceState(Bundle outState) {
323 CatLog.d(LOG_TAG, "onSaveInstanceState: " + mSlotId);
324 outState.putBoolean("ACCEPT_USERS_INPUT", mAcceptUsersInput);
325 }
326
327 @Override
328 protected void onRestoreInstanceState(Bundle savedInstanceState) {
329 CatLog.d(LOG_TAG, "onRestoreInstanceState: " + mSlotId);
330 mAcceptUsersInput = savedInstanceState.getBoolean("ACCEPT_USERS_INPUT");
331 }
332
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800333 public void beforeTextChanged(CharSequence s, int start, int count,
334 int after) {
335 }
336
337 public void onTextChanged(CharSequence s, int start, int before, int count) {
338 // Reset timeout.
339 startTimeOut();
340 }
341
342 public void afterTextChanged(Editable s) {
343 }
344
345 private boolean verfiyTypedText() {
346 // If not enough input was typed in stay on the edit screen.
347 if (mTextIn.getText().length() < mStkInput.minLen) {
348 return false;
349 }
350
351 return true;
352 }
353
354 private void cancelTimeOut() {
355 mTimeoutHandler.removeMessages(MSG_ID_TIMEOUT);
356 }
357
358 private void startTimeOut() {
Abhishek Adappac7c3a462013-02-14 13:36:57 -0800359 int duration = StkApp.calculateDurationInMilis(mStkInput.duration);
360
361 if (duration <= 0) {
362 duration = StkApp.UI_TIMEOUT;
363 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800364 cancelTimeOut();
365 mTimeoutHandler.sendMessageDelayed(mTimeoutHandler
Abhishek Adappac7c3a462013-02-14 13:36:57 -0800366 .obtainMessage(MSG_ID_TIMEOUT), duration);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800367 }
368
369 private void configInputDisplay() {
370 TextView numOfCharsView = (TextView) findViewById(R.id.num_of_chars);
371 TextView inTypeView = (TextView) findViewById(R.id.input_type);
372
373 int inTypeId = R.string.alphabet;
374
375 // set the prompt.
Takeshi Shinoharac6589002013-05-27 11:01:06 +0900376 if (mStkInput.iconSelfExplanatory && mStkInput.icon != null) {
377 mPromptView.setVisibility(View.GONE);
378 } else {
379 mPromptView.setText(mStkInput.text);
380 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800381
Wink Saville79085fc2009-06-09 10:27:23 -0700382 // Set input type (alphabet/digit) info close to the InText form.
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800383 if (mStkInput.digitOnly) {
384 mTextIn.setKeyListener(StkDigitsKeyListener.getInstance());
385 inTypeId = R.string.digits;
386 }
387 inTypeView.setText(inTypeId);
388
Takanori Nakano48544352016-12-02 18:32:59 +0900389 TextView textView = (TextView) this.findViewById(R.id.title_text);
390 textView.setText(R.string.app_name);
391
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800392 if (mStkInput.icon != null) {
Takanori Nakano48544352016-12-02 18:32:59 +0900393 ImageView imageView = (ImageView) findViewById(R.id.title_icon);
394 imageView.setImageBitmap(mStkInput.icon);
395 imageView.setVisibility(View.VISIBLE);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800396 }
397
398 // Handle specific global and text attributes.
399 switch (mState) {
Wink Saville79085fc2009-06-09 10:27:23 -0700400 case STATE_TEXT:
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800401 int maxLen = mStkInput.maxLen;
402 int minLen = mStkInput.minLen;
403 mTextIn.setFilters(new InputFilter[] {new InputFilter.LengthFilter(
404 maxLen)});
Wink Saville79085fc2009-06-09 10:27:23 -0700405
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800406 // Set number of chars info.
407 String lengthLimit = String.valueOf(minLen);
408 if (maxLen != minLen) {
409 lengthLimit = minLen + " - " + maxLen;
410 }
411 numOfCharsView.setText(lengthLimit);
412
413 if (!mStkInput.echo) {
duho.roee36b6f2013-09-03 15:15:16 +0900414 mTextIn.setInputType(InputType.TYPE_CLASS_NUMBER
415 | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800416 }
417 // Set default text if present.
418 if (mStkInput.defaultText != null) {
419 mTextIn.setText(mStkInput.defaultText);
420 } else {
421 // make sure the text is cleared
422 mTextIn.setText("", BufferType.EDITABLE);
423 }
424
425 break;
426 case STATE_YES_NO:
427 // Set display mode - normal / yes-no layout
428 mYesNoLayout.setVisibility(View.VISIBLE);
429 mNormalLayout.setVisibility(View.GONE);
430 break;
431 }
432 }
433
434 private float getFontSizeFactor(FontSize size) {
Wink Saville79085fc2009-06-09 10:27:23 -0700435 final float[] fontSizes =
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800436 {NORMAL_FONT_FACTOR, LARGE_FONT_FACTOR, SMALL_FONT_FACTOR};
437
438 return fontSizes[size.ordinal()];
439 }
Wink Savillee68857d2014-10-17 15:23:05 -0700440
441 private void initFromIntent(Intent intent) {
442 // Get the calling intent type: text/key, and setup the
443 // display parameters.
444 CatLog.d(LOG_TAG, "initFromIntent - slot id: " + mSlotId);
445 if (intent != null) {
446 mStkInput = intent.getParcelableExtra("INPUT");
447 mSlotId = intent.getIntExtra(StkAppService.SLOT_ID, -1);
448 CatLog.d(LOG_TAG, "onCreate - slot id: " + mSlotId);
449 if (mStkInput == null) {
450 finish();
451 } else {
452 mState = mStkInput.yesNo ? STATE_YES_NO :
453 STATE_TEXT;
454 configInputDisplay();
455 }
456 } else {
457 finish();
458 }
459 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800460}