Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.tv.settings.util;
     18 
     19 import android.graphics.Bitmap;
     20 import android.os.Bundle;
     21 import android.os.IBinder;
     22 import android.os.RemoteException;
     23 import android.util.Log;
     24 
     25 import java.lang.reflect.Method;
     26 
     27 // This is a helper class to allow for light-weight transmission of Bitmap data through
     28 // an intent extra.
     29 public class ActivityTransitionBitmapHelper {
     30 
     31     private static final String TAG = "ActivityTransitionBitmapHelper";
     32     private static final String EXTRA_BINDER =
     33             "com.android.tv.settings.util.extra_binder";
     34     private static Method sPutBinder;
     35     private static Method sGetBinder;
     36 
     37     static {
     38         // TODO: switch to not use reflection when everybody is building against the right target
     39         try {
     40             sPutBinder = Bundle.class.getDeclaredMethod("putBinder", String.class, IBinder.class);
     41         } catch (Exception e) {
     42             Log.e(TAG, e.getMessage());
     43         }
     44         try {
     45             sGetBinder = Bundle.class.getDeclaredMethod("getBinder", String.class);
     46         } catch (Exception e) {
     47             Log.e(TAG, e.getMessage());
     48         }
     49     }
     50 
     51     public static Bitmap getBitmapFromBinderBundle(Bundle bundle) {
     52         if (bundle.containsKey(EXTRA_BINDER)) {
     53 
     54             IActivityTransitionBitmapProvider provider = null;
     55             IBinder binder = null;
     56             if (sGetBinder != null) {
     57                 try {
     58                     binder = (IBinder) sGetBinder.invoke(bundle, EXTRA_BINDER);
     59                 } catch (Exception e) {
     60                     Log.e(TAG, e.getMessage());
     61                 }
     62             }
     63 
     64             if (binder != null) {
     65                 provider = IActivityTransitionBitmapProvider.
     66                         Stub.asInterface(binder);
     67             }
     68             if (provider != null) {
     69                 try {
     70                     return provider.getTransitionBitmap();
     71                 } catch (RemoteException e) {
     72                     Log.d(TAG, "The remote process is not accessible, maybe it was killed.", e);
     73                 }
     74             }
     75         }
     76         return null;
     77     }
     78 
     79     public static Bundle bitmapAsBinderBundle(Bitmap bitmap) {
     80         ActivityTransitionBitmapProvider provider = new ActivityTransitionBitmapProvider(bitmap);
     81         Bundle bundle = new Bundle();
     82 
     83         if (sPutBinder != null) {
     84             try {
     85                 sPutBinder.invoke(bundle, EXTRA_BINDER, provider);
     86             } catch (Exception e) {
     87                 Log.e(TAG, "Error invoking binder. ", e);
     88             }
     89         }
     90 
     91         return bundle;
     92     }
     93 
     94     private static class ActivityTransitionBitmapProvider extends
     95             IActivityTransitionBitmapProvider.Stub {
     96         private Bitmap mBitmap;
     97 
     98         public ActivityTransitionBitmapProvider(Bitmap bitmap) {
     99             mBitmap = bitmap;
    100         }
    101 
    102         @Override
    103         public Bitmap getTransitionBitmap() {
    104             Bitmap b = mBitmap;
    105 
    106             // We don't want to hold on to the bitmap object longer than necessary
    107             mBitmap = null;
    108             return b;
    109         }
    110     }
    111 }
    112