StkMenuActivity.java revision 64ec38ec889df7bf757861b02e918c05464cc545
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.view.ContextMenu;
26import android.view.ContextMenu.ContextMenuInfo;
27import android.view.KeyEvent;
28import android.view.MenuItem;
29import android.view.View;
30import android.view.Window;
31import android.widget.AdapterView;
32import android.widget.ImageView;
33import android.widget.ListView;
34import android.widget.ProgressBar;
35import android.widget.TextView;
36
37import com.android.internal.telephony.cat.Item;
38import com.android.internal.telephony.cat.Menu;
39import 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 */
47public 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