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");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of 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.ListActivity;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.os.Bundle;
     23 import android.os.Handler;
     24 import android.os.Message;
     25 import android.view.ContextMenu;
     26 import android.view.ContextMenu.ContextMenuInfo;
     27 import android.view.KeyEvent;
     28 import android.view.MenuItem;
     29 import android.view.View;
     30 import android.view.Window;
     31 import android.widget.AdapterView;
     32 import android.widget.ImageView;
     33 import android.widget.ListView;
     34 import android.widget.ProgressBar;
     35 import android.widget.TextView;
     36 
     37 import com.android.internal.telephony.cat.Item;
     38 import com.android.internal.telephony.cat.Menu;
     39 import com.android.internal.telephony.cat.CatLog;
     40 
     41 /**
     42  * ListActivity used for displaying STK menus. These can be SET UP MENU and
     43  * SELECT ITEM menus. This activity is started multiple times with different
     44  * menu content.
     45  *
     46  */
     47 public class StkMenuActivity extends ListActivity implements View.OnCreateContextMenuListener {
     48     private Context mContext;
     49     private Menu mStkMenu = null;
     50     private int mState = STATE_MAIN;
     51     private boolean mAcceptUsersInput = true;
     52 
     53     private TextView mTitleTextView = null;
     54     private ImageView mTitleIconView = null;
     55     private ProgressBar mProgressView = null;
     56 
     57     StkAppService appService = StkAppService.getInstance();
     58 
     59     // Internal state values
     60     static final int STATE_MAIN = 1;
     61     static final int STATE_SECONDARY = 2;
     62 
     63     // message id for time out
     64     private static final int MSG_ID_TIMEOUT = 1;
     65     private static final int CONTEXT_MENU_HELP = 0;
     66 
     67     Handler mTimeoutHandler = new Handler() {
     68         @Override
     69         public void handleMessage(Message msg) {
     70             switch(msg.what) {
     71             case MSG_ID_TIMEOUT:
     72                 mAcceptUsersInput = false;
     73                 sendResponse(StkAppService.RES_ID_TIMEOUT);
     74                 break;
     75             }
     76         }
     77     };
     78 
     79     @Override
     80     public void onCreate(Bundle icicle) {
     81         super.onCreate(icicle);
     82 
     83         CatLog.d(this, "onCreate");
     84         // Set the layout for this activity.
     85         setContentView(R.layout.stk_menu_list);
     86 
     87         mTitleTextView = (TextView) findViewById(R.id.title_text);
     88         mTitleIconView = (ImageView) findViewById(R.id.title_icon);
     89         mProgressView = (ProgressBar) findViewById(R.id.progress_bar);
     90         mContext = getBaseContext();
     91 
     92         initFromIntent(getIntent());
     93         mAcceptUsersInput = true;
     94 
     95         getListView().setOnCreateContextMenuListener(this);
     96     }
     97 
     98     @Override
     99     protected void onNewIntent(Intent intent) {
    100         super.onNewIntent(intent);
    101 
    102         CatLog.d(this, "onNewIntent");
    103         initFromIntent(intent);
    104         mAcceptUsersInput = true;
    105     }
    106 
    107     @Override
    108     protected void onListItemClick(ListView l, View v, int position, long id) {
    109         super.onListItemClick(l, v, position, id);
    110 
    111         if (!mAcceptUsersInput) {
    112             return;
    113         }
    114 
    115         Item item = getSelectedItem(position);
    116         if (item == null) {
    117             return;
    118         }
    119         sendResponse(StkAppService.RES_ID_MENU_SELECTION, item.id, false);
    120         mAcceptUsersInput = false;
    121         mProgressView.setVisibility(View.VISIBLE);
    122         mProgressView.setIndeterminate(true);
    123     }
    124 
    125     @Override
    126     public boolean onKeyDown(int keyCode, KeyEvent event) {
    127 
    128         if (!mAcceptUsersInput) {
    129             return true;
    130         }
    131 
    132         switch (keyCode) {
    133         case KeyEvent.KEYCODE_BACK:
    134             switch (mState) {
    135             case STATE_SECONDARY:
    136                 cancelTimeOut();
    137                 mAcceptUsersInput = false;
    138                 sendResponse(StkAppService.RES_ID_BACKWARD);
    139                 return true;
    140             case STATE_MAIN:
    141                 break;
    142             }
    143             break;
    144         }
    145         return super.onKeyDown(keyCode, event);
    146     }
    147 
    148     @Override
    149     public void onResume() {
    150         super.onResume();
    151 
    152         appService.indicateMenuVisibility(true);
    153         mStkMenu = appService.getMenu();
    154         if (mStkMenu == null) {
    155             finish();
    156             return;
    157         }
    158         displayMenu();
    159         startTimeOut();
    160         // whenever this activity is resumed after a sub activity was invoked
    161         // (Browser, In call screen) switch back to main state and enable
    162         // user's input;
    163         if (!mAcceptUsersInput) {
    164             mState = STATE_MAIN;
    165             mAcceptUsersInput = true;
    166         }
    167         invalidateOptionsMenu();
    168         // make sure the progress bar is not shown.
    169         mProgressView.setIndeterminate(false);
    170         mProgressView.setVisibility(View.GONE);
    171     }
    172 
    173     @Override
    174     public void onPause() {
    175         super.onPause();
    176 
    177         appService.indicateMenuVisibility(false);
    178         cancelTimeOut();
    179     }
    180 
    181     @Override
    182     public void onDestroy() {
    183         getListView().setOnCreateContextMenuListener(null);
    184         super.onDestroy();
    185 
    186         CatLog.d(this, "onDestroy");
    187     }
    188 
    189     @Override
    190     public boolean onCreateOptionsMenu(android.view.Menu menu) {
    191         super.onCreateOptionsMenu(menu);
    192         menu.add(0, StkApp.MENU_ID_END_SESSION, 1, R.string.menu_end_session);
    193         menu.add(0, StkApp.MENU_ID_HELP, 2, R.string.help);
    194         return true;
    195     }
    196 
    197     @Override
    198     public boolean onPrepareOptionsMenu(android.view.Menu menu) {
    199         super.onPrepareOptionsMenu(menu);
    200         boolean helpVisible = false;
    201         boolean mainVisible = false;
    202 
    203         if (mState == STATE_SECONDARY) {
    204             mainVisible = true;
    205         }
    206         if (mStkMenu != null) {
    207             helpVisible = mStkMenu.helpAvailable;
    208         }
    209 
    210         menu.findItem(StkApp.MENU_ID_END_SESSION).setVisible(mainVisible);
    211         menu.findItem(StkApp.MENU_ID_HELP).setVisible(helpVisible);
    212 
    213         return true;
    214     }
    215 
    216     @Override
    217     public boolean onOptionsItemSelected(MenuItem item) {
    218         if (!mAcceptUsersInput) {
    219             return true;
    220         }
    221         switch (item.getItemId()) {
    222         case StkApp.MENU_ID_END_SESSION:
    223             cancelTimeOut();
    224             mAcceptUsersInput = false;
    225             // send session end response.
    226             sendResponse(StkAppService.RES_ID_END_SESSION);
    227             return true;
    228         case StkApp.MENU_ID_HELP:
    229             cancelTimeOut();
    230             mAcceptUsersInput = false;
    231             int position = getSelectedItemPosition();
    232             Item stkItem = getSelectedItem(position);
    233             if (stkItem == null) {
    234                 break;
    235             }
    236             // send help needed response.
    237             sendResponse(StkAppService.RES_ID_MENU_SELECTION, stkItem.id, true);
    238             return true;
    239         }
    240         return super.onOptionsItemSelected(item);
    241     }
    242 
    243     @Override
    244     public void onCreateContextMenu(ContextMenu menu, View v,
    245             ContextMenuInfo menuInfo) {
    246         CatLog.d(this, "onCreateContextMenu");
    247         boolean helpVisible = false;
    248         if (mStkMenu != null) {
    249             helpVisible = mStkMenu.helpAvailable;
    250         }
    251         if (helpVisible) {
    252             CatLog.d(this, "add menu");
    253             menu.add(0, CONTEXT_MENU_HELP, 0, R.string.help);
    254         }
    255     }
    256 
    257     @Override
    258     public boolean onContextItemSelected(MenuItem item) {
    259         AdapterView.AdapterContextMenuInfo info;
    260         try {
    261             info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
    262         } catch (ClassCastException e) {
    263             return false;
    264         }
    265         switch (item.getItemId()) {
    266             case CONTEXT_MENU_HELP:
    267                 cancelTimeOut();
    268                 mAcceptUsersInput = false;
    269                 int position = info.position;
    270                 CatLog.d(this, "Position:" + position);
    271                 Item stkItem = getSelectedItem(position);
    272                 if (stkItem != null) {
    273                     CatLog.d(this, "item id:" + stkItem.id);
    274                     sendResponse(StkAppService.RES_ID_MENU_SELECTION, stkItem.id, true);
    275                 }
    276                 return true;
    277 
    278             default:
    279                 return super.onContextItemSelected(item);
    280         }
    281     }
    282 
    283     @Override
    284     protected void onSaveInstanceState(Bundle outState) {
    285         outState.putInt("STATE", mState);
    286         outState.putParcelable("MENU", mStkMenu);
    287     }
    288 
    289     @Override
    290     protected void onRestoreInstanceState(Bundle savedInstanceState) {
    291         mState = savedInstanceState.getInt("STATE");
    292         mStkMenu = savedInstanceState.getParcelable("MENU");
    293     }
    294 
    295     private void cancelTimeOut() {
    296         mTimeoutHandler.removeMessages(MSG_ID_TIMEOUT);
    297     }
    298 
    299     private void startTimeOut() {
    300         if (mState == STATE_SECONDARY) {
    301             // Reset timeout.
    302             cancelTimeOut();
    303             mTimeoutHandler.sendMessageDelayed(mTimeoutHandler
    304                     .obtainMessage(MSG_ID_TIMEOUT), StkApp.UI_TIMEOUT);
    305         }
    306     }
    307 
    308     // Bind list adapter to the items list.
    309     private void displayMenu() {
    310 
    311         if (mStkMenu != null) {
    312             String title = mStkMenu.title == null ? getString(R.string.app_name) : mStkMenu.title;
    313             // Display title & title icon
    314             if (mStkMenu.titleIcon != null) {
    315                 mTitleIconView.setImageBitmap(mStkMenu.titleIcon);
    316                 mTitleIconView.setVisibility(View.VISIBLE);
    317                 mTitleTextView.setVisibility(View.INVISIBLE);
    318                 if (!mStkMenu.titleIconSelfExplanatory) {
    319                     mTitleTextView.setText(title);
    320                     mTitleTextView.setVisibility(View.VISIBLE);
    321                 }
    322             } else {
    323                 mTitleIconView.setVisibility(View.GONE);
    324                 mTitleTextView.setVisibility(View.VISIBLE);
    325                 mTitleTextView.setText(title);
    326             }
    327             // create an array adapter for the menu list
    328             StkMenuAdapter adapter = new StkMenuAdapter(this,
    329                     mStkMenu.items, mStkMenu.itemsIconSelfExplanatory);
    330             // Bind menu list to the new adapter.
    331             setListAdapter(adapter);
    332             // Set default item
    333             setSelection(mStkMenu.defaultItem);
    334         }
    335     }
    336 
    337     private void initFromIntent(Intent intent) {
    338 
    339         if (intent != null) {
    340             mState = intent.getIntExtra("STATE", STATE_MAIN);
    341         } else {
    342             finish();
    343         }
    344     }
    345 
    346     private Item getSelectedItem(int position) {
    347         Item item = null;
    348         if (mStkMenu != null) {
    349             try {
    350                 item = mStkMenu.items.get(position);
    351             } catch (IndexOutOfBoundsException e) {
    352                 if (StkApp.DBG) {
    353                     CatLog.d(this, "Invalid menu");
    354                 }
    355             } catch (NullPointerException e) {
    356                 if (StkApp.DBG) {
    357                     CatLog.d(this, "Invalid menu");
    358                 }
    359             }
    360         }
    361         return item;
    362     }
    363 
    364     private void sendResponse(int resId) {
    365         sendResponse(resId, 0, false);
    366     }
    367 
    368     private void sendResponse(int resId, int itemId, boolean help) {
    369         Bundle args = new Bundle();
    370         args.putInt(StkAppService.OPCODE, StkAppService.OP_RESPONSE);
    371         args.putInt(StkAppService.RES_ID, resId);
    372         args.putInt(StkAppService.MENU_SELECTION, itemId);
    373         args.putBoolean(StkAppService.HELP, help);
    374         mContext.startService(new Intent(mContext, StkAppService.class)
    375                 .putExtras(args));
    376     }
    377 }
    378