Delete browserplugin sample. do not merge

It doesn't build in all environments.

Change-Id: I96fbb28e1bea44656ff6cfb9002eedfd5471612e
This commit is contained in:
Jean-Baptiste Queru
2011-01-27 13:35:23 -08:00
parent 2d81c413c7
commit c8fd87e476
35 changed files with 0 additions and 4586 deletions

View File

@@ -1,38 +0,0 @@
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
TOP_LOCAL_PATH:= $(call my-dir)
# Build application
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PROGUARD_ENABLED := disabled
LOCAL_PACKAGE_NAME := SampleBrowserPlugin
LOCAL_JNI_SHARED_LIBRARIES := libsampleplugin
include $(BUILD_PACKAGE)
# ============================================================
# Also build all of the sub-targets under this one: the shared library.
include $(call all-makefiles-under,$(LOCAL_PATH))

View File

@@ -1,36 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.sampleplugin"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.webkit.permission.PLUGIN"/>
<uses-sdk android:minSdkVersion="3" />
<application android:icon="@drawable/sample_browser_plugin"
android:label="@string/sample_browser_plugin">
<service android:name=".SamplePlugin">
<intent-filter>
<action android:name="android.webkit.PLUGIN" />
</intent-filter>
<meta-data android:name="type" android:value="native" />
</service>
</application>
</manifest>

View File

@@ -1,190 +0,0 @@
Copyright (c) 2005-2008, The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

View File

@@ -1,177 +0,0 @@
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################
######### CONTENTS ###########
A. INTRODUCTION
B. PLUGIN STRUCTURE
C. HOW TO DEPLOY
D. SUB-PLUGINS
1. ANIMATION
2. AUDIO
3. BACKGROUND
4. FORM
5. PAINT
##############################
## (A) INTRODUCTION ##########
The sample plugin is intended to give plugin developers a point of reference to
see how an android browser plugin is created and how to use the available APIs.
A plugin is packaged like a standard apk and can be installed either via the
market or adb. The sample plugin attempts to exercise as many of the APIs as
possible but unfortunately not all are covered.
Trying to have a single plugin demonstrate all possible API interactions on one
screen was not practical. On the other hand we also didn't want a separate
plugin for each interction, as that would result in many separate apk's that
would need to be maintained. To solve this problem we developed the idea to use
"sub-plugins". With a sub-plugin only one specific feature of the plugin would
be active at a time, but they would all share as much common code as possible.
A detailed description of each sub-plugin and its function can be found in the
sub-plugins section.
##############################
## (B) PLUGIN STRUCTURE ######
The sample plugin is packaged as one plugin but contains many unique sub-plugins
(e.g. audio and paint). The package consists of two pieces: (1) Java code
containing the config; (2) C++ shared library containing the brower/plugin
bindings and the sub-plugin classes.
~~~~ (1) JAVA ~~~~~
Android.mk: specifies the name of the APK (SampleBrowserPlugin) as well as which
shared libraries to include.
AndroidManifest.xml: similar to a standard android manifest file, except that it
must contain the "uses-permission" and "service"
elements that are plugin specific. The "service" element
contains sub-elements that describe the java component of
the service.
src/*: location of the java source files. This contains the SamplePlugin.class
which is the java component of our plugin. The component must exist and
implement the required interfaces, though simply returning null is valid.
res/*: location of the static resources (e.g. an icon for the plugin)
~~~~ (2) C++ ~~~~~
jni/Android.mk: specifies the build parameters for the shared library that is to
be included with the apk. The library contains all the bindings
between the plugin and the browser.
jni/main.*: this code is the binding point between the plugin and the browser.
It supports all of the functions required for a standard netscape
style plugin as well as all the android specific APIs. The initial
starting point for the plugin is the NP_Initialize function. The
NPP_New function is responsible for reading the input args and
selecting the appropriate sub-plugin to instantiate. Most other
functions either return fixed values or pass their inputs to the
sub-plugin for processing.
jni/PluginObject.*: The pluginObject provides a convenient container in which to
store variables (the plugin's state). This objects two main
responsibilities are (1) to construct and store the NPClass
object (done using code provided by Apple) and (2) provide
the abstract class for the sub-plugin objects and a place to
store the sub-plugin after it is instantiated.
jni/*/*: Each of the sub-plugins has a folder that contains its class definition
and logic. The sub-plugin receives events from the browser and it can
also communicate with the browser using the netscape plugin functions
as well as the specialized android interfaces.
##############################
## (C) HOW TO DEPLOY #########
To compile and install a plugin on a device/emulator simply...
1. run "make SampleBrowserPlugin" (compiles libsampleplugin.so and builds the apk)
2. the previous command produces an apk file so record its location
3. run "adb install [apk_file]" to install it on a device/emulator
4. the browser will auto recognize the plugin is available
Now that the plugin is installed you can manage it just like you would any other
application via Settings -> Applications -> Manage applications. To execute the
plugin you need to include an html snippet (similar to the one found below) in
a document that is accessible by the browser. The mime-type cannot change but
you can change the width, height, and parameters. The parameters are used to
notify the plugin which sub-plugin to execute and which drawing model to use.
<object type="application/x-testbrowserplugin" height=50 width=250>
<param name="DrawingModel" value="Surface" />
<param name="PluginType" value="Background" />
</object>
##############################
## (D) SUB-PLUGINS ###########
Each sub-plugin corresponds to exactly one plugin type and can support one or
more drawing models. In the subsections below there are descriptions of each of
the sub-plugins as well as the information required to create the html snippets.
#######################
## (D1) ANIMATION #####
PLUGIN TYPE: Animation
DRAWING MODEL: Bitmap
This plugin draws a ball bouncing around the screen. If the plugin is not entirely
on the screen and it it touched, then it will attempt to center itself on screen.
#######################
## (D2) AUDIO #########
PLUGIN TYPE: Audio
DRAWING MODEL: Bitmap
This plugin plays a raw audio file located at /sdcard/sample.raw (need to supply
your own). It uses touch to trigger the play, pause, and stop buttons.
#######################
## (D3) BACKGROUND ####
PLUGIN TYPE: Background
DRAWING MODEL: Surface
This plugin has minimal visual components but mainly runs API tests in the
background. The plugin handles scaling its own bitmap on zoom which in this
case is a simple string of text. The output of this plugin is found in the logs
as it prints errors if it detects any API failures. Some of the API's tested are
timers, javascript access, and bitmap formatting.
#######################
## (D4) FORM ##########
PLUGIN TYPE: Form
DRAWING MODEL: Bitmap
This plugin mimics a simple username/password form. You can select a textbox by
either touching it or using the navigation keys. Once selected the box will
highlight and the keyboard will appear. If the textbox selected is not fully
in view then the plugin will ensure it is centered on the screen.
#######################
## (D5) PAINT #########
PLUGIN TYPE: Paint
DRAWING MODEL: Surface
This plugin provides a surface that the user can "paint" on. The inputs method
can be toggled between mouse (dots) and touch (lines). This plugin has a fixed
surface and allows the browser to scale the surface when zooming.

View File

@@ -1,68 +0,0 @@
##
##
## Copyright 2008, The Android Open Source Project
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions
## are met:
## * Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## * Redistributions in binary form must reproduce the above copyright
## notice, this list of conditions and the following disclaimer in the
## documentation and/or other materials provided with the distribution.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
main.cpp \
PluginObject.cpp \
animation/AnimationPlugin.cpp \
audio/AudioPlugin.cpp \
background/BackgroundPlugin.cpp \
form/FormPlugin.cpp \
navigation/NavigationPlugin.cpp \
paint/PaintPlugin.cpp \
video/VideoPlugin.cpp \
jni-bridge.cpp \
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
$(LOCAL_PATH) \
$(LOCAL_PATH)/animation \
$(LOCAL_PATH)/audio \
$(LOCAL_PATH)/background \
$(LOCAL_PATH)/form \
$(LOCAL_PATH)/navigation \
$(LOCAL_PATH)/paint \
$(LOCAL_PATH)/video \
external/webkit/WebCore/bridge \
external/webkit/WebCore/plugins \
external/webkit/WebCore/platform/android/JavaVM \
external/webkit/WebKit/android/plugins
LOCAL_SHARED_LIBRARIES := \
libnativehelper
LOCAL_CFLAGS += -fvisibility=hidden
LOCAL_PRELINK_MODULE:=false
LOCAL_MODULE:= libsampleplugin
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)

View File

