NFC: Update framework to 4.5.0_M

Update framework to latest release, manually integrated
modifications to ApduServiceInfo.

Integrated from commit 0a6bbe0b48e0e341fa1e5d2aee2cfb83364e20ef in
caf-3/nxpnfc-project/br_android_ncihalx_m.

Change-Id: I9398ea9124c217dae33e1f08ed1534234f7dfe2a
diff --git a/android/nfc/cardemulation/NQApduServiceInfo.java b/android/nfc/cardemulation/NQApduServiceInfo.java
index 821134e..b5d6959 100644
--- a/android/nfc/cardemulation/NQApduServiceInfo.java
+++ b/android/nfc/cardemulation/NQApduServiceInfo.java
@@ -45,6 +45,7 @@
 import android.util.Log;
 import android.util.Xml;
 import android.graphics.Bitmap;
+import com.nxp.nfc.NxpConstants;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -121,10 +122,13 @@
 
     /**
      * This says whether the Service is enabled or disabled by the user
-     * By default it is enabled.This is only applicable for OTHER category.
-     *
+     * By default it is disabled.This is only applicable for OTHER category.
+     * states are as follows
+     * ENABLING(service creation)->ENABLED(Committed to Routing)->
+     * DISABLING(user requested to disable)->DISABLED(Removed from Routing).
+     * In ENABLED or DISABLING state, this service will be accounted for routing.
      */
-    boolean mServiceState;
+    int mServiceState;
 
     /**
       * nxp se extension
@@ -172,7 +176,7 @@
         this.mNfcid2Groups = new ArrayList<Nfcid2Group>();
         this.mNfcid2s = new ArrayList<String>();
         this.mNfcid2CategoryToGroup = new HashMap<String, Nfcid2Group>();
-        this.mServiceState = true;
+        this.mServiceState = NxpConstants.SERVICE_STATE_ENABLING;
         if(nfcid2Groups != null) {
             for (Nfcid2Group nfcid2Group : nfcid2Groups) {
                 this.mNfcid2Groups.add(nfcid2Group);
@@ -190,7 +194,7 @@
         super(pm, info, onHost);
         this.mBanner = null;
         this.mModifiable = false;
-        this.mServiceState = true;
+        this.mServiceState = NxpConstants.SERVICE_STATE_ENABLING;
         ServiceInfo si = info.serviceInfo;
         XmlResourceParser parser = null;
         XmlResourceParser extParser = null;
@@ -748,20 +752,103 @@
         }
     };
 
-    public boolean getServiceState(String category) {
+    public boolean isServiceEnabled(String category) {
         if(category != CardEmulation.CATEGORY_OTHER) {
             return true;
         }
-        return mServiceState;
+
+        if((mServiceState ==  NxpConstants.SERVICE_STATE_ENABLED) || (mServiceState ==  NxpConstants.SERVICE_STATE_DISABLING)){
+            return true;
+        }else{ /*SERVICE_STATE_DISABLED or SERVICE_STATE_ENABLING*/
+            return false;
+        }
     }
 
-    public void setServiceState(String category ,boolean state) {
+    /**
+     * This method is invoked before the service is commited to routing table.
+     * mServiceState is previous state of the service, and,
+     * user is now requesting to enable/disable (using flagEnable) this service
+     * before committing all the services to routing table.
+     * @param flagEnable To Enable/Disable the service.
+     *        FALSE Disable service
+     *        TRUE Enable service
+     */
+    public void enableService(String category ,boolean flagEnable) {
         if(category != CardEmulation.CATEGORY_OTHER) {
             return;
         }
-        mServiceState = state;
+        Log.d(TAG, "setServiceState:Description:" + mDescription + ":InternalState:" + mServiceState + ":flagEnable:"+ flagEnable);
+        if(((mServiceState == NxpConstants.SERVICE_STATE_ENABLED) &&    (flagEnable == true )) ||
+           ((mServiceState ==  NxpConstants.SERVICE_STATE_DISABLED) &&  (flagEnable == false)) ||
+           ((mServiceState ==  NxpConstants.SERVICE_STATE_DISABLING) && (flagEnable == false)) ||
+           ((mServiceState ==  NxpConstants.SERVICE_STATE_ENABLING) &&  (flagEnable == true ))){
+            /*No change in state*/
+            return;
+        }
+        else if((mServiceState ==  NxpConstants.SERVICE_STATE_ENABLED) && (flagEnable == false)){
+            mServiceState =  NxpConstants.SERVICE_STATE_DISABLING;
+        }
+        else if((mServiceState ==  NxpConstants.SERVICE_STATE_DISABLED) && (flagEnable == true)){
+            mServiceState =  NxpConstants.SERVICE_STATE_ENABLING;
+        }
+        else if((mServiceState ==  NxpConstants.SERVICE_STATE_DISABLING) && (flagEnable == true)){
+            mServiceState =  NxpConstants.SERVICE_STATE_ENABLED;
+        }
+        else if((mServiceState ==  NxpConstants.SERVICE_STATE_ENABLING) && (flagEnable == false)){
+            mServiceState =  NxpConstants.SERVICE_STATE_DISABLED;
+        }
     }
 
+    public int getServiceState(String category) {
+        if(category != CardEmulation.CATEGORY_OTHER) {
+            return NxpConstants.SERVICE_STATE_ENABLED;
+        }
+
+        return mServiceState;
+    }
+
+    public int setServiceState(String category ,int state) {
+        if(category != CardEmulation.CATEGORY_OTHER) {
+            return NxpConstants.SERVICE_STATE_ENABLED;
+        }
+
+        mServiceState = state;
+        return mServiceState;
+    }
+
+    /**
+     * Updates the state of the service based on the commit status
+     * This method needs to be invoked after current service is pushed for the commit to routing table
+     * @param commitStatus Result of the commit.
+     *        FALSE if the commit failed. Reason for ex: there was an overflow of routing table
+     *        TRUE if the commit was successful
+     */
+    public void updateServiceCommitStatus(String category ,boolean commitStatus) {
+        if(category != CardEmulation.CATEGORY_OTHER) {
+            return;
+        }
+        Log.d(TAG, "updateServiceCommitStatus:Description:" + mDescription + ":InternalState:" + mServiceState + ":commitStatus:"+ commitStatus);
+        if(commitStatus){
+            /*Commit was successful and all newly added services were registered,
+             * disabled applications were removed/unregistered from routing entries*/
+            if(mServiceState ==  NxpConstants.SERVICE_STATE_DISABLING){
+                mServiceState =  NxpConstants.SERVICE_STATE_DISABLED;
+            }
+            else if(mServiceState == NxpConstants.SERVICE_STATE_ENABLING){
+                mServiceState = NxpConstants.SERVICE_STATE_ENABLED;
+            }
+
+        }else{
+            /*Commit failed and all newly added services were not registered successfully.
+             * disabled applications were not successfully disabled*/
+            if(mServiceState ==  NxpConstants.SERVICE_STATE_DISABLING){
+                mServiceState =  NxpConstants.SERVICE_STATE_ENABLED;
+            }
+            else if(mServiceState ==  NxpConstants.SERVICE_STATE_ENABLING){
+                mServiceState =  NxpConstants.SERVICE_STATE_DISABLED;
+            }
+        }
+    }
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("    " + getComponent() +
                 " (Description: " + getDescription() + ")");
diff --git a/com/nxp/nfc/INxpNfcAdapter.aidl b/com/nxp/nfc/INxpNfcAdapter.aidl
index c7085e1..d7b4317 100644
--- a/com/nxp/nfc/INxpNfcAdapter.aidl
+++ b/com/nxp/nfc/INxpNfcAdapter.aidl
@@ -47,6 +47,8 @@
     int getSeInterface(int type);
     byte[]  getFWVersion();
     Map getServicesAidCacheSize(int userId, String category);
+    int getMaxAidRoutingTableSize();
+    int getCommittedAidRoutingTableSize();
     int[] getActiveSecureElementList(String pkg);
     int updateServiceState(int userId , in Map serviceState);
 }
