/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.producers;

import android.content.ContentResolver;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import com.facebook.common.memory.PooledByteBufferFactory;
import com.facebook.common.util.UriUtil;
import com.facebook.imagepipeline.image.EncodedImage;
import com.facebook.imagepipeline.request.ImageRequest;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.Executor;
import javax.annotation.Nullable;

/**
 * Represents a local content Uri fetch producer.
 */
public class LocalContentUriFetchProducer extends LocalFetchProducer {

  public static final String PRODUCER_NAME = "LocalContentUriFetchProducer";

  private static final String[] PROJECTION = new String[] {
      MediaStore.Images.Media._ID,
      MediaStore.Images.ImageColumns.DATA
  };

  private final ContentResolver mContentResolver;

  public LocalContentUriFetchProducer(
      Executor executor,
      PooledByteBufferFactory pooledByteBufferFactory,
      ContentResolver contentResolver) {
    super(executor, pooledByteBufferFactory);
    mContentResolver = contentResolver;
  }

  @Override
  protected EncodedImage getEncodedImage(ImageRequest imageRequest) throws IOException {
    Uri uri = imageRequest.getSourceUri();
    if (UriUtil.isLocalContactUri(uri)) {
      final InputStream inputStream;
      if (uri.toString().endsWith("/photo")) {
        inputStream =  mContentResolver.openInputStream(uri);
      } else if (uri.toString().endsWith("/display_photo")) {
        try {
          AssetFileDescriptor fd = mContentResolver.openAssetFileDescriptor(uri, "r");
          inputStream = fd.createInputStream();
        } catch (IOException e) {
          throw new IOException("Contact photo does not exist: " + uri);
        }
      } else {
        inputStream = ContactsContract.Contacts.openContactPhotoInputStream(mContentResolver, uri);
        if (inputStream == null) {
          throw new IOException("Contact photo does not exist: " + uri);
        }
      }
      // If a Contact URI is provided, use the special helper to open that contact's photo.
      return getEncodedImage(
          inputStream,
          EncodedImage.UNKNOWN_STREAM_SIZE);
    }

    if (UriUtil.isLocalCameraUri(uri)) {
      EncodedImage cameraImage = getCameraImage(uri);
      if (cameraImage != null) {
        return cameraImage;
      }
    }

    return getEncodedImage(
        mContentResolver.openInputStream(uri),
        EncodedImage.UNKNOWN_STREAM_SIZE);
  }

  private @Nullable EncodedImage getCameraImage(Uri uri) throws IOException {
    Cursor cursor = mContentResolver.query(uri, PROJECTION, null, null, null);
    if (cursor == null) {
      return null;
    }
    try {
      if (cursor.getCount() == 0) {
        return null;
      }
      cursor.moveToFirst();
      final String pathname =
          cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA));
      if (pathname != null) {
        return getEncodedImage(new FileInputStream(pathname), getLength(pathname));
      }
    } finally {
      cursor.close();
    }
    return null;
  }

  private static int getLength(String pathname) {
    return pathname == null ? -1 : (int) new File(pathname).length();
  }

  @Override
  protected String getProducerName() {
    return PRODUCER_NAME;
  }
}

@@ -373,16 +373,56 @@
 et.Uri;%0A
+import android.os.ParcelFileDescriptor;%0A
 import a
@@ -722,16 +722,47 @@
 o.File;%0A
+import java.io.FileDescriptor;%0A
 import j
@@ -1184,24 +1184,28 @@
 g%5B%5D %7B%0A      
+    
 MediaStore.I
@@ -1221,16 +1221,20 @@
 ia._ID,%0A
+    
       Me
@@ -1369,16 +1369,20 @@
 (%0A      
+    
 Executor
@@ -1392,16 +1392,20 @@
 ecutor,%0A
+    
       Po
@@ -1451,16 +1451,20 @@
 actory,%0A
+    
       Co
@@ -2612,32 +2612,36 @@
 mage(%0A          
+    
 inputStream,%0A   
@@ -2637,16 +2637,20 @@
 Stream,%0A
+    
         
@@ -2896,24 +2896,28 @@
 ge(%0A        
+    
 mContentReso
@@ -2943,16 +2943,20 @@
 m(uri),%0A
+    
         
@@ -3342,24 +3342,28 @@
 =%0A          
+    
 cursor.getSt
@@ -3450,32 +3450,201 @@
 name != null) %7B%0A
+        ParcelFileDescriptor parcelFileDescriptor = mContentResolver.openFileDescriptor(uri, %22r%22);%0A        FileDescriptor fd = parcelFileDescriptor.getFileDescriptor();%0A
         return g
@@ -3678,24 +3678,18 @@
 tStream(
-pathname
+fd
 ), getLe

use ContentResolver.openFileDescriptor() to open Camera Image (#2380)