Merge "IMS: Use AOSP Defined Carrier Config APIs for RTT"
diff --git a/ims/ims-ext-common/src/org/codeaurora/ims/QtiImsUnsupportedImageFormatException.java b/ims/ims-ext-common/src/org/codeaurora/ims/QtiImsUnsupportedImageFormatException.java
deleted file mode 100644
index 4241577..0000000
--- a/ims/ims-ext-common/src/org/codeaurora/ims/QtiImsUnsupportedImageFormatException.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimer in the documentation and/or other materials provided
- *       with the distribution.
- *     * Neither the name of The Linux Foundation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package org.codeaurora.ims;
-
-/**
- * This class is to handle custom unsupported image format exception
- */
-public class QtiImsUnsupportedImageFormatException extends QtiImsException {
-
-    public QtiImsUnsupportedImageFormatException() {
-        // Empty constructor
-    }
-
-    public QtiImsUnsupportedImageFormatException(String message) {
-        super(message);
-    }
-
-    public QtiImsUnsupportedImageFormatException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/ims/ims-ext-common/src/org/codeaurora/ims/utils/QtiImsExtUtils.java b/ims/ims-ext-common/src/org/codeaurora/ims/utils/QtiImsExtUtils.java
index 6b0bd2c..17b2cce 100644
--- a/ims/ims-ext-common/src/org/codeaurora/ims/utils/QtiImsExtUtils.java
+++ b/ims/ims-ext-common/src/org/codeaurora/ims/utils/QtiImsExtUtils.java
@@ -35,6 +35,8 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Matrix;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
 import android.os.SystemProperties;
 import android.provider.Settings;
@@ -45,6 +47,11 @@
 import android.util.Log;
 
 import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.IllegalArgumentException;
+import java.lang.SecurityException;
 
 import org.codeaurora.ims.QtiCallConstants;
 import org.codeaurora.ims.QtiCarrierConfigs;
@@ -197,13 +204,12 @@
                                      QTI_IMS_STATIC_IMAGE_SETTING);
     }
 
-    private static boolean isValidUriStr(String uri) {
+    private static boolean isValidUriStr(String uriStr) {
         /* uri is not valid if
-         * 1. uri is null
-         * 2. uri is empty
-         * 3. uri doesn't exist in UE
+         * 1. uriStr is null
+         * 2. uriStr is empty
          */
-        return uri != null && !uri.isEmpty() && (new File(uri)).exists();
+        return uriStr != null && !uriStr.isEmpty();
     }
 
     /**
@@ -248,28 +254,54 @@
      * Decodes an image pointed to by uri as per requested Width and requested Height
      * and returns a bitmap
      */
-    public static Bitmap decodeImage(String uri, int reqWidth, int reqHeight) {
-        if (uri == null) {
+    public static Bitmap decodeImage(String uriStr, Context context, int reqWidth, int reqHeight) {
+        if (uriStr == null) {
             return null;
         }
+        ParcelFileDescriptor parcelFileDescriptor = null;
 
-        BitmapFactory.Options options = new BitmapFactory.Options();
-        // Each pixel is stored on 4 bytes
-        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
-        /* If set to true, the decoder will return null (no bitmap),
-           but the out... fields (i.e. outWidth, outHeight and outMimeType)
-           will still be set, allowing the caller to query the bitmap
-           without having to allocate the memory for its pixels */
-        options.inJustDecodeBounds = true;
-        BitmapFactory.decodeFile(uri, options);
+        Uri uri = Uri.parse(uriStr);
 
-        // Calculate inSampleSize
-        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
+        try {
+            parcelFileDescriptor = context.getContentResolver().openFileDescriptor(uri, "r");
+            FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
 
-        // Decode bitmap with inSampleSize set
-        options.inJustDecodeBounds = false;
-        Bitmap bitmap = BitmapFactory.decodeFile(uri, options);
-        return scaleImage(bitmap, reqWidth, reqHeight);
+            BitmapFactory.Options options = new BitmapFactory.Options();
+            // Each pixel is stored on 4 bytes
+            options.inPreferredConfig = Bitmap.Config.ARGB_8888;
+            /* If set to true, the decoder will return null (no bitmap),
+               but the out... fields (i.e. outWidth, outHeight and outMimeType)
+               will still be set, allowing the caller to query the bitmap
+               without having to allocate the memory for its pixels */
+            options.inJustDecodeBounds = true;
+            BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
+
+            // Calculate inSampleSize
+            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
+
+            // Decode bitmap with inSampleSize set
+            options.inJustDecodeBounds = false;
+            Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
+
+            return scaleImage(image, reqWidth, reqHeight);
+        } catch (FileNotFoundException e) {
+            Log.e(LOG_TAG, "File not found for uri: " + uri + " exception : " + e);
+        } catch (IllegalArgumentException e) {
+            Log.e(LOG_TAG, "Check arguments passed to decodeFileDescriptor, exception : " + e);
+        } catch (SecurityException e) {
+            //If the selected static image file located under file path "/sdcard/" is deleted,
+            //SecurityException is thrown by ContentResolver#openFileDescriptor.
+            Log.e(LOG_TAG, "SecurityException, exception : " + e);
+        } finally {
+            try {
+                if (parcelFileDescriptor != null) {
+                    parcelFileDescriptor.close();
+                }
+            } catch (IOException e) {
+                Log.e(LOG_TAG, "Closing parcelFileDescriptor " + " exception : " + e);
+            }
+        }
+        return null;
     }
 
     // scales the image using reqWidth/reqHeight and returns a scaled bitmap
@@ -341,7 +373,7 @@
             throw new QtiImsException("invalid file path");
         }
 
-        Bitmap imageBitmap = decodeImage(uriStr, reqWidth, reqHeight);
+        Bitmap imageBitmap = decodeImage(uriStr, context, reqWidth, reqHeight);
         if (imageBitmap == null) {
             throw new QtiImsException("image decoding error");
         }