@@ -1,211 +0,0 @@
/*
IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in
consideration of your agreement to the following terms, and your use, installation,
modification or redistribution of this Apple software constitutes acceptance of these
terms. If you do not agree with these terms, please do not use, install, modify or
redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject to these
terms, Apple grants you a personal, non-exclusive license, under AppleÕs copyrights in
this original Apple software (the "Apple Software"), to use, reproduce, modify and
redistribute the Apple Software, with or without modifications, in source and/or binary
forms; provided that if you redistribute the Apple Software in its entirety and without
modifications, you must retain this notice and the following text and disclaimers in all
such redistributions of the Apple Software. Neither the name, trademarks, service marks
or logos of Apple Computer, Inc. may be used to endorse or promote products derived from
the Apple Software without specific prior written permission from Apple. Except as expressly
stated in this notice, no other rights or licenses, express or implied, are granted by Apple
herein, including but not limited to any patent rights that may be infringed by your
derivative works or by other works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES,
EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS
USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND
WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "main.h"
#include "PluginObject.h"
int SubPlugin::getPluginWidth() {
PluginObject *obj = (PluginObject*) inst()->pdata;
return obj->window->width;
}
int SubPlugin::getPluginHeight() {
PluginObject *obj = (PluginObject*) inst()->pdata;
return obj->window->height;
}
bool SurfaceSubPlugin::supportsDrawingModel(ANPDrawingModel model) {
return (model == kSurface_ANPDrawingModel);
}
void SurfaceSubPlugin::setContext(jobject context) {
JNIEnv* env = NULL;
if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
// if one exists then free its global reference
if (m_context) {
env->DeleteGlobalRef(m_context);
m_context = NULL;
}
// create a new global ref
if (context) {
context = env->NewGlobalRef(context);
}
// set the value
m_context = context;
}
}
static void pluginInvalidate(NPObject *obj);
static bool pluginHasProperty(NPObject *obj, NPIdentifier name);
static bool pluginHasMethod(NPObject *obj, NPIdentifier name);
static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant);
static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant);
static bool pluginInvoke(NPObject *obj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result);
static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
static NPObject *pluginAllocate(NPP npp, NPClass *theClass);
static void pluginDeallocate(NPObject *obj);
static bool pluginRemoveProperty(NPObject *npobj, NPIdentifier name);
static bool pluginEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count);
static NPClass pluginClass = {
NP_CLASS_STRUCT_VERSION,
pluginAllocate,
pluginDeallocate,
pluginInvalidate,
pluginHasMethod,
pluginInvoke,
pluginInvokeDefault,
pluginHasProperty,
pluginGetProperty,
pluginSetProperty,
pluginRemoveProperty,
pluginEnumerate
};
NPClass *getPluginClass(void)
{
return &pluginClass;
}
static bool identifiersInitialized = false;
#define ID_TESTFILE_PROPERTY 0
#define NUM_PROPERTY_IDENTIFIERS 1
static NPIdentifier pluginPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS];
static const NPUTF8 *pluginPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = {
"testfile"
};
#define ID_GETTESTFILE_METHOD 0
#define NUM_METHOD_IDENTIFIERS 1
static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
"getTestFile"
};
static void initializeIdentifiers(void)
{
browser->getstringidentifiers(pluginPropertyIdentifierNames, NUM_PROPERTY_IDENTIFIERS, pluginPropertyIdentifiers);
browser->getstringidentifiers(pluginMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, pluginMethodIdentifiers);
}
static bool pluginHasProperty(NPObject *obj, NPIdentifier name)
{
int i;
for (i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++)
if (name == pluginPropertyIdentifiers[i])
return true;
return false;
}
static bool pluginHasMethod(NPObject *obj, NPIdentifier name)
{
int i;
for (i = 0; i < NUM_METHOD_IDENTIFIERS; i++)
if (name == pluginMethodIdentifiers[i])
return true;
return false;
}
static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant)
{
PluginObject *plugin = (PluginObject *)obj;
if (name == pluginPropertyIdentifiers[ID_TESTFILE_PROPERTY]) {
BOOLEAN_TO_NPVARIANT(true, *variant);
return true;
}
return false;
}
static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant)
{
return false;
}
static bool pluginInvoke(NPObject *obj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)
{
PluginObject *plugin = (PluginObject *)obj;
if (name == pluginMethodIdentifiers[ID_GETTESTFILE_METHOD]) {
return true;
}
return false;
}
static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result)
{
return false;
}
static void pluginInvalidate(NPObject *obj)
{
// Release any remaining references to JavaScript objects.
}
static NPObject *pluginAllocate(NPP npp, NPClass *theClass)
{
PluginObject *newInstance = (PluginObject*) malloc(sizeof(PluginObject));
newInstance->header._class = theClass;
newInstance->header.referenceCount = 1;
if (!identifiersInitialized) {
identifiersInitialized = true;
initializeIdentifiers();
}
newInstance->npp = npp;
return &newInstance->header;
}
static void pluginDeallocate(NPObject *obj)
{
free(obj);
}
static bool pluginRemoveProperty(NPObject *npobj, NPIdentifier name)
{
return false;
}
static bool pluginEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
{
return false;
}

View File

@@ -1,99 +0,0 @@
/*
IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in
consideration of your agreement to the following terms, and your use, installation,
modification or redistribution of this Apple software constitutes acceptance of these
terms. If you do not agree with these terms, please do not use, install, modify or
redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject to these
terms, Apple grants you a personal, non-exclusive license, under Apple<6C>s copyrights in
this original Apple software (the "Apple Software"), to use, reproduce, modify and
redistribute the Apple Software, with or without modifications, in source and/or binary
forms; provided that if you redistribute the Apple Software in its entirety and without
modifications, you must retain this notice and the following text and disclaimers in all
such redistributions of the Apple Software. Neither the name, trademarks, service marks
or logos of Apple Computer, Inc. may be used to endorse or promote products derived from
the Apple Software without specific prior written permission from Apple. Except as expressly
stated in this notice, no other rights or licenses, express or implied, are granted by Apple
herein, including but not limited to any patent rights that may be infringed by your
derivative works or by other works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES,
EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS
USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND
WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PluginObject__DEFINED
#define PluginObject__DEFINED
#include "main.h"
#include <jni.h>
enum CustomEventTypes {
kSurfaceCreated_CustomEvent = 0,
kSurfaceChanged_CustomEvent = 1,
kSurfaceDestroyed_CustomEvent = 2,
};
typedef int32_t CustomEventType;
class SubPlugin {
public:
SubPlugin(NPP inst) : m_inst(inst) {}
virtual ~SubPlugin() {}
virtual int16 handleEvent(const ANPEvent* evt) = 0;
virtual bool supportsDrawingModel(ANPDrawingModel) = 0;
int getPluginWidth();
int getPluginHeight();
NPP inst() const { return m_inst; }
private:
NPP m_inst;
};
class SurfaceSubPlugin : public SubPlugin {
public:
SurfaceSubPlugin(NPP inst) : SubPlugin(inst) { m_context = NULL; }
virtual ~SurfaceSubPlugin() {}
virtual jobject getSurface() = 0;
virtual bool supportsDrawingModel(ANPDrawingModel);
void setContext(jobject context);
jobject m_context;
};
enum PluginTypes {
kAnimation_PluginType = 1,
kAudio_PluginType = 2,
kBackground_PluginType = 3,
kForm_PluginType = 4,
kText_PluginType = 5,
kPaint_PluginType = 6,
kVideo_PluginType = 7,
kNavigation_PluginType = 8,
};
typedef uint32_t PluginType;
typedef struct PluginObject {
NPObject header;
NPP npp;
NPWindow* window;
PluginType pluginType;
SubPlugin* activePlugin;
} PluginObject;
NPClass *getPluginClass(void);
#endif // PluginObject__DEFINED

View File

@@ -1,197 +0,0 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "AnimationPlugin.h"
#include <math.h>
#include <string.h>
extern NPNetscapeFuncs* browser;
extern ANPLogInterfaceV0 gLogI;
extern ANPCanvasInterfaceV0 gCanvasI;
extern ANPPaintInterfaceV0 gPaintI;
extern ANPPathInterfaceV0 gPathI;
extern ANPWindowInterfaceV0 gWindowI;
static uint16 rnd16(float x, int inset) {
int ix = (int)roundf(x) + inset;
if (ix < 0) {
ix = 0;
}
return static_cast<uint16>(ix);
}
static void inval(NPP instance, const ANPRectF& r, bool doAA) {
const int inset = doAA ? -1 : 0;
NPRect inval;
inval.left = rnd16(r.left, inset);
inval.top = rnd16(r.top, inset);
inval.right = rnd16(r.right, -inset);
inval.bottom = rnd16(r.bottom, -inset);
browser->invalidaterect(instance, &inval);
}
static void bounce(float* x, float* dx, const float max) {
*x += *dx;
if (*x < 0) {
*x = 0;
if (*dx < 0) {
*dx = -*dx;
}
} else if (*x > max) {
*x = max;
if (*dx > 0) {
*dx = -*dx;
}
}
}
///////////////////////////////////////////////////////////////////////////////
BallAnimation::BallAnimation(NPP inst) : SubPlugin(inst) {
m_x = m_y = 0;
m_dx = 7 * SCALE;
m_dy = 5 * SCALE;
memset(&m_oval, 0, sizeof(m_oval));
m_paint = gPaintI.newPaint();
gPaintI.setFlags(m_paint, gPaintI.getFlags(m_paint) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(m_paint, 0xFFFF0000);
//register for touch events
ANPEventFlags flags = kTouch_ANPEventFlag;
NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
if (err != NPERR_NO_ERROR) {
gLogI.log(kError_ANPLogType, "Error selecting input events.");
}
}
BallAnimation::~BallAnimation() {
gPaintI.deletePaint(m_paint);
}
bool BallAnimation::supportsDrawingModel(ANPDrawingModel model) {
return (model == kBitmap_ANPDrawingModel);
}
void BallAnimation::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
// create a canvas
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
// clip the canvas
ANPRectF clipR;
clipR.left = clip.left;
clipR.top = clip.top;
clipR.right = clip.right;
clipR.bottom = clip.bottom;
gCanvasI.clipRect(canvas, &clipR);
// setup variables
PluginObject *obj = (PluginObject*) inst()->pdata;
const float OW = 20;
const float OH = 20;
const int W = obj->window->width;
const int H = obj->window->height;
// paint the canvas (using the path API)
gCanvasI.drawColor(canvas, 0xFFFFFFFF);
{
ANPPath* path = gPathI.newPath();
float cx = W * 0.5f;
float cy = H * 0.5f;
gPathI.moveTo(path, 0, 0);
gPathI.quadTo(path, cx, cy, W, 0);
gPathI.quadTo(path, cx, cy, W, H);
gPathI.quadTo(path, cx, cy, 0, H);
gPathI.quadTo(path, cx, cy, 0, 0);
gPaintI.setColor(m_paint, 0xFF0000FF);
gCanvasI.drawPath(canvas, path, m_paint);
ANPRectF bounds;
memset(&bounds, 0, sizeof(bounds));
gPathI.getBounds(path, &bounds);
gPathI.deletePath(path);
}
// draw the oval
inval(inst(), m_oval, true); // inval the old
m_oval.left = m_x;
m_oval.top = m_y;
m_oval.right = m_x + OW;
m_oval.bottom = m_y + OH;
inval(inst(), m_oval, true); // inval the new
gPaintI.setColor(m_paint, 0xFFFF0000);
gCanvasI.drawOval(canvas, &m_oval, m_paint);
// update the coordinates of the oval
bounce(&m_x, &m_dx, obj->window->width - OW);
bounce(&m_y, &m_dy, obj->window->height - OH);
// delete the canvas
gCanvasI.deleteCanvas(canvas);
}
void BallAnimation::showEntirePluginOnScreen() {
NPP instance = this->inst();
PluginObject *obj = (PluginObject*) instance->pdata;
NPWindow *window = obj->window;
ANPRectI visibleRects[1];
visibleRects[0].left = 0;
visibleRects[0].top = 0;
visibleRects[0].right = window->width;
visibleRects[0].bottom = window->height;
gWindowI.setVisibleRects(instance, visibleRects, 1);
gWindowI.clearVisibleRects(instance);
}
int16 BallAnimation::handleEvent(const ANPEvent* evt) {
NPP instance = this->inst();
switch (evt->eventType) {
case kDraw_ANPEventType:
switch (evt->data.draw.model) {
case kBitmap_ANPDrawingModel:
drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
return 1;
default:
break; // unknown drawing model
}
case kTouch_ANPEventType:
if (kDown_ANPTouchAction == evt->data.touch.action) {
showEntirePluginOnScreen();
}
return 1;
default:
break;
}
return 0; // unknown or unhandled event
}

View File

@@ -1,52 +0,0 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "PluginObject.h"
#ifndef pluginGraphics__DEFINED
#define pluginGraphics__DEFINED
class BallAnimation : public SubPlugin {
public:
BallAnimation(NPP inst);
virtual ~BallAnimation();
virtual bool supportsDrawingModel(ANPDrawingModel);
virtual int16 handleEvent(const ANPEvent* evt);
private:
void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
void showEntirePluginOnScreen();
float m_x;
float m_y;
float m_dx;
float m_dy;
ANPRectF m_oval;
ANPPaint* m_paint;
static const float SCALE = 0.1;
};
#endif // pluginGraphics__DEFINED

View File

@@ -1,382 +0,0 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "AudioPlugin.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#include <math.h>
#include <string.h>
extern NPNetscapeFuncs* browser;
extern ANPLogInterfaceV0 gLogI;
extern ANPCanvasInterfaceV0 gCanvasI;
extern ANPPaintInterfaceV0 gPaintI;
extern ANPAudioTrackInterfaceV0 gSoundI;
extern ANPTypefaceInterfaceV0 gTypefaceI;
static void inval(NPP instance) {
browser->invalidaterect(instance, NULL);
}
static uint16 rnd16(float x, int inset) {
int ix = (int)roundf(x) + inset;
if (ix < 0) {
ix = 0;
}
return static_cast<uint16>(ix);
}
static void inval(NPP instance, const ANPRectF& r, bool doAA) {
const int inset = doAA ? -1 : 0;
PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
NPRect inval;
inval.left = rnd16(r.left, inset);
inval.top = rnd16(r.top, inset);
inval.right = rnd16(r.right, -inset);
inval.bottom = rnd16(r.bottom, -inset);
browser->invalidaterect(instance, &inval);
}
static void audioCallback(ANPAudioEvent evt, void* user, ANPAudioBuffer* buffer) {
switch (evt) {
case kMoreData_ANPAudioEvent: {
SoundPlay* play = reinterpret_cast<SoundPlay*>(user);
size_t amount = fread(buffer->bufferData, 1, buffer->size, play->file);
buffer->size = amount;
if (amount == 0) {
gSoundI.stop(play->track);
fclose(play->file);
play->file = NULL;
// TODO need to notify our main thread to delete the track now
}
if (play->fileSize > 0) {
// TODO we need to properly update the progress value
play->progress = 1;
inval(play->instance);
}
break;
}
default:
break;
}
}
///////////////////////////////////////////////////////////////////////////////
AudioPlugin::AudioPlugin(NPP inst) : SubPlugin(inst) {
const char path[] = "/sdcard/sample.raw";
// open a file stream
FILE* f = fopen(path, "r");
gLogI.log(kDebug_ANPLogType, "--- path %s FILE %p", path, f);
// setup our private audio struct's default values
m_soundPlay = new SoundPlay;
m_soundPlay->instance = inst;
m_soundPlay->progress = 0;
m_soundPlay->fileSize = 0;
m_soundPlay->file = f;
m_soundPlay->track = NULL;
// create the audio track
if (f) {
m_soundPlay->track = gSoundI.newTrack(44100, kPCM16Bit_ANPSampleFormat, 2, audioCallback, m_soundPlay);
if (!m_soundPlay->track) {
fclose(f);
m_soundPlay->file = NULL;
}
}
// get the audio file's size
int fileDescriptor = open(path, O_RDONLY);
struct stat fileStatus;
if(fileDescriptor <= 0) {
gLogI.log(kError_ANPLogType, "fopen error");
}
else if (fstat(fileDescriptor, &fileStatus) != 0) {
gLogI.log(kDebug_ANPLogType, "File Size: %d", fileStatus.st_size);
m_soundPlay->fileSize = fileStatus.st_size;
} else {
gLogI.log(kError_ANPLogType, "fstat error");
}
// configure the UI elements
m_activeTouch = false;
memset(&m_trackRect, 0, sizeof(m_trackRect));
memset(&m_playRect, 0, sizeof(m_playRect));
memset(&m_pauseRect, 0, sizeof(m_pauseRect));
memset(&m_stopRect, 0, sizeof(m_stopRect));
m_paintTrack = gPaintI.newPaint();
gPaintI.setFlags(m_paintTrack, gPaintI.getFlags(m_paintTrack) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(m_paintTrack, 0xFFC0C0C0);
m_paintRect = gPaintI.newPaint();
gPaintI.setFlags(m_paintRect, gPaintI.getFlags(m_paintRect) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(m_paintRect, 0xFFA8A8A8);
m_paintText = gPaintI.newPaint();
gPaintI.setFlags(m_paintText, gPaintI.getFlags(m_paintText) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(m_paintText, 0xFF2F4F4F);
gPaintI.setTextSize(m_paintText, 18);
m_paintTrackProgress = gPaintI.newPaint();
gPaintI.setFlags(m_paintTrackProgress, gPaintI.getFlags(m_paintTrackProgress) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(m_paintTrackProgress, 0xFF545454);
m_paintActiveRect = gPaintI.newPaint();
gPaintI.setFlags(m_paintActiveRect, gPaintI.getFlags(m_paintActiveRect) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(m_paintActiveRect, 0xFF545454);
ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
gPaintI.setTypeface(m_paintText, tf);
gTypefaceI.unref(tf);
//register for touch events
ANPEventFlags flags = kTouch_ANPEventFlag;
NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
if (err != NPERR_NO_ERROR) {
gLogI.log(kError_ANPLogType, "Error selecting input events.");
}
}
AudioPlugin::~AudioPlugin() {
gPaintI.deletePaint(m_paintTrack);
gPaintI.deletePaint(m_paintRect);
gPaintI.deletePaint(m_paintText);
gPaintI.deletePaint(m_paintTrackProgress);
gPaintI.deletePaint(m_paintActiveRect);
if(m_soundPlay->track)
gSoundI.deleteTrack(m_soundPlay->track);
delete m_soundPlay;
}
bool AudioPlugin::supportsDrawingModel(ANPDrawingModel model) {
return (model == kBitmap_ANPDrawingModel);
}
void AudioPlugin::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
ANPRectF clipR;
clipR.left = clip.left;
clipR.top = clip.top;
clipR.right = clip.right;
clipR.bottom = clip.bottom;
gCanvasI.clipRect(canvas, &clipR);
draw(canvas);
gCanvasI.deleteCanvas(canvas);
}
void AudioPlugin::draw(ANPCanvas* canvas) {
PluginObject *obj = (PluginObject*) this->inst()->pdata;
gLogI.log(kError_ANPLogType, "Drawing");
const float trackHeight = 30;
const float buttonWidth = 60;
const float buttonHeight = 30;
const int W = obj->window->width;
const int H = obj->window->height;
// color the plugin canvas
gCanvasI.drawColor(canvas, 0xFFCDCDCD);
// get font metrics
ANPFontMetrics fontMetrics;
gPaintI.getFontMetrics(m_paintText, &fontMetrics);
// draw the track box (1 px from the edge)
m_trackRect.left = 1;
m_trackRect.top = 1;
m_trackRect.right = W - 2;
m_trackRect.bottom = 1 + trackHeight;
gCanvasI.drawRect(canvas, &m_trackRect, m_paintTrack);
// draw the progress bar
if (m_soundPlay->progress > 0) {
// TODO need to draw progress bar to cover the proper percentage of the track bar
gCanvasI.drawRect(canvas, &m_trackRect, m_paintTrackProgress);
}
// draw the play box (under track box)
m_playRect.left = m_trackRect.left + 5;
m_playRect.top = m_trackRect.bottom + 10;
m_playRect.right = m_playRect.left + buttonWidth;
m_playRect.bottom = m_playRect.top + buttonHeight;
gCanvasI.drawRect(canvas, &m_playRect, getPaint(&m_playRect));
// draw the play box (under track box)
const char playText[] = "Play";
gCanvasI.drawText(canvas, playText, sizeof(playText)-1, m_playRect.left + 5,
m_playRect.top - fontMetrics.fTop, m_paintText);
// draw the pause box (under track box)
m_pauseRect.left = m_playRect.right + 20;
m_pauseRect.top = m_trackRect.bottom + 10;
m_pauseRect.right = m_pauseRect.left + buttonWidth;
m_pauseRect.bottom = m_pauseRect.top + buttonHeight;
gCanvasI.drawRect(canvas, &m_pauseRect, getPaint(&m_pauseRect));
// draw the text in the pause box
const char pauseText[] = "Pause";
gCanvasI.drawText(canvas, pauseText, sizeof(pauseText)-1, m_pauseRect.left + 5,
m_pauseRect.top - fontMetrics.fTop, m_paintText);
// draw the stop box (under track box)
m_stopRect.left = m_pauseRect.right + 20;
m_stopRect.top = m_trackRect.bottom + 10;
m_stopRect.right = m_stopRect.left + buttonWidth;
m_stopRect.bottom = m_stopRect.top + buttonHeight;
gCanvasI.drawRect(canvas, &m_stopRect, getPaint(&m_stopRect));
// draw the text in the pause box
const char stopText[] = "Stop";
gCanvasI.drawText(canvas, stopText, sizeof(stopText)-1, m_stopRect.left + 5,
m_stopRect.top - fontMetrics.fTop, m_paintText);
}
ANPPaint* AudioPlugin::getPaint(ANPRectF* input) {
return (input == m_activeRect) ? m_paintActiveRect : m_paintRect;
}
int16 AudioPlugin::handleEvent(const ANPEvent* evt) {
NPP instance = this->inst();
switch (evt->eventType) {
case kDraw_ANPEventType:
switch (evt->data.draw.model) {
case kBitmap_ANPDrawingModel:
drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
return 1;
default:
break; // unknown drawing model
}
case kTouch_ANPEventType: {
int x = evt->data.touch.x;
int y = evt->data.touch.y;
if (kDown_ANPTouchAction == evt->data.touch.action) {
m_activeTouchRect = validTouch(x,y);
if(m_activeTouchRect) {
m_activeTouch = true;
return 1;
}
} else if (kUp_ANPTouchAction == evt->data.touch.action && m_activeTouch) {
handleTouch(x, y);
m_activeTouch = false;
return 1;
} else if (kCancel_ANPTouchAction == evt->data.touch.action) {
m_activeTouch = false;
}
break;
}
default:
break;
}
return 0; // unknown or unhandled event
}
void AudioPlugin::invalActiveRect() {
}
ANPRectF* AudioPlugin::validTouch(int x, int y) {
if (m_playRect.left && x < m_playRect.right && y > m_playRect.top && y < m_playRect.bottom)
return &m_playRect;
else if (m_pauseRect.left && x < m_pauseRect.right && y > m_pauseRect.top && y < m_pauseRect.bottom)
return &m_pauseRect;
else if (x > m_stopRect.left && x < m_stopRect.right && y > m_stopRect.top && y < m_stopRect.bottom)
return &m_stopRect;
else
return NULL;
}
void AudioPlugin::handleTouch(int x, int y) {
NPP instance = this->inst();
// if the track is null then return
if (NULL == m_soundPlay->track) {
gLogI.log(kError_ANPLogType, "---- %p unable to create track",
instance);
return;
}
// check to make sure the currentRect matches the activeRect
ANPRectF* currentRect = validTouch(x,y);
if (m_activeTouchRect != currentRect)
return;
if (currentRect == &m_playRect) {
gLogI.log(kDebug_ANPLogType, "---- %p starting track (%d)",
m_soundPlay->track, gSoundI.isStopped(m_soundPlay->track));
if (gSoundI.isStopped(m_soundPlay->track)) {
gSoundI.start(m_soundPlay->track);
}
}
else if (currentRect == &m_pauseRect) {
gLogI.log(kDebug_ANPLogType, "---- %p pausing track (%d)",
m_soundPlay->track, gSoundI.isStopped(m_soundPlay->track));
if (!gSoundI.isStopped(m_soundPlay->track)) {
gSoundI.pause(m_soundPlay->track);
}
}
else if (currentRect == &m_stopRect) {
gLogI.log(kDebug_ANPLogType, "---- %p stopping track (%d)",
m_soundPlay->track, gSoundI.isStopped(m_soundPlay->track));
if (!gSoundI.isStopped(m_soundPlay->track)) {
gSoundI.stop(m_soundPlay->track);
}
if (m_soundPlay->file) {
fseek(m_soundPlay->file, 0, SEEK_SET);
}
}
else {
return;
}
// set the currentRect to be the activeRect
m_activeRect = currentRect;
inval(instance);
}

View File

@@ -1,74 +0,0 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "PluginObject.h"
#include <stdio.h>
#ifndef audioPlugin__DEFINED
#define audioPlugin__DEFINED
struct SoundPlay {
NPP instance;
ANPAudioTrack* track;
FILE* file;
int fileSize;
int progress; // value between 0 and 100
};
class AudioPlugin : public SubPlugin {
public:
AudioPlugin(NPP inst);
virtual ~AudioPlugin();
virtual bool supportsDrawingModel(ANPDrawingModel);
virtual int16 handleEvent(const ANPEvent* evt);
private:
void draw(ANPCanvas*);
void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
void handleTouch(int x, int y);
void invalActiveRect();
ANPPaint* getPaint(ANPRectF*);
ANPRectF* validTouch(int x, int y);
ANPRectF m_trackRect;
ANPRectF m_playRect;
ANPRectF m_pauseRect;
ANPRectF m_stopRect;
ANPPaint* m_paintTrack;
ANPPaint* m_paintRect;
ANPPaint* m_paintText;
ANPPaint* m_paintTrackProgress;
ANPPaint* m_paintActiveRect;
SoundPlay* m_soundPlay;
bool m_activeTouch;
ANPRectF* m_activeTouchRect;
ANPRectF* m_activeRect;
};
#endif // audioPlugin__DEFINED

View File

@@ -1,499 +0,0 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "BackgroundPlugin.h"
#include "android_npapi.h"
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <math.h>
#include <string.h>
extern NPNetscapeFuncs* browser;
extern ANPBitmapInterfaceV0 gBitmapI;
extern ANPCanvasInterfaceV0 gCanvasI;
extern ANPLogInterfaceV0 gLogI;
extern ANPPaintInterfaceV0 gPaintI;
extern ANPSurfaceInterfaceV0 gSurfaceI;
extern ANPSystemInterfaceV0 gSystemI;
extern ANPTypefaceInterfaceV0 gTypefaceI;
extern ANPWindowInterfaceV0 gWindowI;
#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
static uint32_t getMSecs() {
struct timeval tv;
gettimeofday(&tv, NULL);
return (uint32_t) (tv.tv_sec * 1000 + tv.tv_usec / 1000 ); // microseconds to milliseconds
}
///////////////////////////////////////////////////////////////////////////////
BackgroundPlugin::BackgroundPlugin(NPP inst) : SurfaceSubPlugin(inst) {
// initialize the drawing surface
m_surface = NULL;
//initialize bitmap transparency variables
mFinishedStageOne = false;
mFinishedStageTwo = false;
mFinishedStageThree = false;
// test basic plugin functionality
test_logging(); // android logging
test_timers(); // plugin timers
test_bitmaps(); // android bitmaps
test_domAccess();
test_javascript();
test_loadJavaClass();
//register for touch events
ANPEventFlags flags = kTouch_ANPEventFlag;
NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
if (err != NPERR_NO_ERROR) {
gLogI.log(kError_ANPLogType, "Error selecting input events.");
}
}
BackgroundPlugin::~BackgroundPlugin() {
setContext(NULL);
destroySurface();
}
jobject BackgroundPlugin::getSurface() {
if (m_surface) {
return m_surface;
}
// load the appropriate java class and instantiate it
JNIEnv* env = NULL;
if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
return NULL;
}
const char* className = "com.android.sampleplugin.BackgroundSurface";
jclass backgroundClass = gSystemI.loadJavaClass(inst(), className);
if(!backgroundClass) {
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
return NULL;
}
jmethodID constructor = env->GetMethodID(backgroundClass, "<init>", "(Landroid/content/Context;)V");
jobject backgroundSurface = env->NewObject(backgroundClass, constructor, m_context);
if(!backgroundSurface) {
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
return NULL;
}
m_surface = env->NewGlobalRef(backgroundSurface);
return m_surface;
}
void BackgroundPlugin::destroySurface() {
JNIEnv* env = NULL;
if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
env->DeleteGlobalRef(m_surface);
m_surface = NULL;
}
}
void BackgroundPlugin::drawPlugin(int surfaceWidth, int surfaceHeight) {
// get the plugin's dimensions according to the DOM
PluginObject *obj = (PluginObject*) inst()->pdata;
const int W = obj->window->width;
const int H = obj->window->height;
// compute the current zoom level
const float zoomFactorW = static_cast<float>(surfaceWidth) / W;
const float zoomFactorH = static_cast<float>(surfaceHeight) / H;
// check to make sure the zoom level is uniform
if (zoomFactorW + .01 < zoomFactorH && zoomFactorW - .01 > zoomFactorH)
gLogI.log(kError_ANPLogType, " ------ %p zoom is out of sync (%f,%f)",
inst(), zoomFactorW, zoomFactorH);
// scale the variables based on the zoom level
const int fontSize = (int)(zoomFactorW * 16);
const int leftMargin = (int)(zoomFactorW * 10);
// lock the surface
ANPBitmap bitmap;
JNIEnv* env = NULL;
if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
!gSurfaceI.lock(env, m_surface, &bitmap, NULL)) {
gLogI.log(kError_ANPLogType, " ------ %p unable to lock the plugin", inst());
return;
}
// create a canvas
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
gCanvasI.drawColor(canvas, 0xFFFFFFFF);
ANPPaint* paint = gPaintI.newPaint();
gPaintI.setFlags(paint, gPaintI.getFlags(paint) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(paint, 0xFFFF0000);
gPaintI.setTextSize(paint, fontSize);
ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
gPaintI.setTypeface(paint, tf);
gTypefaceI.unref(tf);
ANPFontMetrics fm;
gPaintI.getFontMetrics(paint, &fm);
gPaintI.setColor(paint, 0xFF0000FF);
const char c[] = "This is a background plugin.";
gCanvasI.drawText(canvas, c, sizeof(c)-1, leftMargin, -fm.fTop, paint);
// clean up variables and unlock the surface
gPaintI.deletePaint(paint);
gCanvasI.deleteCanvas(canvas);
gSurfaceI.unlock(env, m_surface);
}
int16 BackgroundPlugin::handleEvent(const ANPEvent* evt) {
switch (evt->eventType) {
case kDraw_ANPEventType:
gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request draw events", inst());
break;
case kLifecycle_ANPEventType:
switch (evt->data.lifecycle.action) {
case kOnLoad_ANPLifecycleAction:
gLogI.log(kDebug_ANPLogType, " ------ %p onLoad", inst());
return 1;
case kOnScreen_ANPLifecycleAction:
gLogI.log(kDebug_ANPLogType, " ------ %p onScreen", inst());
return 1;
case kOffScreen_ANPLifecycleAction:
gLogI.log(kDebug_ANPLogType, " ------ %p offScreen", inst());
return 1;
}
break; // end kLifecycle_ANPEventType
case kTouch_ANPEventType:
if (kLongPress_ANPTouchAction == evt->data.touch.action) {
browser->geturl(inst(), "javascript:alert('Detected long press event.')", 0);
gWindowI.requestFullScreen(inst());
}
else if (kDoubleTap_ANPTouchAction == evt->data.touch.action)
browser->geturl(inst(), "javascript:alert('Detected double tap event.')", 0);
break;
case kKey_ANPEventType:
gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request key events", inst());
break;
default:
break;
}
return 0; // unknown or unhandled event
}
///////////////////////////////////////////////////////////////////////////////
// LOGGING TESTS
///////////////////////////////////////////////////////////////////////////////
void BackgroundPlugin::test_logging() {
NPP instance = this->inst();
//LOG_ERROR(instance, " ------ %p Testing Log Error", instance);
gLogI.log(kError_ANPLogType, " ------ %p Testing Log Error", instance);
gLogI.log(kWarning_ANPLogType, " ------ %p Testing Log Warning", instance);
gLogI.log(kDebug_ANPLogType, " ------ %p Testing Log Debug", instance);
}
///////////////////////////////////////////////////////////////////////////////
// TIMER TESTS
///////////////////////////////////////////////////////////////////////////////
#define TIMER_INTERVAL 50
static void timer_oneshot(NPP instance, uint32 timerID);
static void timer_repeat(NPP instance, uint32 timerID);
static void timer_neverfires(NPP instance, uint32 timerID);
static void timer_latency(NPP instance, uint32 timerID);
void BackgroundPlugin::test_timers() {
NPP instance = this->inst();
//Setup the testing counters
mTimerRepeatCount = 5;
mTimerLatencyCount = 5;
// test for bogus timerID
browser->unscheduletimer(instance, 999999);
// test one-shot
browser->scheduletimer(instance, 100, false, timer_oneshot);
// test repeat
browser->scheduletimer(instance, 50, true, timer_repeat);
// test timer latency
browser->scheduletimer(instance, TIMER_INTERVAL, true, timer_latency);
mStartTime = mPrevTime = getMSecs();
// test unschedule immediately
uint32 id = browser->scheduletimer(instance, 100, false, timer_neverfires);
browser->unscheduletimer(instance, id);
// test double unschedule (should be no-op)
browser->unscheduletimer(instance, id);
}
static void timer_oneshot(NPP instance, uint32 timerID) {
gLogI.log(kDebug_ANPLogType, "-------- oneshot timer\n");
}
static void timer_repeat(NPP instance, uint32 timerID) {
BackgroundPlugin *obj = ((BackgroundPlugin*) ((PluginObject*) instance->pdata)->activePlugin);
gLogI.log(kDebug_ANPLogType, "-------- repeat timer %d\n",
obj->mTimerRepeatCount);
if (--obj->mTimerRepeatCount == 0) {
browser->unscheduletimer(instance, timerID);
}
}
static void timer_neverfires(NPP instance, uint32 timerID) {
gLogI.log(kError_ANPLogType, "-------- timer_neverfires!!!\n");
}
static void timer_latency(NPP instance, uint32 timerID) {
BackgroundPlugin *obj = ((BackgroundPlugin*) ((PluginObject*) instance->pdata)->activePlugin);
obj->mTimerLatencyCurrentCount += 1;
uint32_t now = getMSecs();
uint32_t interval = now - obj->mPrevTime;
uint32_t dur = now - obj->mStartTime;
uint32_t expectedDur = obj->mTimerLatencyCurrentCount * TIMER_INTERVAL;
int32_t drift = dur - expectedDur;
int32_t avgDrift = drift / obj->mTimerLatencyCurrentCount;
obj->mPrevTime = now;
gLogI.log(kDebug_ANPLogType,
"-------- latency test: [%3d] interval %d expected %d, total %d expected %d, drift %d avg %d\n",
obj->mTimerLatencyCurrentCount, interval, TIMER_INTERVAL, dur,
expectedDur, drift, avgDrift);
if (--obj->mTimerLatencyCount == 0) {
browser->unscheduletimer(instance, timerID);
}
}
///////////////////////////////////////////////////////////////////////////////
// BITMAP TESTS
///////////////////////////////////////////////////////////////////////////////
static void test_formats(NPP instance);
void BackgroundPlugin::test_bitmaps() {
test_formats(this->inst());
}
static void test_formats(NPP instance) {
// TODO pull names from enum in npapi instead of hardcoding them
static const struct {
ANPBitmapFormat fFormat;
const char* fName;
} gRecs[] = {
{ kUnknown_ANPBitmapFormat, "unknown" },
{ kRGBA_8888_ANPBitmapFormat, "8888" },
{ kRGB_565_ANPBitmapFormat, "565" },
};
ANPPixelPacking packing;
for (size_t i = 0; i < ARRAY_COUNT(gRecs); i++) {
if (gBitmapI.getPixelPacking(gRecs[i].fFormat, &packing)) {
gLogI.log(kDebug_ANPLogType,
"pixel format [%d] %s has packing ARGB [%d %d] [%d %d] [%d %d] [%d %d]\n",
gRecs[i].fFormat, gRecs[i].fName,
packing.AShift, packing.ABits,
packing.RShift, packing.RBits,
packing.GShift, packing.GBits,
packing.BShift, packing.BBits);
} else {
gLogI.log(kDebug_ANPLogType,
"pixel format [%d] %s has no packing\n",
gRecs[i].fFormat, gRecs[i].fName);
}
}
}
void BackgroundPlugin::test_bitmap_transparency(const ANPEvent* evt) {
NPP instance = this->inst();
// check default & set transparent
if (!mFinishedStageOne) {
gLogI.log(kDebug_ANPLogType, "BEGIN: testing bitmap transparency");
//check to make sure it is not transparent
if (evt->data.draw.data.bitmap.format == kRGBA_8888_ANPBitmapFormat) {
gLogI.log(kError_ANPLogType, "bitmap default format is transparent");
}
//make it transparent (any non-null value will set it to true)
bool value = true;
NPError err = browser->setvalue(instance, NPPVpluginTransparentBool, &value);
if (err != NPERR_NO_ERROR) {
gLogI.log(kError_ANPLogType, "Error setting transparency.");
}
mFinishedStageOne = true;
browser->invalidaterect(instance, NULL);
}
// check transparent & set opaque
else if (!mFinishedStageTwo) {
//check to make sure it is transparent
if (evt->data.draw.data.bitmap.format != kRGBA_8888_ANPBitmapFormat) {
gLogI.log(kError_ANPLogType, "bitmap did not change to transparent format");
}
//make it opaque
NPError err = browser->setvalue(instance, NPPVpluginTransparentBool, NULL);
if (err != NPERR_NO_ERROR) {
gLogI.log(kError_ANPLogType, "Error setting transparency.");
}
mFinishedStageTwo = true;
}
// check opaque
else if (!mFinishedStageThree) {
//check to make sure it is not transparent
if (evt->data.draw.data.bitmap.format == kRGBA_8888_ANPBitmapFormat) {
gLogI.log(kError_ANPLogType, "bitmap default format is transparent");
}
gLogI.log(kDebug_ANPLogType, "END: testing bitmap transparency");
mFinishedStageThree = true;
}
}
///////////////////////////////////////////////////////////////////////////////
// DOM TESTS
///////////////////////////////////////////////////////////////////////////////
void BackgroundPlugin::test_domAccess() {
NPP instance = this->inst();
gLogI.log(kDebug_ANPLogType, " ------ %p Testing DOM Access", instance);
// Get the plugin's DOM object
NPObject* windowObject = NULL;
browser->getvalue(instance, NPNVWindowNPObject, &windowObject);
if (!windowObject)
gLogI.log(kError_ANPLogType, " ------ %p Unable to retrieve DOM Window", instance);
// Retrieve a property from the plugin's DOM object
NPIdentifier topIdentifier = browser->getstringidentifier("top");
NPVariant topObjectVariant;
browser->getproperty(instance, windowObject, topIdentifier, &topObjectVariant);
if (topObjectVariant.type != NPVariantType_Object)
gLogI.log(kError_ANPLogType, " ------ %p Invalid Variant type for DOM Property: %d,%d", instance, topObjectVariant.type, NPVariantType_Object);
}
///////////////////////////////////////////////////////////////////////////////
// JAVASCRIPT TESTS
///////////////////////////////////////////////////////////////////////////////
void BackgroundPlugin::test_javascript() {
NPP instance = this->inst();
gLogI.log(kDebug_ANPLogType, " ------ %p Testing JavaScript Access", instance);
// Get the plugin's DOM object
NPObject* windowObject = NULL;
browser->getvalue(instance, NPNVWindowNPObject, &windowObject);
if (!windowObject)
gLogI.log(kError_ANPLogType, " ------ %p Unable to retrieve DOM Window", instance);
// create a string (JS code) that is stored in memory allocated by the browser
const char* jsString = "1200 + 34";
void* stringMem = browser->memalloc(strlen(jsString));
memcpy(stringMem, jsString, strlen(jsString));
// execute the javascript in the plugin's DOM object
NPString script = { (char*)stringMem, strlen(jsString) };
NPVariant scriptVariant;
if (!browser->evaluate(instance, windowObject, &script, &scriptVariant))
gLogI.log(kError_ANPLogType, " ------ %p Unable to eval the JS.", instance);
if (scriptVariant.type == NPVariantType_Int32) {
if (scriptVariant.value.intValue != 1234)
gLogI.log(kError_ANPLogType, " ------ %p Invalid Value for JS Return: %d,1234", instance, scriptVariant.value.intValue);
} else {
gLogI.log(kError_ANPLogType, " ------ %p Invalid Variant type for JS Return: %d,%d", instance, scriptVariant.type, NPVariantType_Int32);
}
// free the memory allocated within the browser
browser->memfree(stringMem);
}
///////////////////////////////////////////////////////////////////////////////
// Load Java Classes Tests
///////////////////////////////////////////////////////////////////////////////
void BackgroundPlugin::test_loadJavaClass() {
JNIEnv* env = NULL;
if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: failed to get env");
return;
}
const char* className = "com.android.sampleplugin.BackgroundTest";
jclass backgroundClass = gSystemI.loadJavaClass(inst(), className);
if(!backgroundClass) {
gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: failed to load class");
return;
}
jmethodID constructor = env->GetMethodID(backgroundClass, "<init>", "()V");
jmethodID addMethod = env->GetMethodID(backgroundClass, "addInt", "(II)I");
jobject backgroundObject = env->NewObject(backgroundClass, constructor);
if(!backgroundObject) {
gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: failed to construct object");
return;
}
jint result = env->CallIntMethod(backgroundObject, addMethod, 2, 2);
if (result != 4) {
gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: invalid result (%d != 4)", result);
}
}

View File

@@ -1,66 +0,0 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "PluginObject.h"
#ifndef backgroundPlugin__DEFINED
#define backgroundPlugin__DEFINED
class BackgroundPlugin : public SurfaceSubPlugin {
public:
BackgroundPlugin(NPP inst);
virtual ~BackgroundPlugin();
virtual int16 handleEvent(const ANPEvent* evt);
virtual jobject getSurface();
// Timer Testing Variables
uint32_t mStartTime;
uint32_t mPrevTime;
int mTimerRepeatCount;
int mTimerLatencyCount;
int mTimerLatencyCurrentCount;
// Bitmap Transparency Variables
bool mFinishedStageOne; // check default & set transparent
bool mFinishedStageTwo; // check transparent & set opaque
bool mFinishedStageThree; // check opaque
private:
void drawPlugin(int surfaceWidth, int surfaceHeight);
void destroySurface();
jobject m_surface;
void test_logging();
void test_timers();
void test_bitmaps();
void test_bitmap_transparency(const ANPEvent* evt);
void test_domAccess();
void test_javascript();
void test_loadJavaClass();
};
#endif // backgroundPlugin__DEFINED

View File

@@ -1,381 +0,0 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "FormPlugin.h"
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <math.h>
#include <string.h>
extern NPNetscapeFuncs* browser;
extern ANPLogInterfaceV0 gLogI;
extern ANPCanvasInterfaceV0 gCanvasI;
extern ANPPaintInterfaceV0 gPaintI;
extern ANPTypefaceInterfaceV0 gTypefaceI;
extern ANPWindowInterfaceV0 gWindowI;
static void inval(NPP instance) {
browser->invalidaterect(instance, NULL);
}
static uint16 rnd16(float x, int inset) {
int ix = (int)roundf(x) + inset;
if (ix < 0) {
ix = 0;
}
return static_cast<uint16>(ix);
}
static void inval(NPP instance, const ANPRectF& r, bool doAA) {
const int inset = doAA ? -1 : 0;
PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
NPRect inval;
inval.left = rnd16(r.left, inset);
inval.top = rnd16(r.top, inset);
inval.right = rnd16(r.right, -inset);
inval.bottom = rnd16(r.bottom, -inset);
browser->invalidaterect(instance, &inval);
}
///////////////////////////////////////////////////////////////////////////////
FormPlugin::FormPlugin(NPP inst) : SubPlugin(inst) {
m_hasFocus = false;
m_activeInput = NULL;
memset(&m_usernameInput, 0, sizeof(m_usernameInput));
memset(&m_passwordInput, 0, sizeof(m_passwordInput));
m_usernameInput.text[0] = '\0';
m_usernameInput.charPtr = 0;
m_passwordInput.text[0] = '\0';
m_passwordInput.charPtr = 0;
m_paintInput = gPaintI.newPaint();
gPaintI.setFlags(m_paintInput, gPaintI.getFlags(m_paintInput) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(m_paintInput, 0xFFFFFFFF);
m_paintActive = gPaintI.newPaint();
gPaintI.setFlags(m_paintActive, gPaintI.getFlags(m_paintActive) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(m_paintActive, 0xFFFFFF00);
m_paintText = gPaintI.newPaint();
gPaintI.setFlags(m_paintText, gPaintI.getFlags(m_paintText) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(m_paintText, 0xFF000000);
gPaintI.setTextSize(m_paintText, 18);
ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
gPaintI.setTypeface(m_paintText, tf);
gTypefaceI.unref(tf);
//register for key and visibleRect events
ANPEventFlags flags = kKey_ANPEventFlag;
NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
if (err != NPERR_NO_ERROR) {
gLogI.log(kError_ANPLogType, "Error selecting input events.");
}
}
FormPlugin::~FormPlugin() {
gPaintI.deletePaint(m_paintInput);
gPaintI.deletePaint(m_paintActive);
gPaintI.deletePaint(m_paintText);
}
bool FormPlugin::supportsDrawingModel(ANPDrawingModel model) {
return (model == kBitmap_ANPDrawingModel);
}
void FormPlugin::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
ANPRectF clipR;
clipR.left = clip.left;
clipR.top = clip.top;
clipR.right = clip.right;
clipR.bottom = clip.bottom;
gCanvasI.clipRect(canvas, &clipR);
draw(canvas);
gCanvasI.deleteCanvas(canvas);
}
void FormPlugin::draw(ANPCanvas* canvas) {
NPP instance = this->inst();
PluginObject *obj = (PluginObject*) instance->pdata;
const float inputWidth = 60;
const float inputHeight = 30;
const int W = obj->window->width;
const int H = obj->window->height;
// color the plugin canvas
gCanvasI.drawColor(canvas, (m_hasFocus) ? 0xFFCDCDCD : 0xFF545454);
// draw the username box (5 px from the top edge)
m_usernameInput.rect.left = 5;
m_usernameInput.rect.top = 5;
m_usernameInput.rect.right = W - 5;
m_usernameInput.rect.bottom = m_usernameInput.rect.top + inputHeight;
gCanvasI.drawRect(canvas, &m_usernameInput.rect, getPaint(&m_usernameInput));
drawText(canvas, m_usernameInput);
// draw the password box (5 px from the bottom edge)
m_passwordInput.rect.left = 5;
m_passwordInput.rect.top = H - (inputHeight + 5);
m_passwordInput.rect.right = W - 5;
m_passwordInput.rect.bottom = m_passwordInput.rect.top + inputHeight;
gCanvasI.drawRect(canvas, &m_passwordInput.rect, getPaint(&m_passwordInput));
drawPassword(canvas, m_passwordInput);
//invalidate the canvas
//inval(instance);
}
ANPPaint* FormPlugin::getPaint(TextInput* input) {
return (input == m_activeInput) ? m_paintActive : m_paintInput;
}
void FormPlugin::drawText(ANPCanvas* canvas, TextInput textInput) {
// get font metrics
ANPFontMetrics fontMetrics;
gPaintI.getFontMetrics(m_paintText, &fontMetrics);
gCanvasI.drawText(canvas, textInput.text, textInput.charPtr,
textInput.rect.left + 5,
textInput.rect.bottom - fontMetrics.fBottom, m_paintText);
}
void FormPlugin::drawPassword(ANPCanvas* canvas, TextInput passwordInput) {
// get font metrics
ANPFontMetrics fontMetrics;
gPaintI.getFontMetrics(m_paintText, &fontMetrics);
// comput the circle dimensions and initial location
float initialX = passwordInput.rect.left + 5;
float ovalBottom = passwordInput.rect.bottom - 2;
float ovalTop = ovalBottom - (fontMetrics.fBottom - fontMetrics.fTop);
float ovalWidth = ovalBottom - ovalTop;
float ovalSpacing = 3;
// draw circles instead of the actual text
for (uint32_t x = 0; x < passwordInput.charPtr; x++) {
ANPRectF oval;
oval.left = initialX + ((ovalWidth + ovalSpacing) * (float) x);
oval.right = oval.left + ovalWidth;
oval.top = ovalTop;
oval.bottom = ovalBottom;
gCanvasI.drawOval(canvas, &oval, m_paintText);
}
}
int16 FormPlugin::handleEvent(const ANPEvent* evt) {
NPP instance = this->inst();
switch (evt->eventType) {
case kDraw_ANPEventType:
switch (evt->data.draw.model) {
case kBitmap_ANPDrawingModel:
drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
return 1;
default:
break; // unknown drawing model
}
break;
case kLifecycle_ANPEventType:
if (evt->data.lifecycle.action == kLoseFocus_ANPLifecycleAction) {
gLogI.log(kDebug_ANPLogType, "----%p Loosing Focus", instance);
if (m_activeInput) {
// hide the keyboard
gWindowI.showKeyboard(instance, false);
//reset the activeInput
m_activeInput = NULL;
}
m_hasFocus = false;
inval(instance);
return 1;
}
else if (evt->data.lifecycle.action == kGainFocus_ANPLifecycleAction) {
gLogI.log(kDebug_ANPLogType, "----%p Gaining Focus", instance);
m_hasFocus = true;
inval(instance);
return 1;
}
break;
case kMouse_ANPEventType: {
int x = evt->data.mouse.x;
int y = evt->data.mouse.y;
if (kDown_ANPMouseAction == evt->data.mouse.action) {
TextInput* currentInput = validTap(x,y);
if (currentInput)
gWindowI.showKeyboard(instance, true);
else if (m_activeInput)
gWindowI.showKeyboard(instance, false);
if (currentInput != m_activeInput)
switchActiveInput(currentInput);
return 1;
}
break;
}
case kKey_ANPEventType:
if (evt->data.key.action == kDown_ANPKeyAction) {
//handle navigation keys
if (evt->data.key.nativeCode >= kDpadUp_ANPKeyCode
&& evt->data.key.nativeCode <= kDpadCenter_ANPKeyCode) {
return handleNavigation(evt->data.key.nativeCode) ? 1 : 0;
}
if (m_activeInput) {
handleTextInput(m_activeInput, evt->data.key.nativeCode,
evt->data.key.unichar);
inval(instance, m_activeInput->rect, true);
}
}
return 1;
default:
break;
}
return 0; // unknown or unhandled event
}
void FormPlugin::switchActiveInput(TextInput* newInput) {
NPP instance = this->inst();
if (m_activeInput) {
inval(instance, m_activeInput->rect, true); // inval the old
gWindowI.clearVisibleRects(instance);
}
m_activeInput = newInput; // set the new active input
if (m_activeInput) {
inval(instance, m_activeInput->rect, true); // inval the new
scrollIntoView(m_activeInput);
}
}
bool FormPlugin::handleNavigation(ANPKeyCode keyCode) {
NPP instance = this->inst();
gLogI.log(kDebug_ANPLogType, "----%p Recvd Nav Key %d", instance, keyCode);
if (!m_activeInput) {
gWindowI.showKeyboard(instance, true);
switchActiveInput(&m_usernameInput);
}
else if (m_activeInput == &m_usernameInput) {
if (keyCode == kDpadDown_ANPKeyCode) {
switchActiveInput(&m_passwordInput);
}
else if (keyCode == kDpadCenter_ANPKeyCode)
gWindowI.showKeyboard(instance, false);
else if (keyCode == kDpadUp_ANPKeyCode)
return false;
}
else if (m_activeInput == &m_passwordInput) {
if (keyCode == kDpadUp_ANPKeyCode) {
switchActiveInput(&m_usernameInput);
}
else if (keyCode == kDpadCenter_ANPKeyCode)
gWindowI.showKeyboard(instance, false);
else if (keyCode == kDpadDown_ANPKeyCode)
return false;
}
return true;
}
void FormPlugin::handleTextInput(TextInput* input, ANPKeyCode keyCode, int32_t unichar) {
NPP instance = this->inst();
//make sure the input field is in view
scrollIntoView(input);
//handle the delete operation
if (keyCode == kDel_ANPKeyCode) {
if (input->charPtr > 0) {
input->charPtr--;
}
return;
}
//check to see that the input is not full
if (input->charPtr >= (sizeof(input->text) - 1))
return;
//add the character
input->text[input->charPtr] = static_cast<char>(unichar);
input->charPtr++;
gLogI.log(kDebug_ANPLogType, "----%p Text: %c", instance, unichar);
}
void FormPlugin::scrollIntoView(TextInput* input) {
NPP instance = this->inst();
PluginObject *obj = (PluginObject*) instance->pdata;
NPWindow *window = obj->window;
// find the textInput's global rect coordinates
ANPRectI visibleRects[1];
visibleRects[0].left = input->rect.left;
visibleRects[0].top = input->rect.top;
visibleRects[0].right = input->rect.right;
visibleRects[0].bottom = input->rect.bottom;
gWindowI.setVisibleRects(instance, visibleRects, 1);
}
TextInput* FormPlugin::validTap(int x, int y) {
if (x > m_usernameInput.rect.left && x < m_usernameInput.rect.right &&
y > m_usernameInput.rect.top && y < m_usernameInput.rect.bottom)
return &m_usernameInput;
else if (x >m_passwordInput.rect.left && x < m_passwordInput.rect.right &&
y > m_passwordInput.rect.top && y < m_passwordInput.rect.bottom)
return &m_passwordInput;
else
return NULL;
}

View File

@@ -1,72 +0,0 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "PluginObject.h"
#ifndef formPlugin__DEFINED
#define formPlugin__DEFINED
struct TextInput {
ANPRectF rect;
char text[30];
uint32_t charPtr;
};
class FormPlugin : public SubPlugin {
public:
FormPlugin(NPP inst);
virtual ~FormPlugin();
virtual bool supportsDrawingModel(ANPDrawingModel);
virtual int16 handleEvent(const ANPEvent* evt);
private:
void draw(ANPCanvas*);
void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
bool m_hasFocus;
TextInput* m_activeInput;
TextInput m_usernameInput;
TextInput m_passwordInput;
ANPPaint* m_paintInput;
ANPPaint* m_paintActive;
ANPPaint* m_paintText;
ANPRectI m_visibleRect;
void drawText(ANPCanvas*, TextInput);
void drawPassword(ANPCanvas*, TextInput);
bool handleNavigation(ANPKeyCode keyCode);
void handleTextInput(TextInput* input, ANPKeyCode keyCode, int32_t unichar);
void scrollIntoView(TextInput* input);
void switchActiveInput(TextInput* input);
ANPPaint* getPaint(TextInput*);
TextInput* validTap(int x, int y);
};
#endif // formPlugin__DEFINED

View File

@@ -1,82 +0,0 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <string.h>
#include <jni.h>
#include <JNIHelp.h>
#include <utils/Log.h>
#include "PluginObject.h"
#define EXPORT __attribute__((visibility("default")))
extern ANPEventInterfaceV0 gEventI;
static void surfaceCreated(JNIEnv* env, jobject thiz, jint npp, jobject surface) {
// send custom event
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = kCustom_ANPEventType;
event.data.other[0] = kSurfaceCreated_CustomEvent;
gEventI.postEvent((NPP)npp, &event);
}
static void surfaceChanged(JNIEnv* env, jobject thiz, jint npp, jint format, jint width, jint height) {
// send custom event
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = kCustom_ANPEventType;
event.data.other[0] = kSurfaceChanged_CustomEvent;
event.data.other[1] = width;
event.data.other[2] = height;
gEventI.postEvent((NPP)npp, &event);
}
static void surfaceDestroyed(JNIEnv* env, jobject thiz, jint npp) {
// send custom event
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = kCustom_ANPEventType;
event.data.other[0] = kSurfaceDestroyed_CustomEvent;
gEventI.postEvent((NPP)npp, &event);
}
/*
* JNI registration.
*/
static JNINativeMethod gPaintSurfaceMethods[] = {
{ "nativeSurfaceCreated", "(I)V", (void*) surfaceCreated },
{ "nativeSurfaceChanged", "(IIII)V", (void*) surfaceChanged },
{ "nativeSurfaceDestroyed", "(I)V", (void*) surfaceDestroyed },
};
EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env = NULL;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
return -1;
}
jniRegisterNativeMethods(env, "com/android/sampleplugin/PaintSurface",
gPaintSurfaceMethods, NELEM(gPaintSurfaceMethods));
return JNI_VERSION_1_4;
}

