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