diff --git a/com/nxp/nfc/INxpNfcAdapterExtras.aidl b/com/nxp/nfc/INxpNfcAdapterExtras.aidl
index 943d343..7f96e5f 100644
--- a/com/nxp/nfc/INxpNfcAdapterExtras.aidl
+++ b/com/nxp/nfc/INxpNfcAdapterExtras.aidl
@@ -33,4 +33,7 @@
     byte[] doGetRouting();
     void notifyCheckCertResult(in String pkg, in boolean success);
     void deliverSeIntent(String pkg, in Intent seIntent);
+    int selectUicc(int uiccSlot);
+    int getSelectedUicc();
+
 }
\ No newline at end of file
diff --git a/com/nxp/nfc/NxpConstants.java b/com/nxp/nfc/NxpConstants.java
index 7270b49..4c070f8 100644
--- a/com/nxp/nfc/NxpConstants.java
+++ b/com/nxp/nfc/NxpConstants.java
@@ -186,5 +186,14 @@
     public static final String ACTION_GSMA_ENABLE_NFC = "com.gsma.services.nfc.action.ENABLE_NFC";
     public static final String ACTION_GSMA_ENABLE_SET_FLAG = "com.gsma.services.nfc.action.ENABLE_NFC_SET_FALG";
 
+    /**
+     * Indicates the states of an APDU service.
+     * Service is enabled only when the commit to routing table is successful
+     */
+    public static final int SERVICE_STATE_DISABLED  = 0;
+    public static final int SERVICE_STATE_ENABLED   = 1;
+    public static final int SERVICE_STATE_ENABLING  = 2;
+    public static final int SERVICE_STATE_DISABLING = 3;
+
 
 }
diff --git a/com/nxp/nfc/NxpNfcAdapter.java b/com/nxp/nfc/NxpNfcAdapter.java
index 14b0125..02eaa4b 100644
--- a/com/nxp/nfc/NxpNfcAdapter.java
+++ b/com/nxp/nfc/NxpNfcAdapter.java
@@ -593,4 +593,35 @@
             return null;
         }
     }
+    /**
+     * This api is called by applications to get the maximum routing table for AID registration
+     * The returned value doesn't provide the current remaining size available for AID.
+     * This value depends on the size available in NFCC and is constant.
+     * <p>Requires {@link android.Manifest.permission#NFC} permission.
+     * @return maximum routing table size for AID registration.
+     * @throws  IOException if any exception occurs while retrieving the size.
+     */
+    public int getMaxAidRoutingTableSize() throws IOException{
+        try{
+            return sNxpService.getMaxAidRoutingTableSize();
+        }catch(RemoteException e){
+            e.printStackTrace();
+            return 0x00;
+        }
+    }
+    /**
+     * This api is called by applications to get the size of AID data which is already committed
+     * to routing table in NFCC.
+     * <p>Requires {@link android.Manifest.permission#NFC} permission.
+     * @return  occupied size of routing table for AID registrations.
+     * @throws  IOException if any exception occurs while retrieving the size.
+     */
+    public int getCommittedAidRoutingTableSize() throws IOException{
+        try{
+            return sNxpService.getCommittedAidRoutingTableSize();
+        }catch(RemoteException e){
+            e.printStackTrace();
+            return 0x00;
+        }
+    }
 }