View File

@@ -1,457 +0,0 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "main.h"
#include "PluginObject.h"
#include "AnimationPlugin.h"
#include "AudioPlugin.h"
#include "BackgroundPlugin.h"
#include "FormPlugin.h"
#include "NavigationPlugin.h"
#include "PaintPlugin.h"
#include "VideoPlugin.h"
NPNetscapeFuncs* browser;
JavaVM* gVM;
#define EXPORT __attribute__((visibility("default")))
NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
char* argn[], char* argv[], NPSavedData* saved);
NPError NPP_Destroy(NPP instance, NPSavedData** save);
NPError NPP_SetWindow(NPP instance, NPWindow* window);
NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
NPBool seekable, uint16* stype);
NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason);
int32 NPP_WriteReady(NPP instance, NPStream* stream);
int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len,
void* buffer);
void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname);
void NPP_Print(NPP instance, NPPrint* platformPrint);
int16 NPP_HandleEvent(NPP instance, void* event);
void NPP_URLNotify(NPP instance, const char* URL, NPReason reason,
void* notifyData);
NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value);
NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value);
extern "C" {
EXPORT NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env);
EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value);
EXPORT const char* NP_GetMIMEDescription(void);
EXPORT void NP_Shutdown(void);
};
ANPAudioTrackInterfaceV0 gSoundI;
ANPBitmapInterfaceV0 gBitmapI;
ANPCanvasInterfaceV0 gCanvasI;
ANPEventInterfaceV0 gEventI;
ANPLogInterfaceV0 gLogI;
ANPPaintInterfaceV0 gPaintI;
ANPPathInterfaceV0 gPathI;
ANPSurfaceInterfaceV0 gSurfaceI;
ANPSystemInterfaceV0 gSystemI;
ANPTypefaceInterfaceV0 gTypefaceI;
ANPWindowInterfaceV0 gWindowI;
#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
#define DEBUG_PLUGIN_EVENTS 0
NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env)
{
// Make sure we have a function table equal or larger than we are built against.
if (browserFuncs->size < sizeof(NPNetscapeFuncs)) {
return NPERR_GENERIC_ERROR;
}
// Copy the function table (structure)
browser = (NPNetscapeFuncs*) malloc(sizeof(NPNetscapeFuncs));
memcpy(browser, browserFuncs, sizeof(NPNetscapeFuncs));
// Build the plugin function table
pluginFuncs->version = 11;
pluginFuncs->size = sizeof(pluginFuncs);
pluginFuncs->newp = NPP_New;
pluginFuncs->destroy = NPP_Destroy;
pluginFuncs->setwindow = NPP_SetWindow;
pluginFuncs->newstream = NPP_NewStream;
pluginFuncs->destroystream = NPP_DestroyStream;
pluginFuncs->asfile = NPP_StreamAsFile;
pluginFuncs->writeready = NPP_WriteReady;
pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
pluginFuncs->print = NPP_Print;
pluginFuncs->event = NPP_HandleEvent;
pluginFuncs->urlnotify = NPP_URLNotify;
pluginFuncs->getvalue = NPP_GetValue;
pluginFuncs->setvalue = NPP_SetValue;
static const struct {
NPNVariable v;
uint32_t size;
ANPInterface* i;
} gPairs[] = {
{ kAudioTrackInterfaceV0_ANPGetValue, sizeof(gSoundI), &gSoundI },
{ kBitmapInterfaceV0_ANPGetValue, sizeof(gBitmapI), &gBitmapI },
{ kCanvasInterfaceV0_ANPGetValue, sizeof(gCanvasI), &gCanvasI },
{ kEventInterfaceV0_ANPGetValue, sizeof(gEventI), &gEventI },
{ kLogInterfaceV0_ANPGetValue, sizeof(gLogI), &gLogI },
{ kPaintInterfaceV0_ANPGetValue, sizeof(gPaintI), &gPaintI },
{ kPathInterfaceV0_ANPGetValue, sizeof(gPathI), &gPathI },
{ kSurfaceInterfaceV0_ANPGetValue, sizeof(gSurfaceI), &gSurfaceI },
{ kSystemInterfaceV0_ANPGetValue, sizeof(gSystemI), &gSystemI },
{ kTypefaceInterfaceV0_ANPGetValue, sizeof(gTypefaceI), &gTypefaceI },
{ kWindowInterfaceV0_ANPGetValue, sizeof(gWindowI), &gWindowI },
};
for (size_t i = 0; i < ARRAY_COUNT(gPairs); i++) {
gPairs[i].i->inSize = gPairs[i].size;
NPError err = browser->getvalue(NULL, gPairs[i].v, gPairs[i].i);
if (err) {
return err;
}
}
// store the JavaVM for the plugin
JNIEnv* env = (JNIEnv*)java_env;
env->GetJavaVM(&gVM);
return NPERR_NO_ERROR;
}
void NP_Shutdown(void)
{
}
const char *NP_GetMIMEDescription(void)
{
return "application/x-testbrowserplugin:tst:Test plugin mimetype is application/x-testbrowserplugin";
}
NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
char* argn[], char* argv[], NPSavedData* saved)
{
/* BEGIN: STANDARD PLUGIN FRAMEWORK */
PluginObject *obj = NULL;
// Scripting functions appeared in NPAPI version 14
if (browser->version >= 14) {
instance->pdata = browser->createobject (instance, getPluginClass());
obj = static_cast<PluginObject*>(instance->pdata);
}
/* END: STANDARD PLUGIN FRAMEWORK */
// select the drawing model based on user input
ANPDrawingModel model = kBitmap_ANPDrawingModel;
for (int i = 0; i < argc; i++) {
if (!strcmp(argn[i], "DrawingModel")) {
if (!strcmp(argv[i], "Bitmap")) {
model = kBitmap_ANPDrawingModel;
}
else if (!strcmp(argv[i], "Surface")) {
model = kSurface_ANPDrawingModel;
}
gLogI.log(kDebug_ANPLogType, "------ %p DrawingModel is %d", instance, model);
break;
}
}
// notify the plugin API of the drawing model we wish to use. This must be
// done prior to creating certain subPlugin objects (e.g. surfaceViews)
NPError err = browser->setvalue(instance, kRequestDrawingModel_ANPSetValue,
reinterpret_cast<void*>(model));
if (err) {
gLogI.log(kError_ANPLogType, "request model %d err %d", model, err);
return err;
}
const char* path = gSystemI.getApplicationDataDirectory();
if (path) {
gLogI.log(kDebug_ANPLogType, "Application data dir is %s", path);
} else {
gLogI.log(kError_ANPLogType, "Can't find Application data dir");
}
// select the pluginType
for (int i = 0; i < argc; i++) {
if (!strcmp(argn[i], "PluginType")) {
if (!strcmp(argv[i], "Animation")) {
obj->pluginType = kAnimation_PluginType;
obj->activePlugin = new BallAnimation(instance);
}
else if (!strcmp(argv[i], "Audio")) {
obj->pluginType = kAudio_PluginType;
obj->activePlugin = new AudioPlugin(instance);
}
else if (!strcmp(argv[i], "Background")) {
obj->pluginType = kBackground_PluginType;
obj->activePlugin = new BackgroundPlugin(instance);
}
else if (!strcmp(argv[i], "Form")) {
obj->pluginType = kForm_PluginType;
obj->activePlugin = new FormPlugin(instance);
}
else if (!strcmp(argv[i], "Navigation")) {
obj->pluginType = kNavigation_PluginType;
obj->activePlugin = new NavigationPlugin(instance);
}
else if (!strcmp(argv[i], "Paint")) {
obj->pluginType = kPaint_PluginType;
obj->activePlugin = new PaintPlugin(instance);
}
else if (!strcmp(argv[i], "Video")) {
obj->pluginType = kVideo_PluginType;
obj->activePlugin = new VideoPlugin(instance);
}
gLogI.log(kDebug_ANPLogType, "------ %p PluginType is %d", instance, obj->pluginType);
break;
}
}
// if no pluginType is specified then default to Animation
if (!obj->pluginType) {
gLogI.log(kError_ANPLogType, "------ %p No PluginType attribute was found", instance);
obj->pluginType = kAnimation_PluginType;
obj->activePlugin = new BallAnimation(instance);
}
// check to ensure the pluginType supports the model
if (!obj->activePlugin->supportsDrawingModel(model)) {
gLogI.log(kError_ANPLogType, "------ %p Unsupported DrawingModel (%d)", instance, model);
return NPERR_GENERIC_ERROR;
}
// if the plugin uses the surface drawing model then set the java context
if (model == kSurface_ANPDrawingModel) {
SurfaceSubPlugin* surfacePlugin = static_cast<SurfaceSubPlugin*>(obj->activePlugin);
jobject context;
NPError err = browser->getvalue(instance, kJavaContext_ANPGetValue,
static_cast<void*>(&context));
if (err) {
gLogI.log(kError_ANPLogType, "request context err: %d", err);
return err;
}
surfacePlugin->setContext(context);
}
return NPERR_NO_ERROR;
}
NPError NPP_Destroy(NPP instance, NPSavedData** save)
{
PluginObject *obj = (PluginObject*) instance->pdata;
if (obj) {
delete obj->activePlugin;
browser->releaseobject(&obj->header);
}
return NPERR_NO_ERROR;
}
NPError NPP_SetWindow(NPP instance, NPWindow* window)
{
PluginObject *obj = (PluginObject*) instance->pdata;
// Do nothing if browser didn't support NPN_CreateObject which would have created the PluginObject.
if (obj != NULL) {
obj->window = window;
}
browser->invalidaterect(instance, NULL);
return NPERR_NO_ERROR;
}
NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
{
*stype = NP_ASFILEONLY;
return NPERR_NO_ERROR;
}
NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
{
return NPERR_NO_ERROR;
}
int32 NPP_WriteReady(NPP instance, NPStream* stream)
{
return 0;
}
int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
{
return 0;
}
void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
{
}
void NPP_Print(NPP instance, NPPrint* platformPrint)
{
}
int16 NPP_HandleEvent(NPP instance, void* event)
{
PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
const ANPEvent* evt = reinterpret_cast<const ANPEvent*>(event);
#if DEBUG_PLUGIN_EVENTS
switch (evt->eventType) {
case kDraw_ANPEventType:
if (evt->data.draw.model == kBitmap_ANPDrawingModel) {
static ANPBitmapFormat currentFormat = -1;
if (evt->data.draw.data.bitmap.format != currentFormat) {
currentFormat = evt->data.draw.data.bitmap.format;
gLogI.log(kDebug_ANPLogType, "---- %p Draw (bitmap)"
" clip=%d,%d,%d,%d format=%d", instance,
evt->data.draw.clip.left,
evt->data.draw.clip.top,
evt->data.draw.clip.right,
evt->data.draw.clip.bottom,
evt->data.draw.data.bitmap.format);
}
}
break;
case kKey_ANPEventType:
gLogI.log(kDebug_ANPLogType, "---- %p Key action=%d"
" code=%d vcode=%d unichar=%d repeat=%d mods=%x", instance,
evt->data.key.action,
evt->data.key.nativeCode,
evt->data.key.virtualCode,
evt->data.key.unichar,
evt->data.key.repeatCount,
evt->data.key.modifiers);
break;
case kLifecycle_ANPEventType:
gLogI.log(kDebug_ANPLogType, "---- %p Lifecycle action=%d",
instance, evt->data.lifecycle.action);
break;
case kTouch_ANPEventType:
gLogI.log(kDebug_ANPLogType, "---- %p Touch action=%d [%d %d]",
instance, evt->data.touch.action, evt->data.touch.x,
evt->data.touch.y);
break;
case kMouse_ANPEventType:
gLogI.log(kDebug_ANPLogType, "---- %p Mouse action=%d [%d %d]",
instance, evt->data.mouse.action, evt->data.mouse.x,
evt->data.mouse.y);
break;
case kVisibleRect_ANPEventType:
gLogI.log(kDebug_ANPLogType, "---- %p VisibleRect [%d %d %d %d]",
instance, evt->data.visibleRect.rect.left, evt->data.visibleRect.rect.top,
evt->data.visibleRect.rect.right, evt->data.visibleRect.rect.bottom);
break;
default:
gLogI.log(kError_ANPLogType, "---- %p Unknown Event [%d]",
instance, evt->eventType);
break;
}
#endif
if(!obj->activePlugin) {
gLogI.log(kError_ANPLogType, "the active plugin is null.");
return 0; // unknown or unhandled event
}
else {
return obj->activePlugin->handleEvent(evt);
}
}
void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
{
}
EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value) {
if (variable == NPPVpluginNameString) {
const char **str = (const char **)value;
*str = "Test Plugin";
return NPERR_NO_ERROR;
}
if (variable == NPPVpluginDescriptionString) {
const char **str = (const char **)value;
*str = "Description of Test Plugin";
return NPERR_NO_ERROR;
}
return NPERR_GENERIC_ERROR;
}
NPError NPP_GetValue(NPP instance, NPPVariable variable, void* value)
{
if (variable == NPPVpluginScriptableNPObject) {
void **v = (void **)value;
PluginObject *obj = (PluginObject*) instance->pdata;
if (obj)
browser->retainobject(&obj->header);
*v = &(obj->header);
return NPERR_NO_ERROR;
}
if (variable == kJavaSurface_ANPGetValue) {
//get the surface sub-plugin
PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
if (obj && obj->activePlugin) {
if(obj->activePlugin->supportsDrawingModel(kSurface_ANPDrawingModel)) {
SurfaceSubPlugin* plugin = static_cast<SurfaceSubPlugin*>(obj->activePlugin);
jobject* surface = static_cast<jobject*>(value);
*surface = plugin->getSurface();
return NPERR_NO_ERROR;
} else {
gLogI.log(kError_ANPLogType,
"-- %p Tried to retrieve surface for non-surface plugin",
instance);
}
}
}
return NPERR_GENERIC_ERROR;
}
NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
{
return NPERR_GENERIC_ERROR;
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <npapi.h>
#include <npfunctions.h>
#include <npruntime.h>
#include "android_npapi.h"
#include "ANPSurface_npapi.h"
#include "ANPSystem_npapi.h"
extern NPNetscapeFuncs* browser;
extern JavaVM* gVM;

View File

@@ -1,242 +0,0 @@
/*
* Copyright 2010, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "NavigationPlugin.h"
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <math.h>
#include <string.h>
extern NPNetscapeFuncs* browser;
extern ANPLogInterfaceV0 gLogI;
extern ANPCanvasInterfaceV0 gCanvasI;
extern ANPPaintInterfaceV0 gPaintI;
extern ANPTypefaceInterfaceV0 gTypefaceI;
extern ANPWindowInterfaceV0 gWindowI;
static void inval(NPP instance) {
browser->invalidaterect(instance, NULL);
}
static uint16 rnd16(float x, int inset) {
int ix = (int)roundf(x) + inset;
if (ix < 0) {
ix = 0;
}
return static_cast<uint16>(ix);
}
static void inval(NPP instance, const ANPRectF& r, bool doAA) {
const int inset = doAA ? -1 : 0;
PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
NPRect inval;
inval.left = rnd16(r.left, inset);
inval.top = rnd16(r.top, inset);
inval.right = rnd16(r.right, -inset);
inval.bottom = rnd16(r.bottom, -inset);
browser->invalidaterect(instance, &inval);
}
///////////////////////////////////////////////////////////////////////////////
NavigationPlugin::NavigationPlugin(NPP inst) : SubPlugin(inst) {
m_hasFocus = false;
m_activeNav = NULL;
m_paintDisabled = gPaintI.newPaint();
gPaintI.setFlags(m_paintDisabled, gPaintI.getFlags(m_paintDisabled) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(m_paintDisabled, 0xFFFFFFFF);
m_paintActive = gPaintI.newPaint();
gPaintI.setFlags(m_paintActive, gPaintI.getFlags(m_paintActive) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(m_paintActive, 0xFFFFFF00);
//register for key events
ANPEventFlags flags = kKey_ANPEventFlag;
NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
if (err != NPERR_NO_ERROR) {
gLogI.log(kError_ANPLogType, "Error selecting input events.");
}
}
NavigationPlugin::~NavigationPlugin() {
gPaintI.deletePaint(m_paintDisabled);
gPaintI.deletePaint(m_paintActive);
}
bool NavigationPlugin::supportsDrawingModel(ANPDrawingModel model) {
return (model == kBitmap_ANPDrawingModel);
}
void NavigationPlugin::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
ANPRectF clipR;
clipR.left = clip.left;
clipR.top = clip.top;
clipR.right = clip.right;
clipR.bottom = clip.bottom;
gCanvasI.clipRect(canvas, &clipR);
draw(canvas);
gCanvasI.deleteCanvas(canvas);
}
void NavigationPlugin::draw(ANPCanvas* canvas) {
NPP instance = this->inst();
PluginObject *obj = (PluginObject*) instance->pdata;
const int W = obj->window->width;
const int H = obj->window->height;
const int Wm = W/2;
const int Hm = H/2;
// color the plugin canvas
gCanvasI.drawColor(canvas, (m_hasFocus) ? 0xFFCDCDCD : 0xFF545454);
// draw the nav up box (5 px from the top edge)
m_navUp.left = Wm - 15;
m_navUp.top = 5;
m_navUp.right = m_navUp.left + 30;
m_navUp.bottom = m_navUp.top + 30;
gCanvasI.drawRect(canvas, &m_navUp, getPaint(&m_navUp));
// draw the nav down box (5 px from the bottom edge)
m_navDown.left = Wm - 15;
m_navDown.top = H - (30 + 5);
m_navDown.right = m_navDown.left + 30;
m_navDown.bottom = m_navDown.top + 30;
gCanvasI.drawRect(canvas, &m_navDown, getPaint(&m_navDown));
// draw the nav left box (5 px from the left edge)
m_navLeft.left = 5;
m_navLeft.top = Hm - 15;
m_navLeft.right = m_navLeft.left + 30;
m_navLeft.bottom = m_navLeft.top + 30;
gCanvasI.drawRect(canvas, &m_navLeft, getPaint(&m_navLeft));
// draw the nav right box (5 px from the right edge)
m_navRight.left = W - (30 + 5);
m_navRight.top = Hm - 15;
m_navRight.right = m_navRight.left + 30;
m_navRight.bottom = m_navRight.top + 30;
gCanvasI.drawRect(canvas, &m_navRight, getPaint(&m_navRight));
// draw the nav center box
m_navCenter.left = Wm - 15;
m_navCenter.top = Hm - 15;
m_navCenter.right = m_navCenter.left + 30;
m_navCenter.bottom = m_navCenter.top + 30;
gCanvasI.drawRect(canvas, &m_navCenter, getPaint(&m_navCenter));
gLogI.log(kDebug_ANPLogType, "----%p Drawing Plugin", inst());
}
ANPPaint* NavigationPlugin::getPaint(ANPRectF* input) {
return (input == m_activeNav) ? m_paintActive : m_paintDisabled;
}
int16 NavigationPlugin::handleEvent(const ANPEvent* evt) {
NPP instance = this->inst();
switch (evt->eventType) {
case kDraw_ANPEventType:
switch (evt->data.draw.model) {
case kBitmap_ANPDrawingModel:
drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
return 1;
default:
break; // unknown drawing model
}
break;
case kLifecycle_ANPEventType:
if (evt->data.lifecycle.action == kLoseFocus_ANPLifecycleAction) {
gLogI.log(kDebug_ANPLogType, "----%p Loosing Focus", instance);
m_hasFocus = false;
inval(instance);
return 1;
}
else if (evt->data.lifecycle.action == kGainFocus_ANPLifecycleAction) {
gLogI.log(kDebug_ANPLogType, "----%p Gaining Focus", instance);
m_hasFocus = true;
inval(instance);
return 1;
}
break;
case kMouse_ANPEventType:
return 1;
case kKey_ANPEventType:
if (evt->data.key.action == kDown_ANPKeyAction) {
bool result = handleNavigation(evt->data.key.nativeCode);
inval(instance);
return result;
}
return 1;
default:
break;
}
return 0; // unknown or unhandled event
}
bool NavigationPlugin::handleNavigation(ANPKeyCode keyCode) {
NPP instance = this->inst();
gLogI.log(kDebug_ANPLogType, "----%p Received Key %d", instance, keyCode);
switch (keyCode) {
case kDpadUp_ANPKeyCode:
m_activeNav = &m_navUp;
break;
case kDpadDown_ANPKeyCode:
m_activeNav = &m_navDown;
break;
case kDpadLeft_ANPKeyCode:
m_activeNav = &m_navLeft;
break;
case kDpadRight_ANPKeyCode:
m_activeNav = &m_navRight;
break;
case kDpadCenter_ANPKeyCode:
m_activeNav = &m_navCenter;
break;
case kQ_ANPKeyCode:
case kDel_ANPKeyCode:
m_activeNav = NULL;
return false;
default:
m_activeNav = NULL;
break;
}
return true;
}

View File

@@ -1,57 +0,0 @@
/*
* Copyright 2010, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "PluginObject.h"
#ifndef navigationPlugin__DEFINED
#define navigationPlugin__DEFINED
class NavigationPlugin : public SubPlugin {
public:
NavigationPlugin(NPP inst);
virtual ~NavigationPlugin();
virtual bool supportsDrawingModel(ANPDrawingModel);
virtual int16 handleEvent(const ANPEvent* evt);
private:
void draw(ANPCanvas*);
void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
bool m_hasFocus;
ANPRectF* m_activeNav;
ANPRectF m_navUp;
ANPRectF m_navDown;
ANPRectF m_navLeft;
ANPRectF m_navRight;
ANPRectF m_navCenter;
ANPPaint* m_paintDisabled;
ANPPaint* m_paintActive;
bool handleNavigation(ANPKeyCode keyCode);
ANPPaint* getPaint(ANPRectF*);
};
#endif // navigationPlugin__DEFINED

View File

@@ -1,462 +0,0 @@
/*
* Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "PaintPlugin.h"
#include <fcntl.h>
#include <math.h>
#include <string.h>
extern NPNetscapeFuncs* browser;
extern ANPLogInterfaceV0 gLogI;
extern ANPCanvasInterfaceV0 gCanvasI;
extern ANPPaintInterfaceV0 gPaintI;
extern ANPPathInterfaceV0 gPathI;
extern ANPSurfaceInterfaceV0 gSurfaceI;
extern ANPSystemInterfaceV0 gSystemI;
extern ANPTypefaceInterfaceV0 gTypefaceI;
extern ANPWindowInterfaceV0 gWindowI;
///////////////////////////////////////////////////////////////////////////////
PaintPlugin::PaintPlugin(NPP inst) : SurfaceSubPlugin(inst) {
m_isTouchActive = false;
m_isTouchCurrentInput = true;
m_activePaintColor = s_redColor;
memset(&m_drawingSurface, 0, sizeof(m_drawingSurface));
memset(&m_inputToggle, 0, sizeof(m_inputToggle));
memset(&m_colorToggle, 0, sizeof(m_colorToggle));
memset(&m_fullScreenToggle, 0, sizeof(m_fullScreenToggle));
memset(&m_clearSurface, 0, sizeof(m_clearSurface));
// initialize the drawing surface
m_surface = NULL;
// initialize the path
m_touchPath = gPathI.newPath();
if(!m_touchPath)
gLogI.log(kError_ANPLogType, "----%p Unable to create the touch path", inst);
// initialize the paint colors
m_paintSurface = gPaintI.newPaint();
gPaintI.setFlags(m_paintSurface, gPaintI.getFlags(m_paintSurface) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(m_paintSurface, 0xFFC0C0C0);
gPaintI.setTextSize(m_paintSurface, 18);
m_paintButton = gPaintI.newPaint();
gPaintI.setFlags(m_paintButton, gPaintI.getFlags(m_paintButton) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(m_paintButton, 0xFFA8A8A8);
// initialize the typeface (set the colors)
ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
gPaintI.setTypeface(m_paintSurface, tf);
gTypefaceI.unref(tf);
//register for touch events
ANPEventFlags flags = kTouch_ANPEventFlag;
NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
if (err != NPERR_NO_ERROR) {
gLogI.log(kError_ANPLogType, "Error selecting input events.");
}
}
PaintPlugin::~PaintPlugin() {
gPathI.deletePath(m_touchPath);
gPaintI.deletePaint(m_paintSurface);
gPaintI.deletePaint(m_paintButton);
setContext(NULL);
destroySurface();
}
ANPCanvas* PaintPlugin::getCanvas(ANPRectI* dirtyRect) {
ANPBitmap bitmap;
JNIEnv* env = NULL;
if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
!gSurfaceI.lock(env, m_surface, &bitmap, dirtyRect)) {
return NULL;
}
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
// clip the canvas to the dirty rect b/c the surface is only required to
// copy a minimum of the dirty rect and may copy more. The clipped canvas
// however will never write to pixels outside of the clipped area.
if (dirtyRect) {
ANPRectF clipR;
clipR.left = dirtyRect->left;
clipR.top = dirtyRect->top;
clipR.right = dirtyRect->right;
clipR.bottom = dirtyRect->bottom;
gCanvasI.clipRect(canvas, &clipR);
}
return canvas;
}
ANPCanvas* PaintPlugin::getCanvas(ANPRectF* dirtyRect) {
ANPRectI newRect;
newRect.left = (int) dirtyRect->left;
newRect.top = (int) dirtyRect->top;
newRect.right = (int) dirtyRect->right;
newRect.bottom = (int) dirtyRect->bottom;
return getCanvas(&newRect);
}
void PaintPlugin::releaseCanvas(ANPCanvas* canvas) {
JNIEnv* env = NULL;
if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
gSurfaceI.unlock(env, m_surface);
}
gCanvasI.deleteCanvas(canvas);
}
void PaintPlugin::drawCleanPlugin(ANPCanvas* canvas) {
NPP instance = this->inst();
PluginObject *obj = (PluginObject*) instance->pdata;
// if no canvas get a locked canvas
if (!canvas)
canvas = getCanvas();
if (!canvas)
return;
const float buttonWidth = 60;
const float buttonHeight = 30;
const int W = obj->window->width;
const int H = obj->window->height;
// color the plugin canvas
gCanvasI.drawColor(canvas, 0xFFCDCDCD);
// get font metrics
ANPFontMetrics fontMetrics;
gPaintI.getFontMetrics(m_paintSurface, &fontMetrics);
// draw the input toggle button
m_inputToggle.left = 5;
m_inputToggle.top = H - buttonHeight - 5;
m_inputToggle.right = m_inputToggle.left + buttonWidth;
m_inputToggle.bottom = m_inputToggle.top + buttonHeight;
gCanvasI.drawRect(canvas, &m_inputToggle, m_paintButton);
const char* inputText = m_isTouchCurrentInput ? "Touch" : "Mouse";
gCanvasI.drawText(canvas, inputText, strlen(inputText), m_inputToggle.left + 5,
m_inputToggle.top - fontMetrics.fTop, m_paintSurface);
// draw the color selector button
m_colorToggle.left = (W/3) - (buttonWidth/2);
m_colorToggle.top = H - buttonHeight - 5;
m_colorToggle.right = m_colorToggle.left + buttonWidth;
m_colorToggle.bottom = m_colorToggle.top + buttonHeight;
gCanvasI.drawRect(canvas, &m_colorToggle, m_paintButton);
const char* colorText = getColorText();
gCanvasI.drawText(canvas, colorText, strlen(colorText), m_colorToggle.left + 5,
m_colorToggle.top - fontMetrics.fTop, m_paintSurface);
// draw the full-screen toggle button
m_fullScreenToggle.left = ((W*2)/3) - (buttonWidth/2);
m_fullScreenToggle.top = H - buttonHeight - 5;
m_fullScreenToggle.right = m_fullScreenToggle.left + buttonWidth;
m_fullScreenToggle.bottom = m_fullScreenToggle.top + buttonHeight;
gCanvasI.drawRect(canvas, &m_fullScreenToggle, m_paintButton);
const char* fullScreenText = "Full";
gCanvasI.drawText(canvas, fullScreenText, strlen(fullScreenText),
m_fullScreenToggle.left + 5,
m_fullScreenToggle.top - fontMetrics.fTop, m_paintSurface);
// draw the clear canvas button
m_clearSurface.left = W - buttonWidth - 5;
m_clearSurface.top = H - buttonHeight - 5;
m_clearSurface.right = m_clearSurface.left + buttonWidth;
m_clearSurface.bottom = m_clearSurface.top + buttonHeight;
gCanvasI.drawRect(canvas, &m_clearSurface, m_paintButton);
const char* clearText = "Clear";
gCanvasI.drawText(canvas, clearText, strlen(clearText), m_clearSurface.left + 5,
m_clearSurface.top - fontMetrics.fTop, m_paintSurface);
// draw the drawing surface box (5 px from the edge)
m_drawingSurface.left = 5;
m_drawingSurface.top = 5;
m_drawingSurface.right = W - 5;
m_drawingSurface.bottom = m_colorToggle.top - 5;
gCanvasI.drawRect(canvas, &m_drawingSurface, m_paintSurface);
// release the canvas
releaseCanvas(canvas);
}
const char* PaintPlugin::getColorText() {
if (m_activePaintColor == s_blueColor)
return "Blue";
else if (m_activePaintColor == s_greenColor)
return "Green";
else
return "Red";
}
jobject PaintPlugin::getSurface() {
if (m_surface) {
return m_surface;
}
// load the appropriate java class and instantiate it
JNIEnv* env = NULL;
if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
return NULL;
}
const char* className = "com.android.sampleplugin.PaintSurface";
jclass paintClass = gSystemI.loadJavaClass(inst(), className);
if(!paintClass) {
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
return NULL;
}
PluginObject *obj = (PluginObject*) inst()->pdata;
const int pW = obj->window->width;
const int pH = obj->window->height;
jmethodID constructor = env->GetMethodID(paintClass, "<init>", "(Landroid/content/Context;III)V");
jobject paintSurface = env->NewObject(paintClass, constructor, m_context, (int)inst(), pW, pH);
if(!paintSurface) {
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
return NULL;
}
m_surface = env->NewGlobalRef(paintSurface);
return m_surface;
}
void PaintPlugin::destroySurface() {
JNIEnv* env = NULL;
if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
// detach the native code from the object
jclass javaClass = env->GetObjectClass(m_surface);
jmethodID invalMethod = env->GetMethodID(javaClass, "invalidateNPP", "()V");
env->CallVoidMethod(m_surface, invalMethod);
env->DeleteGlobalRef(m_surface);
m_surface = NULL;
}
}
int16 PaintPlugin::handleEvent(const ANPEvent* evt) {
switch (evt->eventType) {
case kTouch_ANPEventType: {
float x = (float) evt->data.touch.x;
float y = (float) evt->data.touch.y;
if (kDown_ANPTouchAction == evt->data.touch.action && m_isTouchCurrentInput) {
ANPRectF* rect = validTouch(evt->data.touch.x, evt->data.touch.y);
if(rect == &m_drawingSurface) {
m_isTouchActive = true;
gPathI.moveTo(m_touchPath, x, y);
paintTouch();
return 1;
}
} else if (kMove_ANPTouchAction == evt->data.touch.action && m_isTouchActive) {
gPathI.lineTo(m_touchPath, x, y);
paintTouch();
return 1;
} else if (kUp_ANPTouchAction == evt->data.touch.action && m_isTouchActive) {
gPathI.lineTo(m_touchPath, x, y);
paintTouch();
m_isTouchActive = false;
gPathI.reset(m_touchPath);
return 1;
} else if (kCancel_ANPTouchAction == evt->data.touch.action) {
m_isTouchActive = false;
gPathI.reset(m_touchPath);
return 1;
} else if (kDoubleTap_ANPTouchAction == evt->data.touch.action) {
gWindowI.requestCenterFitZoom(inst());
return 1;
}
break;
}
case kMouse_ANPEventType: {
if (m_isTouchActive)
gLogI.log(kError_ANPLogType, "----%p Received unintended mouse event", inst());
if (kDown_ANPMouseAction == evt->data.mouse.action) {
ANPRectF* rect = validTouch(evt->data.mouse.x, evt->data.mouse.y);
if (rect == &m_drawingSurface)
paintMouse(evt->data.mouse.x, evt->data.mouse.y);
else if (rect == &m_inputToggle)
toggleInputMethod();
else if (rect == &m_colorToggle)
togglePaintColor();
else if (rect == &m_fullScreenToggle)
gWindowI.requestFullScreen(inst());
else if (rect == &m_clearSurface)
drawCleanPlugin();
}
return 1;
}
case kCustom_ANPEventType: {
switch (evt->data.other[0]) {
case kSurfaceCreated_CustomEvent:
gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceCreated");
/* The second draw call is added to cover up a problem in this
plugin and is not a recommended usage pattern. This plugin
does not correctly make partial updates to the double
buffered surface and this second call hides that problem.
*/
drawCleanPlugin();
drawCleanPlugin();
break;
case kSurfaceChanged_CustomEvent: {
gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceChanged");
int width = evt->data.other[1];
int height = evt->data.other[2];
PluginObject *obj = (PluginObject*) inst()->pdata;
const int pW = obj->window->width;
const int pH = obj->window->height;
// compare to the plugin's surface dimensions
if (pW != width || pH != height)
gLogI.log(kError_ANPLogType,
"----%p Invalid Surface Dimensions (%d,%d):(%d,%d)",
inst(), pW, pH, width, height);
break;
}
case kSurfaceDestroyed_CustomEvent:
gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceDestroyed");
break;
}
break; // end KCustom_ANPEventType
}
default:
break;
}
return 0; // unknown or unhandled event
}
ANPRectF* PaintPlugin::validTouch(int x, int y) {
//convert to float
float fx = (int) x;
float fy = (int) y;
if (fx > m_drawingSurface.left && fx < m_drawingSurface.right && fy > m_drawingSurface.top && fy < m_drawingSurface.bottom)
return &m_drawingSurface;
else if (fx > m_inputToggle.left && fx < m_inputToggle.right && fy > m_inputToggle.top && fy < m_inputToggle.bottom)
return &m_inputToggle;
else if (fx > m_colorToggle.left && fx < m_colorToggle.right && fy > m_colorToggle.top && fy < m_colorToggle.bottom)
return &m_colorToggle;
else if (fx > m_fullScreenToggle.left && fx < m_fullScreenToggle.right && fy > m_fullScreenToggle.top && fy < m_fullScreenToggle.bottom)
return &m_fullScreenToggle;
else if (fx > m_clearSurface.left && fx < m_clearSurface.right && fy > m_clearSurface.top && fy < m_clearSurface.bottom)
return &m_clearSurface;
else
return NULL;
}
void PaintPlugin::toggleInputMethod() {
m_isTouchCurrentInput = !m_isTouchCurrentInput;
// lock only the input toggle and redraw the canvas
ANPCanvas* lockedCanvas = getCanvas(&m_inputToggle);
drawCleanPlugin(lockedCanvas);
}
void PaintPlugin::togglePaintColor() {
if (m_activePaintColor == s_blueColor)
m_activePaintColor = s_redColor;
else if (m_activePaintColor == s_greenColor)
m_activePaintColor = s_blueColor;
else
m_activePaintColor = s_greenColor;
// lock only the color toggle and redraw the canvas
ANPCanvas* lockedCanvas = getCanvas(&m_colorToggle);
drawCleanPlugin(lockedCanvas);
}
void PaintPlugin::paintMouse(int x, int y) {
//TODO do not paint outside the drawing surface
//create the paint color
ANPPaint* fillPaint = gPaintI.newPaint();
gPaintI.setFlags(fillPaint, gPaintI.getFlags(fillPaint) | kAntiAlias_ANPPaintFlag);
gPaintI.setStyle(fillPaint, kFill_ANPPaintStyle);
gPaintI.setColor(fillPaint, m_activePaintColor);
// handle the simple "mouse" paint (draw a point)
ANPRectF point;
point.left = (float) x-3;
point.top = (float) y-3;
point.right = (float) x+3;
point.bottom = (float) y+3;
// get a canvas that is only locked around the point and draw it
ANPCanvas* canvas = getCanvas(&point);
gCanvasI.drawOval(canvas, &point, fillPaint);
// clean up
releaseCanvas(canvas);
gPaintI.deletePaint(fillPaint);
}
void PaintPlugin::paintTouch() {
//TODO do not paint outside the drawing surface
//create the paint color
ANPPaint* strokePaint = gPaintI.newPaint();
gPaintI.setFlags(strokePaint, gPaintI.getFlags(strokePaint) | kAntiAlias_ANPPaintFlag);
gPaintI.setColor(strokePaint, m_activePaintColor);
gPaintI.setStyle(strokePaint, kStroke_ANPPaintStyle);
gPaintI.setStrokeWidth(strokePaint, 6.0);
gPaintI.setStrokeCap(strokePaint, kRound_ANPPaintCap);
gPaintI.setStrokeJoin(strokePaint, kRound_ANPPaintJoin);
// handle the complex "touch" paint (draw a line)
ANPRectF bounds;
gPathI.getBounds(m_touchPath, &bounds);
// get a canvas that is only locked around the point and draw the path
ANPCanvas* canvas = getCanvas(&bounds);
gCanvasI.drawPath(canvas, m_touchPath, strokePaint);
// clean up
releaseCanvas(canvas);
gPaintI.deletePaint(strokePaint);
}

