1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)package org.chromium.ui.base;
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import android.annotation.SuppressLint;
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import android.app.Activity;
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import android.app.PendingIntent;
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.content.ContentResolver;
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.content.Context;
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.Intent;
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.os.Bundle;
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import android.util.Log;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.util.SparseArray;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.widget.Toast;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import org.chromium.base.CalledByNative;
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import org.chromium.base.JNINamespace;
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuimport org.chromium.ui.VSyncMonitor;
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import java.lang.ref.WeakReference;
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)import java.util.HashMap;
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * The window base class that has the minimum functionality.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)@JNINamespace("ui")
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)public class WindowAndroid {
30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    private static final String TAG = "WindowAndroid";
31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Native pointer to the c++ WindowAndroid object.
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    private long mNativeWindowAndroid = 0;
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    private final VSyncMonitor mVSyncMonitor;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A string used as a key to store intent errors in a bundle
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static final String WINDOW_CALLBACK_ERRORS = "window_callback_errors";
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Error code returned when an Intent fails to start an Activity.
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    public static final int START_INTENT_FAILURE = -1;
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    protected Context mApplicationContext;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    protected SparseArray<IntentCallback> mOutstandingIntents;
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Ideally, this would be a SparseArray<String>, but there's no easy way to store a
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // SparseArray<String> in a bundle during saveInstanceState(). So we use a HashMap and suppress
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // the Android lint warning "UseSparseArrays".
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    protected HashMap<Integer, String> mIntentErrors;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    private final VSyncMonitor.Listener mVSyncListener = new VSyncMonitor.Listener() {
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        @Override
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        public void onVSync(VSyncMonitor monitor, long vsyncTimeMicros) {
535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            if (mNativeWindowAndroid != 0) {
545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                nativeOnVSync(mNativeWindowAndroid, vsyncTimeMicros);
555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            }
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        }
575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    };
585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     * @return true if onVSync handler is executing.
6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     * @see org.chromium.ui.VSyncMonitor#isInsideVSync().
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     */
6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    public boolean isInsideVSync() {
6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        return mVSyncMonitor.isInsideVSync();
6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    /**
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)     * @param context The application context.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    @SuppressLint("UseSparseArrays")
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    public WindowAndroid(Context context) {
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        assert context == context.getApplicationContext();
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mApplicationContext = context;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mOutstandingIntents = new SparseArray<IntentCallback>();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mIntentErrors = new HashMap<Integer, String>();
765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        mVSyncMonitor = new VSyncMonitor(context, mVSyncListener);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Shows an intent and returns the results to the callback object.
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * @param intent   The PendingIntent that needs to be shown.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param callback The object that will receive the results for the intent.
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * @param errorId  The ID of error string to be show if activity is paused before intent
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     *                 results.
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * @return Whether the intent was shown.
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     */
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    public boolean showIntent(PendingIntent intent, IntentCallback callback, int errorId) {
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return showCancelableIntent(intent, callback, errorId) >= 0;
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    /**
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * Shows an intent and returns the results to the callback object.
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * @param intent   The intent that needs to be shown.
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * @param callback The object that will receive the results for the intent.
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * @param errorId  The ID of error string to be show if activity is paused before intent
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     *                 results.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @return Whether the intent was shown.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
99bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    public boolean showIntent(Intent intent, IntentCallback callback, int errorId) {
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return showCancelableIntent(intent, callback, errorId) >= 0;
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    /**
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * Shows an intent that could be canceled and returns the results to the callback object.
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * @param  intent   The PendingIntent that needs to be shown.
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * @param  callback The object that will receive the results for the intent.
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * @param  errorId  The ID of error string to be show if activity is paused before intent
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     *                  results.
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * @return A non-negative request code that could be used for finishActivity, or
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     *         START_INTENT_FAILURE if failed.
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     */
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    public int showCancelableIntent(PendingIntent intent, IntentCallback callback, int errorId) {
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        Log.d(TAG, "Can't show intent as context is not an Activity: " + intent);
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return START_INTENT_FAILURE;
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    /**
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * Shows an intent that could be canceled and returns the results to the callback object.
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * @param  intent   The intent that needs to be showed.
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * @param  callback The object that will receive the results for the intent.
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * @param  errorId  The ID of error string to be show if activity is paused before intent
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     *                  results.
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * @return A non-negative request code that could be used for finishActivity, or
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     *         START_INTENT_FAILURE if failed.
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     */
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    public int showCancelableIntent(Intent intent, IntentCallback callback, int errorId) {
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        Log.d(TAG, "Can't show intent as context is not an Activity: " + intent);
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return START_INTENT_FAILURE;
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    /**
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * Force finish another activity that you had previously started with showCancelableIntent.
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     * @param requestCode The request code returned from showCancelableIntent.
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     */
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    public void cancelIntent(int requestCode) {
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        Log.d(TAG, "Can't cancel intent as context is not an Activity: " + requestCode);
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    /**
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * Removes a callback from the list of pending intents, so that nothing happens if/when the
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * result for that intent is received.
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * @param callback The object that should have received the results
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * @return True if the callback was removed, false if it was not found.
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    */
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    public boolean removeIntentCallback(IntentCallback callback) {
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        int requestCode = mOutstandingIntents.indexOfValue(callback);
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        if (requestCode < 0) return false;
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mOutstandingIntents.remove(requestCode);
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mIntentErrors.remove(requestCode);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Displays an error message with a provided error message string.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param error The error message string to be displayed.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void showError(String error) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (error != null) {
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            Toast.makeText(mApplicationContext, error, Toast.LENGTH_SHORT).show();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
164558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch     * Displays an error message from the given resource id.
165558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch     * @param resId The error message string's resource id.
166558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch     */
167558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    public void showError(int resId) {
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        showError(mApplicationContext.getString(resId));
169558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
170558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
171558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    /**
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Displays an error message for a nonexistent callback.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param error The error message string to be displayed.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    protected void showCallbackNonExistentError(String error) {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        showError(error);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Broadcasts the given intent to all interested BroadcastReceivers.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void sendBroadcast(Intent intent) {
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mApplicationContext.sendBroadcast(intent);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)     * @return A reference to owning Activity.  The returned WeakReference will never be null, but
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)     *         the contained Activity can be null (either if it has been garbage collected or if
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)     *         this is in the context of a WebView that was not created using an Activity).
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    public WeakReference<Activity> getActivity() {
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        return new WeakReference<Activity>(null);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)     * @return The application context for this activity.
197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)     */
198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    public Context getApplicationContext() {
199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        return mApplicationContext;
200424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    /**
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Saves the error messages that should be shown if any pending intents would return
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * after the application has been put onPause.
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param bundle The bundle to save the information in onPause
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void saveInstanceState(Bundle bundle) {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bundle.putSerializable(WINDOW_CALLBACK_ERRORS, mIntentErrors);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Restores the error messages that should be shown if any pending intents would return
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * after the application has been put onPause.
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param bundle The bundle to restore the information from onResume
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void restoreInstanceState(Bundle bundle) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (bundle == null) return;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Object errors = bundle.getSerializable(WINDOW_CALLBACK_ERRORS);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (errors instanceof HashMap) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            @SuppressWarnings("unchecked")
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            HashMap<Integer, String> intentErrors = (HashMap<Integer, String>) errors;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mIntentErrors = intentErrors;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Responds to the intent result if the intent was created by the native window.
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param requestCode Request code of the requested intent.
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param resultCode Result code of the requested intent.
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param data The data returned by the intent.
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @return Boolean value of whether the intent was started by the native window.
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    @CalledByNative
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    private void requestVSyncUpdate() {
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       mVSyncMonitor.requestUpdate();
2415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
2425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    /**
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * An interface that intent callback objects have to implement.
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public interface IntentCallback {
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        /**
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         * Handles the data returned by the requested intent.
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         * @param window A window reference.
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         * @param resultCode Result code of the requested intent.
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         * @param contentResolver An instance of ContentResolver class for accessing returned data.
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         * @param data The data returned by the intent.
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         */
2545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        void onIntentCompleted(WindowAndroid window, int resultCode,
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                ContentResolver contentResolver, Intent data);
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * Tests that an activity is available to handle the passed in intent.
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)     * @param  intent The intent to check.
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * @return True if an activity is available to process this intent when started, meaning that
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     *         Context.startActivity will not throw ActivityNotFoundException.
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     */
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    public boolean canResolveActivity(Intent intent) {
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        return mApplicationContext.getPackageManager().resolveActivity(intent, 0) != null;
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    /**
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Destroys the c++ WindowAndroid object if one has been created.
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public void destroy() {
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeWindowAndroid != 0) {
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            nativeDestroy(mNativeWindowAndroid);
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mNativeWindowAndroid = 0;
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Returns a pointer to the c++ AndroidWindow object and calls the initializer if
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * the object has not been previously initialized.
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @return A pointer to the c++ AndroidWindow.
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    public long getNativePointer() {
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeWindowAndroid == 0) {
2855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            mNativeWindowAndroid = nativeInit(mVSyncMonitor.getVSyncPeriodInMicroseconds());
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return mNativeWindowAndroid;
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    private native long nativeInit(long vsyncPeriod);
2915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    private native void nativeOnVSync(long nativeWindowAndroid, long vsyncTimeMicros);
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    private native void nativeDestroy(long nativeWindowAndroid);
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295