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