1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.content.browser.input; 6 7 import android.content.Context; 8 import android.content.res.Resources; 9 import android.content.res.TypedArray; 10 import android.graphics.Bitmap; 11 import android.graphics.BitmapFactory; 12 import android.graphics.Canvas; 13 import android.graphics.drawable.Drawable; 14 15 import org.chromium.base.CalledByNative; 16 import org.chromium.base.JNINamespace; 17 18 /** 19 * Helper class for retrieving resources related to selection handles. 20 */ 21 @JNINamespace("content") 22 public class HandleViewResources { 23 private static final int[] LEFT_HANDLE_ATTRS = { 24 android.R.attr.textSelectHandleLeft, 25 }; 26 27 private static final int[] CENTER_HANDLE_ATTRS = { 28 android.R.attr.textSelectHandle, 29 }; 30 31 private static final int[] RIGHT_HANDLE_ATTRS = { 32 android.R.attr.textSelectHandleRight, 33 }; 34 35 public static Drawable getLeftHandleDrawable(Context context) { 36 return getHandleDrawable(context, LEFT_HANDLE_ATTRS); 37 } 38 39 public static Drawable getCenterHandleDrawable(Context context) { 40 return getHandleDrawable(context, CENTER_HANDLE_ATTRS); 41 } 42 43 public static Drawable getRightHandleDrawable(Context context) { 44 return getHandleDrawable(context, RIGHT_HANDLE_ATTRS); 45 } 46 47 private static Drawable getHandleDrawable(Context context, final int[] attrs) { 48 TypedArray a = context.getTheme().obtainStyledAttributes(attrs); 49 Drawable drawable = a.getDrawable(0); 50 if (drawable == null) { 51 // If themed resource lookup fails, fall back to using the Context's 52 // resources for attribute lookup. 53 try { 54 drawable = context.getResources().getDrawable(a.getResourceId(0, 0)); 55 } catch (Resources.NotFoundException e) { 56 // The caller should handle the null return case appropriately. 57 } 58 } 59 a.recycle(); 60 return drawable; 61 } 62 63 private static Bitmap getHandleBitmap(Context context, final int[] attrs) { 64 // TODO(jdduke): Properly derive and apply theme color. 65 TypedArray a = context.getTheme().obtainStyledAttributes(attrs); 66 final int resId = a.getResourceId(a.getIndex(0), 0); 67 final Resources res = a.getResources(); 68 a.recycle(); 69 70 final Bitmap.Config config = Bitmap.Config.ARGB_8888; 71 final BitmapFactory.Options options = new BitmapFactory.Options(); 72 options.inJustDecodeBounds = false; 73 options.inPreferredConfig = config; 74 Bitmap bitmap = BitmapFactory.decodeResource(res, resId, options); 75 if (bitmap != null) return bitmap; 76 77 // If themed resource lookup fails, fall back to using the Context's 78 // resources for attribute lookup. 79 if (res != context.getResources()) { 80 bitmap = BitmapFactory.decodeResource(context.getResources(), resId, options); 81 if (bitmap != null) return bitmap; 82 } 83 84 Drawable drawable = getHandleDrawable(context, attrs); 85 assert drawable != null; 86 87 final int width = drawable.getIntrinsicWidth(); 88 final int height = drawable.getIntrinsicHeight(); 89 Bitmap canvasBitmap = Bitmap.createBitmap(width, height, config); 90 Canvas canvas = new Canvas(canvasBitmap); 91 drawable.setBounds(0, 0, width, height); 92 drawable.draw(canvas); 93 return canvasBitmap; 94 } 95 96 @CalledByNative 97 private static Bitmap getLeftHandleBitmap(Context context) { 98 return getHandleBitmap(context, LEFT_HANDLE_ATTRS); 99 } 100 101 @CalledByNative 102 private static Bitmap getCenterHandleBitmap(Context context) { 103 return getHandleBitmap(context, CENTER_HANDLE_ATTRS); 104 } 105 106 @CalledByNative 107 private static Bitmap getRightHandleBitmap(Context context) { 108 return getHandleBitmap(context, RIGHT_HANDLE_ATTRS); 109 } 110 } 111