1 // Copyright 2013 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.
5 package org.chromium.ui.base;
7 import android.app.Activity;
8 import android.app.PendingIntent;
9 import android.content.ActivityNotFoundException;
10 import android.content.Context;
11 import android.content.Intent;
12 import android.content.IntentSender.SendIntentException;
13 import android.graphics.Bitmap;
14 import android.graphics.Rect;
15 import android.util.Log;
16 import android.view.View;
18 import org.chromium.ui.UiUtils;
20 import java.io.ByteArrayOutputStream;
23 * The class provides the WindowAndroid's implementation which requires
25 * Only instantiate this class when you need the implemented features.
27 public class ActivityWindowAndroid extends WindowAndroid {
28 // Constants used for intent request code bounding.
29 private static final int REQUEST_CODE_PREFIX = 1000;
30 private static final int REQUEST_CODE_RANGE_SIZE = 100;
31 private static final String TAG = "ActivityWindowAndroid";
33 private final Activity mActivity;
34 private int mNextRequestCode = 0;
36 public ActivityWindowAndroid(Activity activity) {
37 super(activity.getApplicationContext());
42 public int showCancelableIntent(PendingIntent intent, IntentCallback callback, int errorId) {
43 int requestCode = generateNextRequestCode();
46 mActivity.startIntentSenderForResult(
47 intent.getIntentSender(), requestCode, new Intent(), 0, 0, 0);
48 } catch (SendIntentException e) {
49 return START_INTENT_FAILURE;
52 storeCallbackData(requestCode, callback, errorId);
57 public int showCancelableIntent(Intent intent, IntentCallback callback, int errorId) {
58 int requestCode = generateNextRequestCode();
61 mActivity.startActivityForResult(intent, requestCode);
62 } catch (ActivityNotFoundException e) {
63 return START_INTENT_FAILURE;
66 storeCallbackData(requestCode, callback, errorId);
71 public void cancelIntent(int requestCode) {
72 mActivity.finishActivity(requestCode);
76 public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
77 IntentCallback callback = mOutstandingIntents.get(requestCode);
78 mOutstandingIntents.delete(requestCode);
79 String errorMessage = mIntentErrors.remove(requestCode);
81 if (callback != null) {
82 callback.onIntentCompleted(this, resultCode,
83 mApplicationContext.getContentResolver(), data);
86 if (errorMessage != null) {
87 showCallbackNonExistentError(errorMessage);
96 public Context getContext() {
101 * Returns a PNG-encoded screenshot of the the window region at (|windowX|,
102 * |windowY|) with the size |width| by |height| pixels.
105 public byte[] grabSnapshot(int windowX, int windowY, int width, int height) {
107 // Take a screenshot of the root activity view. This generally includes UI
108 // controls such as the URL bar and OS windows such as the status bar.
109 View rootView = mActivity.findViewById(android.R.id.content).getRootView();
110 Bitmap bitmap = UiUtils.generateScaledScreenshot(rootView, 0, Bitmap.Config.ARGB_8888);
111 if (bitmap == null) return null;
113 // Clip the result into the requested region.
114 if (windowX > 0 || windowY > 0 || width != bitmap.getWidth() ||
115 height != bitmap.getHeight()) {
116 Rect clip = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
117 clip.intersect(windowX, windowY, windowX + width, windowY + height);
118 bitmap = Bitmap.createBitmap(
119 bitmap, clip.left, clip.top, clip.width(), clip.height());
122 // Compress the result into a PNG.
123 ByteArrayOutputStream result = new ByteArrayOutputStream();
124 if (!bitmap.compress(Bitmap.CompressFormat.PNG, 100, result)) return null;
126 return result.toByteArray();
127 } catch (OutOfMemoryError e) {
128 Log.e(TAG, "Out of memory while grabbing window snapshot.", e);
133 private int generateNextRequestCode() {
134 int requestCode = REQUEST_CODE_PREFIX + mNextRequestCode;
135 mNextRequestCode = (mNextRequestCode + 1) % REQUEST_CODE_RANGE_SIZE;
139 private void storeCallbackData(int requestCode, IntentCallback callback, int errorId) {
140 mOutstandingIntents.put(requestCode, callback);
141 mIntentErrors.put(requestCode, mApplicationContext.getString(errorId));