View File

@@ -1,73 +0,0 @@
/*
* Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "PluginObject.h"
#include <stdio.h>
#ifndef paintPlugin__DEFINED
#define paintPlugin__DEFINED
class PaintPlugin : public SurfaceSubPlugin {
public:
PaintPlugin(NPP inst);
virtual ~PaintPlugin();
virtual int16 handleEvent(const ANPEvent* evt);
virtual jobject getSurface();
private:
void drawCleanPlugin(ANPCanvas* canvas = NULL);
ANPCanvas* getCanvas(ANPRectI* dirtyRect = NULL);
ANPCanvas* getCanvas(ANPRectF* dirtyRect);
const char* getColorText();
void destroySurface();
void paintMouse(int x, int y);
void paintTouch();
void releaseCanvas(ANPCanvas*);
void toggleInputMethod();
void togglePaintColor();
ANPRectF* validTouch(int x, int y);
bool m_isTouchActive;
bool m_isTouchCurrentInput;
jobject m_surface;
ANPPath* m_touchPath;
ANPRectF m_drawingSurface;
ANPRectF m_inputToggle;
ANPRectF m_colorToggle;
ANPRectF m_fullScreenToggle;
ANPRectF m_clearSurface;
ANPPaint* m_paintSurface;
ANPPaint* m_paintButton;
ANPColor m_activePaintColor;
static const ANPColor s_redColor = 0xFFFF0000;
static const ANPColor s_greenColor = 0xFF00FF00;
static const ANPColor s_blueColor = 0xFF0000FF;
};
#endif // paintPlugin__DEFINED

View File

@@ -1,135 +0,0 @@
/*
* Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "VideoPlugin.h"
#include "android_npapi.h"
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <math.h>
#include <string.h>
extern NPNetscapeFuncs* browser;
extern ANPBitmapInterfaceV0 gBitmapI;
extern ANPCanvasInterfaceV0 gCanvasI;
extern ANPLogInterfaceV0 gLogI;
extern ANPPaintInterfaceV0 gPaintI;
extern ANPSurfaceInterfaceV0 gSurfaceI;
extern ANPSystemInterfaceV0 gSystemI;
extern ANPTypefaceInterfaceV0 gTypefaceI;
extern ANPWindowInterfaceV0 gWindowI;
///////////////////////////////////////////////////////////////////////////////
VideoPlugin::VideoPlugin(NPP inst) : SurfaceSubPlugin(inst) {
// initialize the drawing surface
m_surface = NULL;
//register for touch events
ANPEventFlags flags = kTouch_ANPEventFlag;
NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
if (err != NPERR_NO_ERROR) {
gLogI.log(kError_ANPLogType, "Error selecting input events.");
}
}
VideoPlugin::~VideoPlugin() {
setContext(NULL);
destroySurface();
}
jobject VideoPlugin::getSurface() {
if (m_surface) {
return m_surface;
}
// load the appropriate java class and instantiate it
JNIEnv* env = NULL;
if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
return NULL;
}
const char* className = "com.android.sampleplugin.VideoSurface";
jclass videoClass = gSystemI.loadJavaClass(inst(), className);
if(!videoClass) {
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
return NULL;
}
jmethodID constructor = env->GetMethodID(videoClass, "<init>", "(Landroid/content/Context;)V");
jobject videoSurface = env->NewObject(videoClass, constructor, m_context);
if(!videoSurface) {
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
return NULL;
}
m_surface = env->NewGlobalRef(videoSurface);
return m_surface;
}
void VideoPlugin::destroySurface() {
JNIEnv* env = NULL;
if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
env->DeleteGlobalRef(m_surface);
m_surface = NULL;
}
}
int16 VideoPlugin::handleEvent(const ANPEvent* evt) {
switch (evt->eventType) {
case kLifecycle_ANPEventType: {
switch (evt->data.lifecycle.action) {
case kEnterFullScreen_ANPLifecycleAction:
gLogI.log(kDebug_ANPLogType, " ---- %p entering fullscreen", inst());
break;
case kExitFullScreen_ANPLifecycleAction:
gLogI.log(kDebug_ANPLogType, " ---- %p exiting fullscreen", inst());
break;
}
break; // end kLifecycle_ANPEventType
}
case kDraw_ANPEventType:
gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request draw events", inst());
break;
case kTouch_ANPEventType:
if (kDown_ANPTouchAction == evt->data.touch.action) {
gLogI.log(kDebug_ANPLogType, " ------ %p requesting fullscreen mode", inst());
gWindowI.requestFullScreen(inst());
}
return 1;
case kKey_ANPEventType:
gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request key events", inst());
break;
default:
break;
}
return 0; // unknown or unhandled event
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "PluginObject.h"
#ifndef videoPlugin__DEFINED
#define videoPlugin__DEFINED
class VideoPlugin : public SurfaceSubPlugin {
public:
VideoPlugin(NPP inst);
virtual ~VideoPlugin();
virtual int16 handleEvent(const ANPEvent* evt);
virtual jobject getSurface();
private:
void destroySurface();
jobject m_surface;
};
#endif // videoPlugin__DEFINED

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-->
<resources>
<string name="sample_browser_plugin">Sample Browser Plugin</string>
</resources>

View File

@@ -1,19 +0,0 @@
package com.android.sampleplugin;
import android.content.Context;
import android.graphics.Color;
import android.widget.TextView;
public class BackgroundSurface extends TextView {
public BackgroundSurface(Context context) {
super(context);
this.setBackgroundColor(Color.BLACK);
this.setTextColor(Color.WHITE);
this.setText("This is a java background plugin");
// ensure that the view system is aware that we will be drawing
this.setWillNotDraw(false);
}
}

View File

@@ -1,11 +0,0 @@
package com.android.sampleplugin;
public class BackgroundTest {
public BackgroundTest() {}
public int addInt(int x, int y) {
return x + y;
}
}

View File

@@ -1,95 +0,0 @@
/*
* Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.android.sampleplugin;
import android.content.Context;
import android.graphics.PixelFormat;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
public class PaintSurface extends SurfaceView {
static {
//needed for jni calls
System.loadLibrary("sampleplugin");
}
private final int npp;
private boolean validNPP = true;
private Object nppLock = new Object();
public PaintSurface(Context context, int NPP, int width, int height) {
super(context);
this.npp = NPP;
this.getHolder().setFormat(PixelFormat.RGBA_8888);
this.getHolder().addCallback(new Callback() {
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
synchronized (nppLock) {
if (validNPP) {
nativeSurfaceChanged(npp, format, width, height);
}
}
}
public void surfaceCreated(SurfaceHolder holder) {
synchronized (nppLock) {
if (validNPP) {
nativeSurfaceCreated(npp);
}
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
synchronized (nppLock) {
if (validNPP) {
nativeSurfaceDestroyed(npp);
}
}
}
});
// sets the plugin's surface to a fixed size
this.getHolder().setFixedSize(width, height);
// ensure that the view system is aware that we will be drawing
this.setWillNotDraw(false);
}
// called by JNI
private void invalidateNPP() {
synchronized (nppLock) {
validNPP = false;
}
}
private native void nativeSurfaceCreated(int npp);
private native void nativeSurfaceChanged(int npp, int format, int width, int height);
private native void nativeSurfaceDestroyed(int npp);
}

View File

@@ -1,38 +0,0 @@
/*
* Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.android.sampleplugin;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class SamplePlugin extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}

View File

@@ -1,67 +0,0 @@
/*
* Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.android.sampleplugin;
import com.android.sampleplugin.graphics.CubeRenderer;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.MediaController;
import android.widget.VideoView;
public class VideoSurface extends FrameLayout {
public VideoSurface(Context context) {
super(context);
LayoutParams fp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
this.setLayoutParams(fp);
// VideoView video = new VideoView(context);
// LayoutParams vp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
// vp.setLayoutParams(vp);
GLSurfaceView gl = new GLSurfaceView(context);
LayoutParams gp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
gl.setLayoutParams(gp);
this.addView(gl);
// this.addView(video);
// Tell the cube renderer that we want to render a translucent version
// of the cube:
gl.setRenderer(new CubeRenderer(false));
gl.setWindowType(WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY);
// video.setVideoPath("/sdcard/test_video.3gp");
// video.setMediaController(new MediaController(context));
// video.requestFocus();
// ensure that the view system is aware that we will be drawing
this.setWillNotDraw(false);
}
}

View File

@@ -1,100 +0,0 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.sampleplugin.graphics;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import javax.microedition.khronos.opengles.GL10;
/**
* A vertex shaded cube.
*/
class Cube
{
public Cube()
{
int one = 0x10000;
int vertices[] = {
-one, -one, -one,
one, -one, -one,
one, one, -one,
-one, one, -one,
-one, -one, one,
one, -one, one,
one, one, one,
-one, one, one,
};
int colors[] = {
0, 0, 0, one,
one, 0, 0, one,
one, one, 0, one,
0, one, 0, one,
0, 0, one, one,
one, 0, one, one,
one, one, one, one,
0, one, one, one,
};
byte indices[] = {
0, 4, 5, 0, 5, 1,
1, 5, 6, 1, 6, 2,
2, 6, 7, 2, 7, 3,
3, 7, 4, 3, 4, 0,
4, 7, 6, 4, 6, 5,
3, 0, 1, 3, 1, 2
};
// Buffers to be passed to gl*Pointer() functions
// must be direct, i.e., they must be placed on the
// native heap where the garbage collector cannot
// move them.
//
// Buffers with multi-byte datatypes (e.g., short, int, float)
// must have their byte order set to native order
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asIntBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
cbb.order(ByteOrder.nativeOrder());
mColorBuffer = cbb.asIntBuffer();
mColorBuffer.put(colors);
mColorBuffer.position(0);
mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
mIndexBuffer.put(indices);
mIndexBuffer.position(0);
}
public void draw(GL10 gl)
{
gl.glFrontFace(gl.GL_CW);
gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE, mIndexBuffer);
}
private IntBuffer mVertexBuffer;
private IntBuffer mColorBuffer;
private ByteBuffer mIndexBuffer;
}

