Fix incorrect handling of pending activity and state management

StkMenuActivity for secondary menu and StkInputActivity currently
register theirselves as pending activity, but it is never unregistered
by theirselves. Pending activity should be unregistered when it is
brought back to the foreground unless terminal response has already been
sent to the card.

Bug: 113367485
Test: Manually confirmed that the pending activity works as expected.

Change-Id: I335d1867c121191b31d8436eea4982a7d45a1c90
diff --git a/src/com/android/stk/StkInputActivity.java b/src/com/android/stk/StkInputActivity.java
index 63d1fba..4e7a48b 100644
--- a/src/com/android/stk/StkInputActivity.java
+++ b/src/com/android/stk/StkInputActivity.java
@@ -81,6 +81,7 @@
     private static final String RESPONSE_SENT_KEY = "response_sent";
     private static final String INPUT_STRING_KEY = "input_string";
     private static final String ALARM_TIME_KEY = "alarm_time";
+    private static final String PENDING = "pending";
 
     private static final String INPUT_ALARM_TAG = LOG_TAG;
     private static final long NO_INPUT_ALARM = -1;
@@ -89,6 +90,8 @@
     private StkAppService appService = StkAppService.getInstance();
 
     private boolean mIsResponseSent = false;
+    // Determines whether this is in the pending state.
+    private boolean mIsPending = false;
     private int mSlotId = -1;
 
     // Click listener to handle buttons press..
@@ -109,8 +112,8 @@
             input = mTextIn.getText().toString();
             break;
         case R.id.button_cancel:
-            appService.getStkContext(mSlotId).setPendingActivityInstance(this);
             sendResponse(StkAppService.RES_ID_END_SESSION);
+            finish();
             return;
         // Yes/No layout buttons.
         case R.id.button_yes:
@@ -143,7 +146,6 @@
             break;
         }
         CatLog.d(LOG_TAG, "handleClick, ready to response");
-        appService.getStkContext(mSlotId).setPendingActivityInstance(this);
         sendResponse(StkAppService.RES_ID_INPUT, input, false);
     }
 
@@ -209,6 +211,11 @@
         super.onResume();
         CatLog.d(LOG_TAG, "onResume - mIsResponseSent[" + mIsResponseSent +
                 "], slot id: " + mSlotId);
+        // If the terminal has already sent response to the card when this activity is resumed,
+        // keep this as a pending activity as this should be finished when the session ends.
+        if (!mIsResponseSent) {
+            setPendingState(false);
+        }
 
         if (mAlarmTime == NO_INPUT_ALARM) {
             startTimeOut();
@@ -229,8 +236,8 @@
         super.onStop();
         CatLog.d(LOG_TAG, "onStop - mIsResponseSent[" + mIsResponseSent + "]");
 
-        // Nothing should be done here if this activity is being restarted now.
-        if (isChangingConfigurations()) {
+        // Nothing should be done here if this activity is being finished or restarted now.
+        if (isFinishing() || isChangingConfigurations()) {
             return;
         }
 
@@ -241,9 +248,9 @@
                 finish();
             }
         } else {
-            // This should be set as the pending activity here
+            // This should be registered as the pending activity here
             // only when no response has been sent back to the card.
-            appService.getStkContext(mSlotId).setPendingActivityInstance(this);
+            setPendingState(true);
         }
     }
 
@@ -287,7 +294,6 @@
         switch (keyCode) {
         case KeyEvent.KEYCODE_BACK:
             CatLog.d(LOG_TAG, "onKeyDown - KEYCODE_BACK");
-            appService.getStkContext(mSlotId).setPendingActivityInstance(this);
             sendResponse(StkAppService.RES_ID_BACKWARD, null, false);
             return true;
         }
@@ -327,6 +333,11 @@
         }
         args.putBoolean(StkAppService.HELP, help);
         startService(new Intent(this, StkAppService.class).putExtras(args));
+
+        // This instance should be set as a pending activity and finished by the service
+        if (resId != StkAppService.RES_ID_END_SESSION) {
+            setPendingState(true);
+        }
     }
 
     @Override
@@ -373,7 +384,6 @@
             return true;
         case StkApp.MENU_ID_HELP:
             sendResponse(StkAppService.RES_ID_INPUT, "", true);
-            finish();
             return true;
         }
         return false;
@@ -385,6 +395,7 @@
         outState.putBoolean(RESPONSE_SENT_KEY, mIsResponseSent);
         outState.putString(INPUT_STRING_KEY, mTextIn.getText().toString());
         outState.putLong(ALARM_TIME_KEY, mAlarmTime);
+        outState.putBoolean(PENDING, mIsPending);
     }
 
     @Override
@@ -405,6 +416,22 @@
         if (mAlarmTime != NO_INPUT_ALARM) {
             startTimeOut();
         }
+
+        if (!mIsResponseSent && !savedInstanceState.getBoolean(PENDING)) {
+            // If this is in the foreground and no response has been sent to the card,
+            // this must not be registered as pending activity by the previous instance.
+            // No need to renew nor clear pending activity in this case.
+        } else {
+            // Renew the instance of the pending activity.
+            setPendingState(true);
+        }
+    }
+
+    private void setPendingState(boolean on) {
+        if (mIsPending != on) {
+            appService.getStkContext(mSlotId).setPendingActivityInstance(on ? this : null);
+            mIsPending = on;
+        }
     }
 
     public void beforeTextChanged(CharSequence s, int start, int count,
@@ -553,8 +580,6 @@
                 public void onAlarm() {
                     CatLog.d(LOG_TAG, "The alarm time is reached");
                     mAlarmTime = NO_INPUT_ALARM;
-                    appService.getStkContext(mSlotId).setPendingActivityInstance(
-                            StkInputActivity.this);
                     sendResponse(StkAppService.RES_ID_TIMEOUT);
                 }
             };