blob: 39c574d67dcffbd860a57a6ba5feb1bcbcaa3268 [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
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800137 // Set the layout for this activity.
Wink Savillee68857d2014-10-17 15:23:05 -0700138 requestWindowFeature(Window.FEATURE_LEFT_ICON);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800139 setContentView(R.layout.stk_input);
140
141 // Initialize members
142 mTextIn = (EditText) this.findViewById(R.id.in_text);
143 mPromptView = (TextView) this.findViewById(R.id.prompt);
Wink Savillee68857d2014-10-17 15:23:05 -0700144 mInstance = this;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800145 // Set buttons listeners.
Wink Saville79085fc2009-06-09 10:27:23 -0700146 Button okButton = (Button) findViewById(R.id.button_ok);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800147 Button yesButton = (Button) findViewById(R.id.button_yes);
148 Button noButton = (Button) findViewById(R.id.button_no);
149
150 okButton.setOnClickListener(this);
151 yesButton.setOnClickListener(this);
152 noButton.setOnClickListener(this);
153
154 mYesNoLayout = findViewById(R.id.yes_no_layout);
155 mNormalLayout = findViewById(R.id.normal_layout);
Wink Savillee68857d2014-10-17 15:23:05 -0700156 initFromIntent(getIntent());
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800157 mContext = getBaseContext();
Wink Savillee68857d2014-10-17 15:23:05 -0700158 mAcceptUsersInput = true;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800159 }
160
161 @Override
162 protected void onPostCreate(Bundle savedInstanceState) {
163 super.onPostCreate(savedInstanceState);
164
165 mTextIn.addTextChangedListener(this);
166 }
167
168 @Override
169 public void onResume() {
170 super.onResume();
Wink Savillee68857d2014-10-17 15:23:05 -0700171 CatLog.d(LOG_TAG, "onResume - mIsResponseSent[" + mIsResponseSent +
172 "], slot id: " + mSlotId);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800173 startTimeOut();
Wink Savillee68857d2014-10-17 15:23:05 -0700174 appService.getStkContext(mSlotId).setPendingActivityInstance(null);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800175 }
176
177 @Override
178 public void onPause() {
179 super.onPause();
Wink Savillee68857d2014-10-17 15:23:05 -0700180 CatLog.d(LOG_TAG, "onPause - mIsResponseSent[" + mIsResponseSent + "]");
181 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800182
Wink Savillee68857d2014-10-17 15:23:05 -0700183 @Override
184 public void onStop() {
185 super.onStop();
186 CatLog.d(LOG_TAG, "onStop - mIsResponseSent[" + mIsResponseSent + "]");
187 if (mIsResponseSent) {
188 cancelTimeOut();
189 finish();
190 } else {
191 appService.getStkContext(mSlotId).setPendingActivityInstance(this);
192 }
193 }
194
195 @Override
196 public void onDestroy() {
197 super.onDestroy();
198 CatLog.d(LOG_TAG, "onDestroy - before Send End Session mIsResponseSent[" +
199 mIsResponseSent + " , " + mSlotId + "]");
200 //If the input activity is finished by stkappservice
201 //when receiving OP_LAUNCH_APP from the other SIM, we can not send TR here
202 //, since the input cmd is waiting user to process.
203 if (!mIsResponseSent && !appService.isInputPending(mSlotId)) {
204 CatLog.d(LOG_TAG, "handleDestroy - Send End Session");
205 sendResponse(StkAppService.RES_ID_END_SESSION);
206 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800207 cancelTimeOut();
208 }
209
210 @Override
211 public boolean onKeyDown(int keyCode, KeyEvent event) {
Wink Savillee68857d2014-10-17 15:23:05 -0700212 if (!mAcceptUsersInput) {
213 CatLog.d(LOG_TAG, "mAcceptUsersInput:false");
214 return true;
215 }
216
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800217 switch (keyCode) {
218 case KeyEvent.KEYCODE_BACK:
Wink Savillee68857d2014-10-17 15:23:05 -0700219 CatLog.d(LOG_TAG, "onKeyDown - KEYCODE_BACK");
220 mAcceptUsersInput = false;
Preeti Ahuja03be6672012-08-30 19:21:25 +0530221 cancelTimeOut();
Wink Savillee68857d2014-10-17 15:23:05 -0700222 appService.getStkContext(mSlotId).setPendingActivityInstance(this);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800223 sendResponse(StkAppService.RES_ID_BACKWARD, null, false);
Wink Savillee68857d2014-10-17 15:23:05 -0700224 return true;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800225 }
226 return super.onKeyDown(keyCode, event);
227 }
228
Wink Savillee68857d2014-10-17 15:23:05 -0700229 void sendResponse(int resId) {
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800230 sendResponse(resId, null, false);
231 }
232
Wink Savillee68857d2014-10-17 15:23:05 -0700233 void sendResponse(int resId, String input, boolean help) {
234 if (mSlotId == -1) {
235 CatLog.d(LOG_TAG, "slot id is invalid");
236 return;
237 }
238
239 if (StkAppService.getInstance() == null) {
240 CatLog.d(LOG_TAG, "StkAppService is null, Ignore response: id is " + resId);
241 return;
242 }
243
Cuihtlauac ALVARADObde7f032015-05-29 16:25:12 +0200244 CatLog.d(LOG_TAG, "sendResponse resID[" + resId + "] input[*****] help["
245 + help + "]");
Wink Savillee68857d2014-10-17 15:23:05 -0700246 mIsResponseSent = true;
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800247 Bundle args = new Bundle();
248 args.putInt(StkAppService.OPCODE, StkAppService.OP_RESPONSE);
Wink Savillee68857d2014-10-17 15:23:05 -0700249 args.putInt(StkAppService.SLOT_ID, mSlotId);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800250 args.putInt(StkAppService.RES_ID, resId);
251 if (input != null) {
252 args.putString(StkAppService.INPUT, input);
253 }
254 args.putBoolean(StkAppService.HELP, help);
255 mContext.startService(new Intent(mContext, StkAppService.class)
256 .putExtras(args));
257 }
258
259 @Override
260 public boolean onCreateOptionsMenu(android.view.Menu menu) {
261 super.onCreateOptionsMenu(menu);
262 menu.add(android.view.Menu.NONE, StkApp.MENU_ID_END_SESSION, 1,
263 R.string.menu_end_session);
264 menu.add(0, StkApp.MENU_ID_HELP, 2, R.string.help);
265
266 return true;
267 }
268
269 @Override
270 public boolean onPrepareOptionsMenu(android.view.Menu menu) {
271 super.onPrepareOptionsMenu(menu);
272 menu.findItem(StkApp.MENU_ID_END_SESSION).setVisible(true);
273 menu.findItem(StkApp.MENU_ID_HELP).setVisible(mStkInput.helpAvailable);
274
275 return true;
276 }
277
278 @Override
279 public boolean onOptionsItemSelected(MenuItem item) {
Wink Savillee68857d2014-10-17 15:23:05 -0700280 if (!mAcceptUsersInput) {
281 CatLog.d(LOG_TAG, "mAcceptUsersInput:false");
282 return true;
283 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800284 switch (item.getItemId()) {
285 case StkApp.MENU_ID_END_SESSION:
Wink Savillee68857d2014-10-17 15:23:05 -0700286 mAcceptUsersInput = false;
287 cancelTimeOut();
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800288 sendResponse(StkAppService.RES_ID_END_SESSION);
289 finish();
290 return true;
291 case StkApp.MENU_ID_HELP:
Wink Savillee68857d2014-10-17 15:23:05 -0700292 mAcceptUsersInput = false;
293 cancelTimeOut();
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800294 sendResponse(StkAppService.RES_ID_INPUT, "", true);
295 finish();
296 return true;
297 }
298 return super.onOptionsItemSelected(item);
299 }
300
Wink Savillee68857d2014-10-17 15:23:05 -0700301 @Override
302 protected void onSaveInstanceState(Bundle outState) {
303 CatLog.d(LOG_TAG, "onSaveInstanceState: " + mSlotId);
304 outState.putBoolean("ACCEPT_USERS_INPUT", mAcceptUsersInput);
305 }
306
307 @Override
308 protected void onRestoreInstanceState(Bundle savedInstanceState) {
309 CatLog.d(LOG_TAG, "onRestoreInstanceState: " + mSlotId);
310 mAcceptUsersInput = savedInstanceState.getBoolean("ACCEPT_USERS_INPUT");
311 }
312
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800313 public void beforeTextChanged(CharSequence s, int start, int count,
314 int after) {
315 }
316
317 public void onTextChanged(CharSequence s, int start, int before, int count) {
318 // Reset timeout.
319 startTimeOut();
320 }
321
322 public void afterTextChanged(Editable s) {
323 }
324
325 private boolean verfiyTypedText() {
326 // If not enough input was typed in stay on the edit screen.
327 if (mTextIn.getText().length() < mStkInput.minLen) {
328 return false;
329 }
330
331 return true;
332 }
333
334 private void cancelTimeOut() {
335 mTimeoutHandler.removeMessages(MSG_ID_TIMEOUT);
336 }
337
338 private void startTimeOut() {
Abhishek Adappac7c3a462013-02-14 13:36:57 -0800339 int duration = StkApp.calculateDurationInMilis(mStkInput.duration);
340
341 if (duration <= 0) {
342 duration = StkApp.UI_TIMEOUT;
343 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800344 cancelTimeOut();
345 mTimeoutHandler.sendMessageDelayed(mTimeoutHandler
Abhishek Adappac7c3a462013-02-14 13:36:57 -0800346 .obtainMessage(MSG_ID_TIMEOUT), duration);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800347 }
348
349 private void configInputDisplay() {
350 TextView numOfCharsView = (TextView) findViewById(R.id.num_of_chars);
351 TextView inTypeView = (TextView) findViewById(R.id.input_type);
352
353 int inTypeId = R.string.alphabet;
354
355 // set the prompt.
356 mPromptView.setText(mStkInput.text);
357
Wink Saville79085fc2009-06-09 10:27:23 -0700358 // Set input type (alphabet/digit) info close to the InText form.
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800359 if (mStkInput.digitOnly) {
360 mTextIn.setKeyListener(StkDigitsKeyListener.getInstance());
361 inTypeId = R.string.digits;
362 }
363 inTypeView.setText(inTypeId);
364
365 if (mStkInput.icon != null) {
366 setFeatureDrawable(Window.FEATURE_LEFT_ICON, new BitmapDrawable(
367 mStkInput.icon));
368 }
369
370 // Handle specific global and text attributes.
371 switch (mState) {
Wink Saville79085fc2009-06-09 10:27:23 -0700372 case STATE_TEXT:
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800373 int maxLen = mStkInput.maxLen;
374 int minLen = mStkInput.minLen;
375 mTextIn.setFilters(new InputFilter[] {new InputFilter.LengthFilter(
376 maxLen)});
Wink Saville79085fc2009-06-09 10:27:23 -0700377
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800378 // Set number of chars info.
379 String lengthLimit = String.valueOf(minLen);
380 if (maxLen != minLen) {
381 lengthLimit = minLen + " - " + maxLen;
382 }
383 numOfCharsView.setText(lengthLimit);
384
385 if (!mStkInput.echo) {
duho.roee36b6f2013-09-03 15:15:16 +0900386 mTextIn.setInputType(InputType.TYPE_CLASS_NUMBER
387 | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800388 }
389 // Set default text if present.
390 if (mStkInput.defaultText != null) {
391 mTextIn.setText(mStkInput.defaultText);
392 } else {
393 // make sure the text is cleared
394 mTextIn.setText("", BufferType.EDITABLE);
395 }
396
397 break;
398 case STATE_YES_NO:
399 // Set display mode - normal / yes-no layout
400 mYesNoLayout.setVisibility(View.VISIBLE);
401 mNormalLayout.setVisibility(View.GONE);
402 break;
403 }
404 }
405
406 private float getFontSizeFactor(FontSize size) {
Wink Saville79085fc2009-06-09 10:27:23 -0700407 final float[] fontSizes =
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800408 {NORMAL_FONT_FACTOR, LARGE_FONT_FACTOR, SMALL_FONT_FACTOR};
409
410 return fontSizes[size.ordinal()];
411 }
Wink Savillee68857d2014-10-17 15:23:05 -0700412
413 private void initFromIntent(Intent intent) {
414 // Get the calling intent type: text/key, and setup the
415 // display parameters.
416 CatLog.d(LOG_TAG, "initFromIntent - slot id: " + mSlotId);
417 if (intent != null) {
418 mStkInput = intent.getParcelableExtra("INPUT");
419 mSlotId = intent.getIntExtra(StkAppService.SLOT_ID, -1);
420 CatLog.d(LOG_TAG, "onCreate - slot id: " + mSlotId);
421 if (mStkInput == null) {
422 finish();
423 } else {
424 mState = mStkInput.yesNo ? STATE_YES_NO :
425 STATE_TEXT;
426 configInputDisplay();
427 }
428 } else {
429 finish();
430 }
431 }
The Android Open Source Project9d9730a2009-03-03 19:32:37 -0800432}