Home | History | Annotate | Download | only in stk
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * 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
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * 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 
     17 package com.android.stk;
     18 
     19 import android.app.Activity;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.graphics.drawable.BitmapDrawable;
     23 import android.os.Bundle;
     24 import android.os.Handler;
     25 import android.os.Message;
     26 import android.text.Editable;
     27 import android.text.InputFilter;
     28 import android.text.InputType;
     29 import android.text.TextWatcher;
     30 import android.text.method.PasswordTransformationMethod;
     31 import android.view.KeyEvent;
     32 import android.view.MenuItem;
     33 import android.view.View;
     34 import android.view.Window;
     35 import android.widget.Button;
     36 import android.widget.TextView;
     37 import android.widget.EditText;
     38 import android.widget.TextView.BufferType;
     39 
     40 import com.android.internal.telephony.cat.FontSize;
     41 import com.android.internal.telephony.cat.Input;
     42 
     43 /**
     44  * Display a request for a text input a long with a text edit form.
     45  */
     46 public 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;
     56     private Input mStkInput = null;
     57 
     58     // Constants
     59     private static final int STATE_TEXT = 1;
     60     private static final int STATE_YES_NO = 2;
     61 
     62     static final String YES_STR_RESPONSE = "YES";
     63     static final String NO_STR_RESPONSE = "NO";
     64 
     65     // Font size factor values.
     66     static final float NORMAL_FONT_FACTOR = 1;
     67     static final float LARGE_FONT_FACTOR = 2;
     68     static final float SMALL_FONT_FACTOR = (1 / 2);
     69 
     70     // message id for time out
     71     private static final int MSG_ID_TIMEOUT = 1;
     72 
     73     Handler mTimeoutHandler = new Handler() {
     74         @Override
     75         public void handleMessage(Message msg) {
     76             switch(msg.what) {
     77             case MSG_ID_TIMEOUT:
     78                 //mAcceptUsersInput = false;
     79                 sendResponse(StkAppService.RES_ID_TIMEOUT);
     80                 finish();
     81                 break;
     82             }
     83         }
     84     };
     85 
     86     // Click listener to handle buttons press..
     87     public void onClick(View v) {
     88         String input = null;
     89 
     90         switch (v.getId()) {
     91         case R.id.button_ok:
     92             // Check that text entered is valid .
     93             if (!verfiyTypedText()) {
     94                 return;
     95             }
     96             input = mTextIn.getText().toString();
     97             break;
     98         // Yes/No layout buttons.
     99         case R.id.button_yes:
    100             input = YES_STR_RESPONSE;
    101             break;
    102         case R.id.button_no:
    103             input = NO_STR_RESPONSE;
    104             break;
    105         }
    106 
    107         sendResponse(StkAppService.RES_ID_INPUT, input, false);
    108         finish();
    109     }
    110 
    111     @Override
    112     public void onCreate(Bundle icicle) {
    113         super.onCreate(icicle);
    114 
    115         // Set the layout for this activity.
    116         requestWindowFeature(Window.FEATURE_LEFT_ICON);
    117         setContentView(R.layout.stk_input);
    118 
    119         // Initialize members
    120         mTextIn = (EditText) this.findViewById(R.id.in_text);
    121         mPromptView = (TextView) this.findViewById(R.id.prompt);
    122 
    123         // Set buttons listeners.
    124         Button okButton = (Button) findViewById(R.id.button_ok);
    125         Button yesButton = (Button) findViewById(R.id.button_yes);
    126         Button noButton = (Button) findViewById(R.id.button_no);
    127 
    128         okButton.setOnClickListener(this);
    129         yesButton.setOnClickListener(this);
    130         noButton.setOnClickListener(this);
    131 
    132         mYesNoLayout = findViewById(R.id.yes_no_layout);
    133         mNormalLayout = findViewById(R.id.normal_layout);
    134 
    135         // Get the calling intent type: text/key, and setup the
    136         // display parameters.
    137         Intent intent = getIntent();
    138         if (intent != null) {
    139             mStkInput = intent.getParcelableExtra("INPUT");
    140             if (mStkInput == null) {
    141                 finish();
    142             } else {
    143                 mState = mStkInput.yesNo ? STATE_YES_NO : STATE_TEXT;
    144                 configInputDisplay();
    145             }
    146         } else {
    147             finish();
    148         }
    149         mContext = getBaseContext();
    150     }
    151 
    152     @Override
    153     protected void onPostCreate(Bundle savedInstanceState) {
    154         super.onPostCreate(savedInstanceState);
    155 
    156         mTextIn.addTextChangedListener(this);
    157     }
    158 
    159     @Override
    160     public void onResume() {
    161         super.onResume();
    162 
    163         startTimeOut();
    164     }
    165 
    166     @Override
    167     public void onPause() {
    168         super.onPause();
    169 
    170         cancelTimeOut();
    171     }
    172 
    173     @Override
    174     public boolean onKeyDown(int keyCode, KeyEvent event) {
    175         switch (keyCode) {
    176         case KeyEvent.KEYCODE_BACK:
    177             sendResponse(StkAppService.RES_ID_BACKWARD, null, false);
    178             finish();
    179             break;
    180         }
    181         return super.onKeyDown(keyCode, event);
    182     }
    183 
    184     private void sendResponse(int resId) {
    185         sendResponse(resId, null, false);
    186     }
    187 
    188     private void sendResponse(int resId, String input, boolean help) {
    189         Bundle args = new Bundle();
    190         args.putInt(StkAppService.OPCODE, StkAppService.OP_RESPONSE);
    191         args.putInt(StkAppService.RES_ID, resId);
    192         if (input != null) {
    193             args.putString(StkAppService.INPUT, input);
    194         }
    195         args.putBoolean(StkAppService.HELP, help);
    196         mContext.startService(new Intent(mContext, StkAppService.class)
    197                 .putExtras(args));
    198     }
    199 
    200     @Override
    201     public boolean onCreateOptionsMenu(android.view.Menu menu) {
    202         super.onCreateOptionsMenu(menu);
    203         menu.add(android.view.Menu.NONE, StkApp.MENU_ID_END_SESSION, 1,
    204                 R.string.menu_end_session);
    205         menu.add(0, StkApp.MENU_ID_HELP, 2, R.string.help);
    206 
    207         return true;
    208     }
    209 
    210     @Override
    211     public boolean onPrepareOptionsMenu(android.view.Menu menu) {
    212         super.onPrepareOptionsMenu(menu);
    213         menu.findItem(StkApp.MENU_ID_END_SESSION).setVisible(true);
    214         menu.findItem(StkApp.MENU_ID_HELP).setVisible(mStkInput.helpAvailable);
    215 
    216         return true;
    217     }
    218 
    219     @Override
    220     public boolean onOptionsItemSelected(MenuItem item) {
    221         switch (item.getItemId()) {
    222         case StkApp.MENU_ID_END_SESSION:
    223             sendResponse(StkAppService.RES_ID_END_SESSION);
    224             finish();
    225             return true;
    226         case StkApp.MENU_ID_HELP:
    227             sendResponse(StkAppService.RES_ID_INPUT, "", true);
    228             finish();
    229             return true;
    230         }
    231         return super.onOptionsItemSelected(item);
    232     }
    233 
    234     public void beforeTextChanged(CharSequence s, int start, int count,
    235             int after) {
    236     }
    237 
    238     public void onTextChanged(CharSequence s, int start, int before, int count) {
    239         // Reset timeout.
    240         startTimeOut();
    241     }
    242 
    243     public void afterTextChanged(Editable s) {
    244     }
    245 
    246     private boolean verfiyTypedText() {
    247         // If not enough input was typed in stay on the edit screen.
    248         if (mTextIn.getText().length() < mStkInput.minLen) {
    249             return false;
    250         }
    251 
    252         return true;
    253     }
    254 
    255     private void cancelTimeOut() {
    256         mTimeoutHandler.removeMessages(MSG_ID_TIMEOUT);
    257     }
    258 
    259     private void startTimeOut() {
    260         int duration = StkApp.calculateDurationInMilis(mStkInput.duration);
    261 
    262         if (duration <= 0) {
    263             duration = StkApp.UI_TIMEOUT;
    264         }
    265         cancelTimeOut();
    266         mTimeoutHandler.sendMessageDelayed(mTimeoutHandler
    267                 .obtainMessage(MSG_ID_TIMEOUT), duration);
    268     }
    269 
    270     private void configInputDisplay() {
    271         TextView numOfCharsView = (TextView) findViewById(R.id.num_of_chars);
    272         TextView inTypeView = (TextView) findViewById(R.id.input_type);
    273 
    274         int inTypeId = R.string.alphabet;
    275 
    276         // set the prompt.
    277         mPromptView.setText(mStkInput.text);
    278 
    279         // Set input type (alphabet/digit) info close to the InText form.
    280         if (mStkInput.digitOnly) {
    281             mTextIn.setKeyListener(StkDigitsKeyListener.getInstance());
    282             inTypeId = R.string.digits;
    283         }
    284         inTypeView.setText(inTypeId);
    285 
    286         if (mStkInput.icon != null) {
    287             setFeatureDrawable(Window.FEATURE_LEFT_ICON, new BitmapDrawable(
    288                     mStkInput.icon));
    289         }
    290 
    291         // Handle specific global and text attributes.
    292         switch (mState) {
    293         case STATE_TEXT:
    294             int maxLen = mStkInput.maxLen;
    295             int minLen = mStkInput.minLen;
    296             mTextIn.setFilters(new InputFilter[] {new InputFilter.LengthFilter(
    297                     maxLen)});
    298 
    299             // Set number of chars info.
    300             String lengthLimit = String.valueOf(minLen);
    301             if (maxLen != minLen) {
    302                 lengthLimit = minLen + " - " + maxLen;
    303             }
    304             numOfCharsView.setText(lengthLimit);
    305 
    306             if (!mStkInput.echo) {
    307                 mTextIn.setInputType(InputType.TYPE_CLASS_NUMBER
    308                                      | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
    309             }
    310             // Set default text if present.
    311             if (mStkInput.defaultText != null) {
    312                 mTextIn.setText(mStkInput.defaultText);
    313             } else {
    314                 // make sure the text is cleared
    315                 mTextIn.setText("", BufferType.EDITABLE);
    316             }
    317 
    318             break;
    319         case STATE_YES_NO:
    320             // Set display mode - normal / yes-no layout
    321             mYesNoLayout.setVisibility(View.VISIBLE);
    322             mNormalLayout.setVisibility(View.GONE);
    323             break;
    324         }
    325     }
    326 
    327     private float getFontSizeFactor(FontSize size) {
    328         final float[] fontSizes =
    329             {NORMAL_FONT_FACTOR, LARGE_FONT_FACTOR, SMALL_FONT_FACTOR};
    330 
    331         return fontSizes[size.ordinal()];
    332     }
    333 }
    334