Merge "Ignore stale scan result if scan timer has been expired."
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 5fe6717..e90f37c 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -385,6 +385,8 @@
     private static final int EVENT_START_SATELLITE_POSITION_UPDATES_DONE = 120;
     private static final int CMD_STOP_SATELLITE_POSITION_UPDATES = 121;
     private static final int EVENT_STOP_SATELLITE_POSITION_UPDATES_DONE = 122;
+    private static final int CMD_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG = 123;
+    private static final int EVENT_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG_DONE = 124;
     // Parameters of select command.
     private static final int SELECT_COMMAND = 0xA4;
     private static final int SELECT_P1 = 0x04;
@@ -2368,6 +2370,53 @@
                     break;
                 }
 
+                case CMD_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG: {
+                    request = (MainThreadRequest) msg.obj;
+                    onCompleted = obtainMessage(EVENT_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG_DONE,
+                            request);
+                    Phone phone = getPhoneFromRequest(request);
+                    if (phone != null) {
+                        phone.getMaxCharactersPerSatelliteTextMessage(onCompleted);
+                    } else {
+                        loge("getMaxCharactersPerSatelliteTextMessage: No phone object");
+                        request.result = SatelliteManager
+                                .SATELLITE_SERVICE_TELEPHONY_INTERNAL_ERROR;
+                        notifyRequester(request);
+                    }
+                    break;
+                }
+
+                case EVENT_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG_DONE: {
+                    ar = (AsyncResult) msg.obj;
+                    request = (MainThreadRequest) ar.userObj;
+                    Consumer<Integer> callback = (Consumer<Integer>) request.argument;
+                    if (ar.exception != null) {
+                        request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
+                        if (ar.exception instanceof CommandException) {
+                            CommandException.Error error =
+                                    ((CommandException) (ar.exception)).getCommandError();
+                            request.result = RILUtils.convertToSatelliteError(error);
+                            loge("getMaxCharactersPerSatelliteTextMessage: "
+                                    + "CommandException: " + ar.exception);
+                        } else {
+                            loge("getMaxCharactersPerSatelliteTextMessage: "
+                                    + "unknown exception:" + ar.exception);
+                        }
+                    } else if (ar.result == null) {
+                        request.result = SatelliteManager
+                                .SATELLITE_SERVICE_TELEPHONY_INTERNAL_ERROR;
+                        loge("getMaxCharactersPerSatelliteTextMessage: result is null");
+                    } else {
+                        request.result = SatelliteManager.SATELLITE_SERVICE_SUCCESS;
+                        int maxCharLimit = ((int[]) ar.result)[0];
+                        if(DBG) log("getMaxCharactersPerSatelliteTextMessage "
+                                + "maxCharLimit:" + maxCharLimit);
+                        callback.accept(maxCharLimit);
+                    }
+                    notifyRequester(request);
+                    break;
+                }
+
                 default:
                     Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
                     break;
@@ -3898,6 +3947,15 @@
         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
     }
 
+    /**
+     * Make sure the caller has SATELLITE_COMMUNICATION permission.
+     * @param message - log message to print.
+     * @throws SecurityException if the caller does not have the required permission
+     */
+    private void enforceSatelliteCommunicationPermission(String message) {
+        mApp.enforceCallingOrSelfPermission(permission.SATELLITE_COMMUNICATION, message);
+    }
+
     private String createTelUrl(String number) {
         if (TextUtils.isEmpty(number)) {
             return null;
@@ -12255,6 +12313,40 @@
     }
 
     /**
+     * Get maximum number of characters per text message on satellite.
+     * @param subId - The subId of the subscription.
+     * @param callback - The callback that will be used to send maximum characters limit
+     *                 if operation is successful.
+     * @return The result of the operation.
+     *
+     * @throws SecurityException if the caller doesn't have the required permission.
+     */
+    @Override
+    public int getMaxCharactersPerSatelliteTextMessage(int subId, IIntegerConsumer callback) {
+        enforceSatelliteCommunicationPermission("getMaxCharactersPerSatelliteTextMessage");
+
+        if (!isSatelliteEnabled(subId)) {
+            return SatelliteManager.SATELLITE_SERVICE_DISABLED;
+        }
+
+        Phone phone = getPhone(subId);
+        if (phone == null) {
+            loge("getMaxCharactersPerSatelliteTextMessage called with invalid subId: " + subId
+                    + ".Retrying with default phone.");
+            phone = getDefaultPhone();
+            if (phone == null) {
+                loge("getMaxCharactersPerSatelliteTextMessage failed with no phone object.");
+                return SatelliteManager.SATELLITE_SERVICE_TELEPHONY_INTERNAL_ERROR;
+            }
+        }
+
+        Consumer<Integer> argument = FunctionalUtils.ignoreRemoteException(callback::accept);
+        int result = (int) sendRequest(CMD_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG, argument, subId);
+        if (DBG) log("getMaxCharPerTextMessageOnSatellite result: " + result);
+        return result;
+    }
+
+    /**
      * Check whether the caller (or self, if not processing an IPC) can read device identifiers.
      *
      * <p>This method behaves in one of the following ways:
@@ -12279,6 +12371,21 @@
     }
 
     /**
+     * Check if satellite is enabled for a subscription.
+     */
+    private boolean isSatelliteEnabled(int subId) {
+        if (mSubscriptionController != null) {
+            String strResult = mSubscriptionController.getSubscriptionProperty(
+                    subId, SubscriptionManager.SATELLITE_ENABLED);
+            if (strResult != null) {
+                int intResult = Integer.parseInt(strResult);
+                return (intResult == 1) ? true : false;
+            }
+        }
+        return false;
+    }
+
+    /**
      * Class binds the consumer[callback] and carrierId.
      */
     private static class CallerCallbackInfo {