View File

@@ -1,109 +0,0 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.sampleplugin.graphics;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView;
/**
* Render a pair of tumbling cubes.
*/
public class CubeRenderer implements GLSurfaceView.Renderer {
public CubeRenderer(boolean useTranslucentBackground) {
mTranslucentBackground = useTranslucentBackground;
mCube = new Cube();
}
public void onDrawFrame(GL10 gl) {
/*
* Usually, the first thing one might want to do is to clear
* the screen. The most efficient way of doing this is to use
* glClear().
*/
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
/*
* Now we're ready to draw some 3D objects
*/
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -3.0f);
gl.glRotatef(mAngle, 0, 1, 0);
gl.glRotatef(mAngle*0.25f, 1, 0, 0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
mCube.draw(gl);
gl.glRotatef(mAngle*2.0f, 0, 1, 1);
gl.glTranslatef(0.5f, 0.5f, 0.5f);
mCube.draw(gl);
mAngle += 1.2f;
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
/*
* Set our projection matrix. This doesn't have to be done
* each time we draw, but usually a new projection needs to
* be set when the viewport is resized.
*/
float ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
/*
* By default, OpenGL enables features that improve quality
* but reduce performance. One might want to tweak that
* especially on software renderer.
*/
gl.glDisable(GL10.GL_DITHER);
/*
* Some one-time OpenGL initialization can be made here
* probably based on features of this particular context
*/
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
GL10.GL_FASTEST);
if (mTranslucentBackground) {
gl.glClearColor(0,0,0,0);
} else {
gl.glClearColor(1,1,1,1);
}
gl.glEnable(GL10.GL_CULL_FACE);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
}
private boolean mTranslucentBackground;
private Cube mCube;
private float mAngle;
}