The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 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 | |
Takanori Nakano | 4854435 | 2016-12-02 18:32:59 +0900 | [diff] [blame] | 19 | import android.app.ActionBar; |
Yoshiaki Naka | 3133534 | 2018-03-19 16:24:12 +0900 | [diff] [blame] | 20 | import android.app.AlarmManager; |
| 21 | import android.app.ListActivity; |
Takanori Nakano | 3776e2c | 2016-10-14 16:54:28 +0900 | [diff] [blame] | 22 | import android.content.BroadcastReceiver; |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 23 | import android.content.Context; |
| 24 | import android.content.Intent; |
Takanori Nakano | 3776e2c | 2016-10-14 16:54:28 +0900 | [diff] [blame] | 25 | import android.content.IntentFilter; |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 26 | import android.os.Bundle; |
Yoshiaki Naka | 3133534 | 2018-03-19 16:24:12 +0900 | [diff] [blame] | 27 | import android.os.SystemClock; |
pkanwar | ae3a1c8 | 2017-04-13 10:24:48 -0700 | [diff] [blame] | 28 | import android.telephony.SubscriptionManager; |
Guillaume Lucas | 82d3e79 | 2012-08-03 17:56:34 +0200 | [diff] [blame] | 29 | import android.view.ContextMenu; |
| 30 | import android.view.ContextMenu.ContextMenuInfo; |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 31 | import android.view.KeyEvent; |
| 32 | import android.view.MenuItem; |
| 33 | import android.view.View; |
Guillaume Lucas | 82d3e79 | 2012-08-03 17:56:34 +0200 | [diff] [blame] | 34 | import android.widget.AdapterView; |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 35 | import android.widget.ImageView; |
| 36 | import android.widget.ListView; |
| 37 | import android.widget.ProgressBar; |
| 38 | import android.widget.TextView; |
| 39 | |
Yoshiaki Naka | a89c934 | 2019-02-21 17:08:13 +0900 | [diff] [blame] | 40 | import androidx.localbroadcastmanager.content.LocalBroadcastManager; |
| 41 | |
Yoshiaki Naka | 3133534 | 2018-03-19 16:24:12 +0900 | [diff] [blame] | 42 | import com.android.internal.telephony.cat.CatLog; |
Alex Yakavenka | d41f1d9 | 2010-07-12 14:13:13 -0700 | [diff] [blame] | 43 | import com.android.internal.telephony.cat.Item; |
| 44 | import com.android.internal.telephony.cat.Menu; |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 45 | |
| 46 | /** |
Wink Saville | 79085fc | 2009-06-09 10:27:23 -0700 | [diff] [blame] | 47 | * ListActivity used for displaying STK menus. These can be SET UP MENU and |
| 48 | * SELECT ITEM menus. This activity is started multiple times with different |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 49 | * menu content. |
| 50 | * |
| 51 | */ |
Guillaume Lucas | 82d3e79 | 2012-08-03 17:56:34 +0200 | [diff] [blame] | 52 | public class StkMenuActivity extends ListActivity implements View.OnCreateContextMenuListener { |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 53 | private Menu mStkMenu = null; |
| 54 | private int mState = STATE_MAIN; |
| 55 | private boolean mAcceptUsersInput = true; |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 56 | private int mSlotId = -1; |
| 57 | private boolean mIsResponseSent = false; |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 58 | |
| 59 | private TextView mTitleTextView = null; |
| 60 | private ImageView mTitleIconView = null; |
| 61 | private ProgressBar mProgressView = null; |
Yoshiaki Naka | 3a980db | 2019-10-30 17:11:33 +0900 | [diff] [blame] | 62 | |
| 63 | private static final String LOG_TAG = |
| 64 | new Object(){}.getClass().getEnclosingClass().getSimpleName(); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 65 | |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 66 | private StkAppService appService = StkAppService.getInstance(); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 67 | |
Takanori Nakano | 6c2d468 | 2017-10-19 20:36:50 +0900 | [diff] [blame] | 68 | // Keys for saving the state of the dialog in the bundle |
| 69 | private static final String STATE_KEY = "state"; |
Takanori Nakano | 6c2d468 | 2017-10-19 20:36:50 +0900 | [diff] [blame] | 70 | private static final String ACCEPT_USERS_INPUT_KEY = "accept_users_input"; |
| 71 | private static final String RESPONSE_SENT_KEY = "response_sent"; |
Yoshiaki Naka | 3133534 | 2018-03-19 16:24:12 +0900 | [diff] [blame] | 72 | private static final String ALARM_TIME_KEY = "alarm_time"; |
| 73 | |
| 74 | private static final String SELECT_ALARM_TAG = LOG_TAG; |
| 75 | private static final long NO_SELECT_ALARM = -1; |
| 76 | private long mAlarmTime = NO_SELECT_ALARM; |
Takanori Nakano | 6c2d468 | 2017-10-19 20:36:50 +0900 | [diff] [blame] | 77 | |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 78 | // Internal state values |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 79 | static final int STATE_INIT = 0; |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 80 | static final int STATE_MAIN = 1; |
| 81 | static final int STATE_SECONDARY = 2; |
| 82 | |
Guillaume Lucas | 82d3e79 | 2012-08-03 17:56:34 +0200 | [diff] [blame] | 83 | private static final int CONTEXT_MENU_HELP = 0; |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 84 | |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 85 | @Override |
Takanori Nakano | 6c2d468 | 2017-10-19 20:36:50 +0900 | [diff] [blame] | 86 | public void onCreate(Bundle savedInstanceState) { |
| 87 | super.onCreate(savedInstanceState); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 88 | |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 89 | CatLog.d(LOG_TAG, "onCreate"); |
Takanori Nakano | 4854435 | 2016-12-02 18:32:59 +0900 | [diff] [blame] | 90 | |
| 91 | ActionBar actionBar = getActionBar(); |
| 92 | actionBar.setCustomView(R.layout.stk_title); |
| 93 | actionBar.setDisplayShowCustomEnabled(true); |
| 94 | |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 95 | // Set the layout for this activity. |
| 96 | setContentView(R.layout.stk_menu_list); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 97 | mTitleTextView = (TextView) findViewById(R.id.title_text); |
| 98 | mTitleIconView = (ImageView) findViewById(R.id.title_icon); |
| 99 | mProgressView = (ProgressBar) findViewById(R.id.progress_bar); |
Guillaume Lucas | 82d3e79 | 2012-08-03 17:56:34 +0200 | [diff] [blame] | 100 | getListView().setOnCreateContextMenuListener(this); |
Ryuto Sawada | ba9b86b | 2016-10-03 14:03:16 +0900 | [diff] [blame] | 101 | |
| 102 | // appService can be null if this activity is automatically recreated by the system |
| 103 | // with the saved instance state right after the phone process is killed. |
| 104 | if (appService == null) { |
| 105 | CatLog.d(LOG_TAG, "onCreate - appService is null"); |
| 106 | finish(); |
| 107 | return; |
| 108 | } |
| 109 | |
Takanori Nakano | 3776e2c | 2016-10-14 16:54:28 +0900 | [diff] [blame] | 110 | LocalBroadcastManager.getInstance(this).registerReceiver(mLocalBroadcastReceiver, |
| 111 | new IntentFilter(StkAppService.SESSION_ENDED)); |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 112 | initFromIntent(getIntent()); |
pkanwar | ae3a1c8 | 2017-04-13 10:24:48 -0700 | [diff] [blame] | 113 | if (!SubscriptionManager.isValidSlotIndex(mSlotId)) { |
| 114 | finish(); |
| 115 | return; |
| 116 | } |
Anna Suzuki | 35309b0 | 2019-02-15 16:24:59 +0900 | [diff] [blame] | 117 | if (mState == STATE_SECONDARY) { |
| 118 | appService.getStkContext(mSlotId).setPendingActivityInstance(this); |
| 119 | } |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 120 | } |
| 121 | |
| 122 | @Override |
| 123 | protected void onListItemClick(ListView l, View v, int position, long id) { |
| 124 | super.onListItemClick(l, v, position, id); |
Wink Saville | 79085fc | 2009-06-09 10:27:23 -0700 | [diff] [blame] | 125 | |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 126 | if (!mAcceptUsersInput) { |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 127 | CatLog.d(LOG_TAG, "mAcceptUsersInput:false"); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 128 | return; |
| 129 | } |
| 130 | |
| 131 | Item item = getSelectedItem(position); |
| 132 | if (item == null) { |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 133 | CatLog.d(LOG_TAG, "Item is null"); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 134 | return; |
| 135 | } |
Preeti Ahuja | 03be667 | 2012-08-30 19:21:25 +0530 | [diff] [blame] | 136 | |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 137 | CatLog.d(LOG_TAG, "onListItemClick Id: " + item.id + ", mState: " + mState); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 138 | sendResponse(StkAppService.RES_ID_MENU_SELECTION, item.id, false); |
Takanori Nakano | 4854435 | 2016-12-02 18:32:59 +0900 | [diff] [blame] | 139 | invalidateOptionsMenu(); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 140 | } |
| 141 | |
| 142 | @Override |
| 143 | public boolean onKeyDown(int keyCode, KeyEvent event) { |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 144 | CatLog.d(LOG_TAG, "mAcceptUsersInput: " + mAcceptUsersInput); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 145 | if (!mAcceptUsersInput) { |
| 146 | return true; |
| 147 | } |
| 148 | |
| 149 | switch (keyCode) { |
| 150 | case KeyEvent.KEYCODE_BACK: |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 151 | CatLog.d(LOG_TAG, "KEYCODE_BACK - mState[" + mState + "]"); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 152 | switch (mState) { |
| 153 | case STATE_SECONDARY: |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 154 | CatLog.d(LOG_TAG, "STATE_SECONDARY"); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 155 | sendResponse(StkAppService.RES_ID_BACKWARD); |
| 156 | return true; |
| 157 | case STATE_MAIN: |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 158 | CatLog.d(LOG_TAG, "STATE_MAIN"); |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 159 | finish(); |
| 160 | return true; |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 161 | } |
| 162 | break; |
| 163 | } |
| 164 | return super.onKeyDown(keyCode, event); |
| 165 | } |
| 166 | |
| 167 | @Override |
| 168 | public void onResume() { |
| 169 | super.onResume(); |
| 170 | |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 171 | CatLog.d(LOG_TAG, "onResume, slot id: " + mSlotId + "," + mState); |
| 172 | appService.indicateMenuVisibility(true, mSlotId); |
| 173 | if (mState == STATE_MAIN) { |
| 174 | mStkMenu = appService.getMainMenu(mSlotId); |
| 175 | } else { |
| 176 | mStkMenu = appService.getMenu(mSlotId); |
| 177 | } |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 178 | if (mStkMenu == null) { |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 179 | CatLog.d(LOG_TAG, "menu is null"); |
| 180 | cancelTimeOut(); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 181 | finish(); |
| 182 | return; |
| 183 | } |
| 184 | displayMenu(); |
Yoshiaki Naka | 3133534 | 2018-03-19 16:24:12 +0900 | [diff] [blame] | 185 | |
| 186 | if (mAlarmTime == NO_SELECT_ALARM) { |
| 187 | startTimeOut(); |
| 188 | } |
| 189 | |
w30234 | 64ec38e | 2014-09-17 16:32:02 -0700 | [diff] [blame] | 190 | invalidateOptionsMenu(); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 191 | } |
| 192 | |
| 193 | @Override |
| 194 | public void onPause() { |
| 195 | super.onPause(); |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 196 | CatLog.d(LOG_TAG, "onPause, slot id: " + mSlotId + "," + mState); |
| 197 | //If activity is finished in onResume and it reaults from null appService. |
| 198 | if (appService != null) { |
| 199 | appService.indicateMenuVisibility(false, mSlotId); |
| 200 | } else { |
| 201 | CatLog.d(LOG_TAG, "onPause: null appService."); |
| 202 | } |
Preeti Ahuja | 03be667 | 2012-08-30 19:21:25 +0530 | [diff] [blame] | 203 | |
| 204 | /* |
| 205 | * do not cancel the timer here cancelTimeOut(). If any higher/lower |
| 206 | * priority events such as incoming call, new sms, screen off intent, |
| 207 | * notification alerts, user actions such as 'User moving to another activtiy' |
| 208 | * etc.. occur during SELECT ITEM ongoing session, |
| 209 | * this activity would receive 'onPause()' event resulting in |
| 210 | * cancellation of the timer. As a result no terminal response is |
| 211 | * sent to the card. |
| 212 | */ |
| 213 | |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 214 | } |
| 215 | |
| 216 | @Override |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 217 | public void onStop() { |
| 218 | super.onStop(); |
| 219 | CatLog.d(LOG_TAG, "onStop, slot id: " + mSlotId + "," + mIsResponseSent + "," + mState); |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 220 | } |
| 221 | |
| 222 | @Override |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 223 | public void onDestroy() { |
Guillaume Lucas | 82d3e79 | 2012-08-03 17:56:34 +0200 | [diff] [blame] | 224 | getListView().setOnCreateContextMenuListener(null); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 225 | super.onDestroy(); |
Srikanth Chintala | b5ea5d6 | 2014-07-11 02:04:40 -0400 | [diff] [blame] | 226 | CatLog.d(LOG_TAG, "onDestroy" + ", " + mState); |
pkanwar | ae3a1c8 | 2017-04-13 10:24:48 -0700 | [diff] [blame] | 227 | if (appService == null || !SubscriptionManager.isValidSlotIndex(mSlotId)) { |
Ryuto Sawada | ba9b86b | 2016-10-03 14:03:16 +0900 | [diff] [blame] | 228 | return; |
| 229 | } |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 230 | //isMenuPending: if input act is finish by stkappservice when OP_LAUNCH_APP again, |
| 231 | //we can not send TR here, since the input cmd is waiting user to process. |
Tsukasa Gotou | 46f29b5 | 2016-01-28 12:32:54 +0900 | [diff] [blame] | 232 | if (mState == STATE_SECONDARY && !mIsResponseSent && !appService.isMenuPending(mSlotId)) { |
Takanori Nakano | 6c2d468 | 2017-10-19 20:36:50 +0900 | [diff] [blame] | 233 | // Avoid sending the terminal response while the activty is being restarted |
| 234 | // due to some kind of configuration change. |
| 235 | if (!isChangingConfigurations()) { |
| 236 | CatLog.d(LOG_TAG, "handleDestroy - Send End Session"); |
| 237 | sendResponse(StkAppService.RES_ID_END_SESSION); |
| 238 | } |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 239 | } |
Yoshiaki Naka | 3133534 | 2018-03-19 16:24:12 +0900 | [diff] [blame] | 240 | cancelTimeOut(); |
Takanori Nakano | 3776e2c | 2016-10-14 16:54:28 +0900 | [diff] [blame] | 241 | LocalBroadcastManager.getInstance(this).unregisterReceiver(mLocalBroadcastReceiver); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 242 | } |
| 243 | |
| 244 | @Override |
| 245 | public boolean onCreateOptionsMenu(android.view.Menu menu) { |
| 246 | super.onCreateOptionsMenu(menu); |
| 247 | menu.add(0, StkApp.MENU_ID_END_SESSION, 1, R.string.menu_end_session); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 248 | return true; |
| 249 | } |
| 250 | |
| 251 | @Override |
| 252 | public boolean onPrepareOptionsMenu(android.view.Menu menu) { |
| 253 | super.onPrepareOptionsMenu(menu); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 254 | boolean mainVisible = false; |
| 255 | |
Takanori Nakano | 4854435 | 2016-12-02 18:32:59 +0900 | [diff] [blame] | 256 | if (mState == STATE_SECONDARY && mAcceptUsersInput) { |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 257 | mainVisible = true; |
| 258 | } |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 259 | |
| 260 | menu.findItem(StkApp.MENU_ID_END_SESSION).setVisible(mainVisible); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 261 | |
Srikanth Chintala | b5ea5d6 | 2014-07-11 02:04:40 -0400 | [diff] [blame] | 262 | return mainVisible; |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 263 | } |
| 264 | |
| 265 | @Override |
| 266 | public boolean onOptionsItemSelected(MenuItem item) { |
| 267 | if (!mAcceptUsersInput) { |
| 268 | return true; |
| 269 | } |
| 270 | switch (item.getItemId()) { |
| 271 | case StkApp.MENU_ID_END_SESSION: |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 272 | // send session end response. |
| 273 | sendResponse(StkAppService.RES_ID_END_SESSION); |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 274 | finish(); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 275 | return true; |
Takanori Nakano | 4854435 | 2016-12-02 18:32:59 +0900 | [diff] [blame] | 276 | default: |
| 277 | break; |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 278 | } |
| 279 | return super.onOptionsItemSelected(item); |
| 280 | } |
| 281 | |
| 282 | @Override |
Guillaume Lucas | 82d3e79 | 2012-08-03 17:56:34 +0200 | [diff] [blame] | 283 | public void onCreateContextMenu(ContextMenu menu, View v, |
| 284 | ContextMenuInfo menuInfo) { |
Yoshiaki Naka | 3a980db | 2019-10-30 17:11:33 +0900 | [diff] [blame] | 285 | CatLog.d(LOG_TAG, "onCreateContextMenu"); |
Guillaume Lucas | 82d3e79 | 2012-08-03 17:56:34 +0200 | [diff] [blame] | 286 | boolean helpVisible = false; |
| 287 | if (mStkMenu != null) { |
| 288 | helpVisible = mStkMenu.helpAvailable; |
| 289 | } |
| 290 | if (helpVisible) { |
Yoshiaki Naka | 3a980db | 2019-10-30 17:11:33 +0900 | [diff] [blame] | 291 | CatLog.d(LOG_TAG, "add menu"); |
Guillaume Lucas | 82d3e79 | 2012-08-03 17:56:34 +0200 | [diff] [blame] | 292 | menu.add(0, CONTEXT_MENU_HELP, 0, R.string.help); |
| 293 | } |
| 294 | } |
| 295 | |
| 296 | @Override |
| 297 | public boolean onContextItemSelected(MenuItem item) { |
| 298 | AdapterView.AdapterContextMenuInfo info; |
| 299 | try { |
| 300 | info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); |
| 301 | } catch (ClassCastException e) { |
| 302 | return false; |
| 303 | } |
| 304 | switch (item.getItemId()) { |
| 305 | case CONTEXT_MENU_HELP: |
Guillaume Lucas | 82d3e79 | 2012-08-03 17:56:34 +0200 | [diff] [blame] | 306 | int position = info.position; |
Yoshiaki Naka | 3a980db | 2019-10-30 17:11:33 +0900 | [diff] [blame] | 307 | CatLog.d(LOG_TAG, "Position:" + position); |
Guillaume Lucas | 82d3e79 | 2012-08-03 17:56:34 +0200 | [diff] [blame] | 308 | Item stkItem = getSelectedItem(position); |
| 309 | if (stkItem != null) { |
Yoshiaki Naka | 3a980db | 2019-10-30 17:11:33 +0900 | [diff] [blame] | 310 | CatLog.d(LOG_TAG, "item id:" + stkItem.id); |
Guillaume Lucas | 82d3e79 | 2012-08-03 17:56:34 +0200 | [diff] [blame] | 311 | sendResponse(StkAppService.RES_ID_MENU_SELECTION, stkItem.id, true); |
| 312 | } |
| 313 | return true; |
| 314 | |
| 315 | default: |
| 316 | return super.onContextItemSelected(item); |
| 317 | } |
| 318 | } |
| 319 | |
| 320 | @Override |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 321 | protected void onSaveInstanceState(Bundle outState) { |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 322 | CatLog.d(LOG_TAG, "onSaveInstanceState: " + mSlotId); |
Takanori Nakano | 6c2d468 | 2017-10-19 20:36:50 +0900 | [diff] [blame] | 323 | outState.putInt(STATE_KEY, mState); |
Takanori Nakano | 6c2d468 | 2017-10-19 20:36:50 +0900 | [diff] [blame] | 324 | outState.putBoolean(ACCEPT_USERS_INPUT_KEY, mAcceptUsersInput); |
| 325 | outState.putBoolean(RESPONSE_SENT_KEY, mIsResponseSent); |
Yoshiaki Naka | 3133534 | 2018-03-19 16:24:12 +0900 | [diff] [blame] | 326 | outState.putLong(ALARM_TIME_KEY, mAlarmTime); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 327 | } |
| 328 | |
| 329 | @Override |
| 330 | protected void onRestoreInstanceState(Bundle savedInstanceState) { |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 331 | CatLog.d(LOG_TAG, "onRestoreInstanceState: " + mSlotId); |
Takanori Nakano | 6c2d468 | 2017-10-19 20:36:50 +0900 | [diff] [blame] | 332 | mState = savedInstanceState.getInt(STATE_KEY); |
Takanori Nakano | 6c2d468 | 2017-10-19 20:36:50 +0900 | [diff] [blame] | 333 | mAcceptUsersInput = savedInstanceState.getBoolean(ACCEPT_USERS_INPUT_KEY); |
Takanori Nakano | 3776e2c | 2016-10-14 16:54:28 +0900 | [diff] [blame] | 334 | if (!mAcceptUsersInput) { |
| 335 | // Check the latest information as the saved instance state can be outdated. |
| 336 | if ((mState == STATE_MAIN) && appService.isMainMenuAvailable(mSlotId)) { |
| 337 | mAcceptUsersInput = true; |
| 338 | } else { |
| 339 | showProgressBar(true); |
| 340 | } |
| 341 | } |
Takanori Nakano | 6c2d468 | 2017-10-19 20:36:50 +0900 | [diff] [blame] | 342 | mIsResponseSent = savedInstanceState.getBoolean(RESPONSE_SENT_KEY); |
Yoshiaki Naka | 3133534 | 2018-03-19 16:24:12 +0900 | [diff] [blame] | 343 | |
| 344 | mAlarmTime = savedInstanceState.getLong(ALARM_TIME_KEY, NO_SELECT_ALARM); |
| 345 | if (mAlarmTime != NO_SELECT_ALARM) { |
| 346 | startTimeOut(); |
| 347 | } |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 348 | } |
Wink Saville | 79085fc | 2009-06-09 10:27:23 -0700 | [diff] [blame] | 349 | |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 350 | private void cancelTimeOut() { |
Yoshiaki Naka | 3133534 | 2018-03-19 16:24:12 +0900 | [diff] [blame] | 351 | if (mAlarmTime != NO_SELECT_ALARM) { |
| 352 | CatLog.d(LOG_TAG, "cancelTimeOut - slot id: " + mSlotId); |
| 353 | AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); |
| 354 | am.cancel(mAlarmListener); |
| 355 | mAlarmTime = NO_SELECT_ALARM; |
| 356 | } |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 357 | } |
| 358 | |
| 359 | private void startTimeOut() { |
Yoshiaki Naka | 3133534 | 2018-03-19 16:24:12 +0900 | [diff] [blame] | 360 | // No need to set alarm if this is the main menu or device sent TERMINAL RESPONSE already. |
| 361 | if (mState != STATE_SECONDARY || mIsResponseSent) { |
| 362 | return; |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 363 | } |
Yoshiaki Naka | 3133534 | 2018-03-19 16:24:12 +0900 | [diff] [blame] | 364 | |
| 365 | if (mAlarmTime == NO_SELECT_ALARM) { |
| 366 | mAlarmTime = SystemClock.elapsedRealtime() + StkApp.UI_TIMEOUT; |
| 367 | } |
| 368 | |
| 369 | CatLog.d(LOG_TAG, "startTimeOut: " + mAlarmTime + "ms, slot id: " + mSlotId); |
| 370 | AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); |
| 371 | am.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, mAlarmTime, SELECT_ALARM_TAG, |
| 372 | mAlarmListener, null); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 373 | } |
Wink Saville | 79085fc | 2009-06-09 10:27:23 -0700 | [diff] [blame] | 374 | |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 375 | // Bind list adapter to the items list. |
| 376 | private void displayMenu() { |
| 377 | |
| 378 | if (mStkMenu != null) { |
Pierre Fröjd | 3e34a8a | 2010-11-30 15:28:54 +0100 | [diff] [blame] | 379 | String title = mStkMenu.title == null ? getString(R.string.app_name) : mStkMenu.title; |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 380 | // Display title & title icon |
| 381 | if (mStkMenu.titleIcon != null) { |
| 382 | mTitleIconView.setImageBitmap(mStkMenu.titleIcon); |
Umashankar Godachi | c77445b | 2018-02-28 02:51:56 +0530 | [diff] [blame] | 383 | mTitleIconView.setContentDescription(StkAppService.TEXT_ICON_FROM_COMMAND); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 384 | mTitleIconView.setVisibility(View.VISIBLE); |
Pierre Fröjd | 3e34a8a | 2010-11-30 15:28:54 +0100 | [diff] [blame] | 385 | mTitleTextView.setVisibility(View.INVISIBLE); |
| 386 | if (!mStkMenu.titleIconSelfExplanatory) { |
| 387 | mTitleTextView.setText(title); |
| 388 | mTitleTextView.setVisibility(View.VISIBLE); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 389 | } |
| 390 | } else { |
Pierre Fröjd | 3e34a8a | 2010-11-30 15:28:54 +0100 | [diff] [blame] | 391 | mTitleIconView.setVisibility(View.GONE); |
| 392 | mTitleTextView.setVisibility(View.VISIBLE); |
| 393 | mTitleTextView.setText(title); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 394 | } |
| 395 | // create an array adapter for the menu list |
| 396 | StkMenuAdapter adapter = new StkMenuAdapter(this, |
| 397 | mStkMenu.items, mStkMenu.itemsIconSelfExplanatory); |
| 398 | // Bind menu list to the new adapter. |
| 399 | setListAdapter(adapter); |
| 400 | // Set default item |
| 401 | setSelection(mStkMenu.defaultItem); |
| 402 | } |
| 403 | } |
| 404 | |
Takanori Nakano | 3776e2c | 2016-10-14 16:54:28 +0900 | [diff] [blame] | 405 | private void showProgressBar(boolean show) { |
| 406 | if (show) { |
| 407 | mProgressView.setIndeterminate(true); |
| 408 | mProgressView.setVisibility(View.VISIBLE); |
| 409 | } else { |
| 410 | mProgressView.setIndeterminate(false); |
| 411 | mProgressView.setVisibility(View.GONE); |
| 412 | } |
| 413 | } |
| 414 | |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 415 | private void initFromIntent(Intent intent) { |
| 416 | |
| 417 | if (intent != null) { |
| 418 | mState = intent.getIntExtra("STATE", STATE_MAIN); |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 419 | mSlotId = intent.getIntExtra(StkAppService.SLOT_ID, -1); |
| 420 | CatLog.d(LOG_TAG, "slot id: " + mSlotId + ", state: " + mState); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 421 | } else { |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 422 | CatLog.d(LOG_TAG, "finish!"); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 423 | finish(); |
| 424 | } |
| 425 | } |
| 426 | |
| 427 | private Item getSelectedItem(int position) { |
| 428 | Item item = null; |
| 429 | if (mStkMenu != null) { |
| 430 | try { |
| 431 | item = mStkMenu.items.get(position); |
| 432 | } catch (IndexOutOfBoundsException e) { |
| 433 | if (StkApp.DBG) { |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 434 | CatLog.d(LOG_TAG, "IOOBE Invalid menu"); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 435 | } |
| 436 | } catch (NullPointerException e) { |
| 437 | if (StkApp.DBG) { |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 438 | CatLog.d(LOG_TAG, "NPE Invalid menu"); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 439 | } |
| 440 | } |
| 441 | } |
| 442 | return item; |
| 443 | } |
| 444 | |
| 445 | private void sendResponse(int resId) { |
| 446 | sendResponse(resId, 0, false); |
| 447 | } |
| 448 | |
| 449 | private void sendResponse(int resId, int itemId, boolean help) { |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 450 | CatLog.d(LOG_TAG, "sendResponse resID[" + resId + "] itemId[" + itemId + |
| 451 | "] help[" + help + "]"); |
Takanori Nakano | 3776e2c | 2016-10-14 16:54:28 +0900 | [diff] [blame] | 452 | |
| 453 | // Disallow user operation temporarily until receiving the result of the response. |
| 454 | mAcceptUsersInput = false; |
| 455 | if (resId == StkAppService.RES_ID_MENU_SELECTION) { |
| 456 | showProgressBar(true); |
| 457 | } |
Yoshiaki Naka | 3133534 | 2018-03-19 16:24:12 +0900 | [diff] [blame] | 458 | cancelTimeOut(); |
Takanori Nakano | 3776e2c | 2016-10-14 16:54:28 +0900 | [diff] [blame] | 459 | |
Wink Saville | e68857d | 2014-10-17 15:23:05 -0700 | [diff] [blame] | 460 | mIsResponseSent = true; |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 461 | Bundle args = new Bundle(); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 462 | args.putInt(StkAppService.RES_ID, resId); |
| 463 | args.putInt(StkAppService.MENU_SELECTION, itemId); |
| 464 | args.putBoolean(StkAppService.HELP, help); |
Takanori Nakano | 43dacc0 | 2018-07-26 11:27:39 +0900 | [diff] [blame] | 465 | appService.sendResponse(args, mSlotId); |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 466 | } |
Takanori Nakano | 3776e2c | 2016-10-14 16:54:28 +0900 | [diff] [blame] | 467 | |
| 468 | private final BroadcastReceiver mLocalBroadcastReceiver = new BroadcastReceiver() { |
| 469 | @Override |
| 470 | public void onReceive(Context context, Intent intent) { |
| 471 | if (StkAppService.SESSION_ENDED.equals(intent.getAction())) { |
| 472 | int slotId = intent.getIntExtra(StkAppService.SLOT_ID, 0); |
| 473 | if ((mState == STATE_MAIN) && (mSlotId == slotId)) { |
| 474 | mAcceptUsersInput = true; |
| 475 | showProgressBar(false); |
| 476 | } |
| 477 | } |
| 478 | } |
| 479 | }; |
Yoshiaki Naka | 3133534 | 2018-03-19 16:24:12 +0900 | [diff] [blame] | 480 | |
| 481 | private final AlarmManager.OnAlarmListener mAlarmListener = |
| 482 | new AlarmManager.OnAlarmListener() { |
| 483 | @Override |
| 484 | public void onAlarm() { |
| 485 | CatLog.d(LOG_TAG, "The alarm time is reached"); |
| 486 | mAlarmTime = NO_SELECT_ALARM; |
Yoshiaki Naka | 3133534 | 2018-03-19 16:24:12 +0900 | [diff] [blame] | 487 | sendResponse(StkAppService.RES_ID_TIMEOUT); |
| 488 | } |
| 489 | }; |
The Android Open Source Project | 9d9730a | 2009-03-03 19:32:37 -0800 | [diff] [blame] | 490 | } |