@ -21,22 +21,27 @@ import android.database.Cursor;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  android.graphics.Bitmap ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  android.graphics.BitmapFactory ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  android.net.Uri ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  android.os. AsyncTask ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  android.os. Process ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  android.provider.ContactsContract ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  android.provider.ContactsContract.Contacts ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  android.provider.ContactsContract.PhoneLookup ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  android.util.Log ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  org.thoughtcrime.securesms.util.LRUCache ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  org.thoughtcrime.securesms.util.ListenableFutureTask ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  org.thoughtcrime.securesms.util.Util ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  java.io.InputStream ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  java.util.Collections ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  java.util.Map ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  java.util.concurrent.Callable ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import  java.util.concurrent.ExecutorService ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				public  class  RecipientProvider  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  private  static  final  Map < String , Recipient >  recipientCache    =  Collections . synchronizedMap ( new  LRUCache < String , Recipient > ( 1000 ) ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//  private static final ExecutorService asyncRecipientResolver = Executors.newSingleThreadExecutor();
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  private  static  final  ExecutorService  asyncRecipientResolver  =  Util . newSingleThreadedLifoExecutor ( ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  private  static  final  String [ ]  CALLER_ID_PROJECTION  =  new  String [ ]  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    PhoneLookup . DISPLAY_NAME , 
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -70,70 +75,43 @@ public class RecipientProvider {
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  private  Recipient  getAsynchronousRecipient ( final  Context  context ,  final  String  number )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    Log . w ( "RecipientProvider" ,  "Cache miss [ASYNC]!" ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    Recipient  recipient  =  new  Recipient ( null ,  number ,  null ,  ContactPhotoFactory . getDefaultContactPhoto ( context ) ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    recipientCache . put ( number ,  recipient ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    new  AsyncTask < Recipient ,  Void ,  RecipientDetails > ( )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				      private  Recipient  recipient ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//    Recipient recipient = new Recipient(null, number, null, ContactPhotoFactory.getDefaultContactPhoto(context));
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//    recipientCache.put(number, recipient);
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//    new AsyncTask<Recipient, Void, RecipientDetails>() {
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//      private Recipient recipient;
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//      @Override
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//      protected RecipientDetails doInBackground(Recipient... recipient) {
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//        this.recipient = recipient[0];
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//        return getRecipientDetails(context, number);
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//      }
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//      @Override
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//      protected void onPostExecute(RecipientDetails result) {
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//        recipient.updateAsynchronousContent(result);
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//      }
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//    }.execute(recipient);
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//    return recipient;
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//    ListenableFutureTask<RecipientDetails> future = new ListenableFutureTask<RecipientDetails>(new Callable<RecipientDetails>() {
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    Callable < RecipientDetails >  task  =  new  Callable < RecipientDetails > ( )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				      @Override 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				      protected  RecipientDetails  doInBackground ( Recipient . . .  recipient )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        this . recipient  =  recipient [ 0 ] ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				      p ublic RecipientDetails  call ( )  throws  Exception   { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        Process . setThreadPriority ( Process . THREAD_PRIORITY_BACKGROUND ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        return  getRecipientDetails ( context ,  number ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				      } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    } ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				      @Override 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				      protected  void  onPostExecute ( RecipientDetails  result )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        recipient . updateAsynchronousContent ( result ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				      } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    } . execute ( recipient ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    ListenableFutureTask < RecipientDetails >  future  =  new  ListenableFutureTask < RecipientDetails > ( task ,  null ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    return  recipient ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    asyncRecipientResolver . submit ( future ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//    ListenableFutureTask<RecipientDetails> future =
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//        new ListenableFutureTask<RecipientDetails>(new Callable<RecipientDetails>() {
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//      @Override
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//      public RecipientDetails call() throws Exception {
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//        return getRecipientDetails(context, number);
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////        RecipientDetails recipientDetails = getRecipientDetails();
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////        if (recipientDeta)
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////        Recipient cachedRecipient = recipientCache.get(number);
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////        if (cachedRecipient != null) {
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////          return new RecipientDetails(cachedRecipient.getName(), cachedRecipient.getContactPhoto());
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////        }
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////        Uri uri       = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////        Cursor cursor = context.getContentResolver().query(uri, CALLER_ID_PROJECTION,
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////                                                           null, null, null);
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////        try {
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////          if (cursor != null && cursor.moveToFirst()) {
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////            Uri contactUri      = Contacts.getLookupUri(cursor.getLong(2), cursor.getString(1));
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////            Bitmap contactPhoto = getContactPhoto(context, Uri.withAppendedPath(Contacts.CONTENT_URI,
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////                                                                                cursor.getLong(2)+""));
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////            recipientCache.put(number, new Recipient(cursor.getString(0), number, contactPhoto));
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////            return new RecipientDetails(cursor.getString(0), contactPhoto);
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////          } else {
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////            recipientCache.put(number, new Recipient(null, number, ContactPhotoFactory.getDefaultContactPhoto(context)));
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////          }
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////        } finally {
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////          if (cursor != null)
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////            cursor.close();
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////        }
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////        return null;
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//      }
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//    }, null);
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//    asyncRecipientResolver.submit(future);
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//    Recipient recipient = new Recipient(number, ContactPhotoFactory.getDefaultContactPhoto(context), future);
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//    recipientCache.put(number, recipient);
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				//    return recipient;
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    Recipient  recipient  =  new  Recipient ( number ,  ContactPhotoFactory . getDefaultContactPhoto ( context ) ,  future ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    recipientCache . put ( number ,  recipient ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    return  recipient ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				////    return new Recipient(null, number, ContactPhotoFactory.getDefaultContactPhoto(context));
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  }