Merge "Fix sp<> conversion operator / constructor"
diff --git a/Android.mk b/Android.mk
index 08ee65e..6e41f96 100644
--- a/Android.mk
+++ b/Android.mk
@@ -188,6 +188,7 @@
telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl \
telephony/java/com/android/internal/telephony/ISms.aidl \
+ telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
wifi/java/android/net/wifi/IWifiManager.aidl \
telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl \
vpn/java/android/net/vpn/IVpnService.aidl \
diff --git a/api/11.xml b/api/11.xml
index 76669e3..8216491 100644
--- a/api/11.xml
+++ b/api/11.xml
@@ -90722,8 +90722,6 @@
>
<parameter name="surfaceTexture" type="android.graphics.SurfaceTexture">
</parameter>
-<exception name="IOException" type="java.io.IOException">
-</exception>
</method>
<method name="setZoomChangeListener"
return="void"
diff --git a/api/current.xml b/api/current.xml
index 872e627..6adf8aa 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -198789,6 +198789,23 @@
<parameter name="buffer" type="android.text.Spannable">
</parameter>
</method>
+<method name="onGenericMotionEvent"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="text" type="android.text.Spannable">
+</parameter>
+<parameter name="event" type="android.view.MotionEvent">
+</parameter>
+</method>
<method name="onKeyDown"
return="boolean"
abstract="false"
@@ -199862,6 +199879,23 @@
<parameter name="text" type="android.text.Spannable">
</parameter>
</method>
+<method name="onGenericMotionEvent"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="widget" type="android.widget.TextView">
+</parameter>
+<parameter name="text" type="android.text.Spannable">
+</parameter>
+<parameter name="event" type="android.view.MotionEvent">
+</parameter>
+</method>
<method name="onKeyDown"
return="boolean"
abstract="true"
@@ -206575,7 +206609,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="protected"
>
<parameter name="key" type="K">
@@ -206583,11 +206617,30 @@
<parameter name="value" type="V">
</parameter>
</method>
+<method name="entryRemoved"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="evicted" type="boolean">
+</parameter>
+<parameter name="key" type="K">
+</parameter>
+<parameter name="oldValue" type="V">
+</parameter>
+<parameter name="newValue" type="V">
+</parameter>
+</method>
<method name="evictAll"
return="void"
abstract="false"
native="false"
- synchronized="true"
+ synchronized="false"
static="false"
final="true"
deprecated="not deprecated"
@@ -206609,7 +206662,7 @@
return="V"
abstract="false"
native="false"
- synchronized="true"
+ synchronized="false"
static="false"
final="true"
deprecated="not deprecated"
@@ -206655,7 +206708,7 @@
return="V"
abstract="false"
native="false"
- synchronized="true"
+ synchronized="false"
static="false"
final="true"
deprecated="not deprecated"
@@ -206681,7 +206734,7 @@
return="V"
abstract="false"
native="false"
- synchronized="true"
+ synchronized="false"
static="false"
final="true"
deprecated="not deprecated"
@@ -217957,6 +218010,17 @@
visibility="public"
>
</field>
+<field name="ACTION_SCROLL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="ACTION_UP"
type="int"
transient="false"
@@ -224280,6 +224344,19 @@
<parameter name="l" type="android.view.View.OnFocusChangeListener">
</parameter>
</method>
+<method name="setOnGenericMotionListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="l" type="android.view.View.OnGenericMotionListener">
+</parameter>
+</method>
<method name="setOnKeyListener"
return="void"
abstract="false"
@@ -225983,6 +226060,29 @@
</parameter>
</method>
</interface>
+<interface name="View.OnGenericMotionListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onGenericMotion"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="v" type="android.view.View">
+</parameter>
+<parameter name="event" type="android.view.MotionEvent">
+</parameter>
+</method>
+</interface>
<interface name="View.OnKeyListener"
abstract="true"
static="true"
@@ -266533,7 +266633,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="t" type="T">
+<parameter name="arg0" type="T">
</parameter>
</method>
</interface>
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 178032d..1b13dd9 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -8,7 +8,7 @@
LOCAL_SHARED_LIBRARIES := \
libstagefright libmedia libutils libbinder libstagefright_foundation \
- libskia
+ libskia libsurfaceflinger_client libgui
LOCAL_C_INCLUDES:= \
$(JNI_H_INCLUDE) \
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index a43b190..a875c3a 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -55,6 +55,11 @@
#include <fcntl.h>
+#include <gui/SurfaceTextureClient.h>
+
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+
using namespace android;
static long gNumRepetitions;
@@ -66,6 +71,10 @@
static bool gDisplayHistogram;
static String8 gWriteMP4Filename;
+static sp<ANativeWindow> gSurface;
+
+#define USE_SURFACE_COMPOSER 0
+
static int64_t getNowUs() {
struct timeval tv;
gettimeofday(&tv, NULL);
@@ -138,7 +147,8 @@
rawSource = OMXCodec::Create(
client->interface(), meta, false /* createEncoder */, source,
NULL /* matchComponentName */,
- gPreferSoftwareCodec ? OMXCodec::kPreferSoftwareCodecs : 0);
+ gPreferSoftwareCodec ? OMXCodec::kPreferSoftwareCodecs : 0,
+ gSurface);
if (rawSource == NULL) {
fprintf(stderr, "Failed to instantiate decoder for '%s'.\n", mime);
@@ -540,6 +550,7 @@
fprintf(stderr, " -k seek test\n");
fprintf(stderr, " -x display a histogram of decoding times/fps "
"(video only)\n");
+ fprintf(stderr, " -S allocate buffers from a surface\n");
}
int main(int argc, char **argv) {
@@ -550,6 +561,7 @@
bool dumpProfiles = false;
bool extractThumbnail = false;
bool seekTest = false;
+ bool useSurfaceAlloc = false;
gNumRepetitions = 1;
gMaxNumFrames = 0;
gReproduceBug = -1;
@@ -563,7 +575,7 @@
sp<LiveSession> liveSession;
int res;
- while ((res = getopt(argc, argv, "han:lm:b:ptsow:kx")) >= 0) {
+ while ((res = getopt(argc, argv, "han:lm:b:ptsow:kxS")) >= 0) {
switch (res) {
case 'a':
{
@@ -642,6 +654,12 @@
break;
}
+ case 'S':
+ {
+ useSurfaceAlloc = true;
+ break;
+ }
+
case '?':
case 'h':
default:
@@ -780,6 +798,39 @@
}
}
+ sp<SurfaceComposerClient> composerClient;
+ sp<SurfaceControl> control;
+
+ if (useSurfaceAlloc && !audioOnly) {
+#if USE_SURFACE_COMPOSER
+ composerClient = new SurfaceComposerClient;
+ CHECK_EQ(composerClient->initCheck(), (status_t)OK);
+
+ control = composerClient->createSurface(
+ getpid(),
+ String8("A Surface"),
+ 0,
+ 1280,
+ 800,
+ PIXEL_FORMAT_RGB_565,
+ 0);
+
+ CHECK(control != NULL);
+ CHECK(control->isValid());
+
+ CHECK_EQ(composerClient->openTransaction(), (status_t)OK);
+ CHECK_EQ(control->setLayer(30000), (status_t)OK);
+ CHECK_EQ(control->show(), (status_t)OK);
+ CHECK_EQ(composerClient->closeTransaction(), (status_t)OK);
+
+ gSurface = control->getSurface();
+ CHECK(gSurface != NULL);
+#else
+ sp<SurfaceTexture> texture = new SurfaceTexture(0 /* tex */);
+ gSurface = new SurfaceTextureClient(texture);
+#endif
+ }
+
DataSource::RegisterDefaultSniffers();
OMXClient client;
@@ -957,6 +1008,14 @@
}
}
+ if (useSurfaceAlloc && !audioOnly) {
+ gSurface.clear();
+
+#if USE_SURFACE_COMPOSER
+ composerClient->dispose();
+#endif
+ }
+
client.disconnect();
return 0;
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 67e4806..9e72c1b 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2122,24 +2122,21 @@
* Called when a generic motion event was not handled by any of the
* views inside of the activity.
* <p>
- * Generic motion events are dispatched to the focused view to describe
- * the motions of input devices such as joysticks. The
+ * Generic motion events describe joystick movements, mouse hovers, track pad
+ * touches, scroll wheel movements and other input events. The
* {@link MotionEvent#getSource() source} of the motion event specifies
* the class of input that was received. Implementations of this method
* must examine the bits in the source before processing the event.
* The following code example shows how this is done.
+ * </p><p>
+ * Generic motion events with source class
+ * {@link android.view.InputDevice#SOURCE_CLASS_POINTER}
+ * are delivered to the view under the pointer. All other generic motion events are
+ * delivered to the focused view.
+ * </p><p>
+ * See {@link View#onGenericMotionEvent(MotionEvent)} for an example of how to
+ * handle this event.
* </p>
- * <code>
- * public boolean onGenericMotionEvent(MotionEvent event) {
- * if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
- * float x = event.getX();
- * float y = event.getY();
- * // process the joystick motion
- * return true;
- * }
- * return super.onGenericMotionEvent(event);
- * }
- * </code>
*
* @param event The generic motion event being processed.
*
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index cc4fefc3..087753b 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -627,24 +627,21 @@
* Called when a generic motion event was not handled by any of the
* views inside of the dialog.
* <p>
- * Generic motion events are dispatched to the focused view to describe
- * the motions of input devices such as joysticks. The
+ * Generic motion events describe joystick movements, mouse hovers, track pad
+ * touches, scroll wheel movements and other input events. The
* {@link MotionEvent#getSource() source} of the motion event specifies
* the class of input that was received. Implementations of this method
* must examine the bits in the source before processing the event.
* The following code example shows how this is done.
+ * </p><p>
+ * Generic motion events with source class
+ * {@link android.view.InputDevice#SOURCE_CLASS_POINTER}
+ * are delivered to the view under the pointer. All other generic motion events are
+ * delivered to the focused view.
+ * </p><p>
+ * See {@link View#onGenericMotionEvent(MotionEvent)} for an example of how to
+ * handle this event.
* </p>
- * <code>
- * public boolean onGenericMotionEvent(MotionEvent event) {
- * if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
- * float x = event.getX();
- * float y = event.getY();
- * // process the joystick motion
- * return true;
- * }
- * return super.onGenericMotionEvent(event);
- * }
- * </code>
*
* @param event The generic motion event being processed.
*
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 178567f..d04fa57 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -907,8 +907,8 @@
/**
* Cancel downloads and remove them from the download manager. Each download will be stopped if
- * it was running, and it will no longer be accessible through the download manager. If a file
- * was already downloaded to external storage, it will not be deleted.
+ * it was running, and it will no longer be accessible through the download manager.
+ * If there is a downloaded file, partial or complete, it is deleted.
*
* @param ids the IDs of the downloads to remove
* @return the number of downloads actually removed
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 1e8743c..a601fbf 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -127,7 +127,7 @@
*/
public boolean isKeyguardLocked() {
try {
- return mWM.isKeyguardSecure();
+ return mWM.isKeyguardLocked();
} catch (RemoteException ex) {
return false;
}
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 61d7424..06c1ecb 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -1094,7 +1094,7 @@
*/
public final int match(String action, String type, String scheme,
Uri data, Set<String> categories, String logTag) {
- if (!matchAction(action)) {
+ if (action != null && !matchAction(action)) {
if (Config.LOGV) Log.v(
logTag, "No matching action " + action + " for " + this);
return NO_MATCH_ACTION;
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 2e43eef..90a5b5d 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -2218,9 +2218,10 @@
}
mCompiledQueries = new LruCache<String, SQLiteCompiledSql>(cacheSize) {
@Override
- protected void entryEvicted(String key, SQLiteCompiledSql value) {
+ protected void entryRemoved(boolean evicted, String key, SQLiteCompiledSql oldValue,
+ SQLiteCompiledSql newValue) {
verifyLockOwner();
- value.releaseIfNotInUse();
+ oldValue.releaseIfNotInUse();
}
};
if (oldCompiledQueries != null) {
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index dd39714..20661d7 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -460,16 +460,17 @@
}
private void dispatchPointer(MotionEvent event) {
- synchronized (mLock) {
- if (event.getAction() == MotionEvent.ACTION_MOVE) {
- mPendingMove = event;
- } else {
- mPendingMove = null;
+ if (event.isTouchEvent()) {
+ synchronized (mLock) {
+ if (event.getAction() == MotionEvent.ACTION_MOVE) {
+ mPendingMove = event;
+ } else {
+ mPendingMove = null;
+ }
}
+ Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT, event);
+ mCaller.sendMessage(msg);
}
-
- Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT, event);
- mCaller.sendMessage(msg);
}
void updateSurface(boolean forceRelayout, boolean forceReport, boolean redrawNeeded) {
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index a95dad7..353b628 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -642,14 +642,18 @@
private static void initFormatStrings() {
synchronized (sLock) {
- Resources r = Resources.getSystem();
- Configuration cfg = r.getConfiguration();
- if (sLastConfig == null || !sLastConfig.equals(cfg)) {
- sLastConfig = cfg;
- sStatusTimeFormat = java.text.DateFormat.getTimeInstance(java.text.DateFormat.SHORT);
- sElapsedFormatMMSS = r.getString(com.android.internal.R.string.elapsed_time_short_format_mm_ss);
- sElapsedFormatHMMSS = r.getString(com.android.internal.R.string.elapsed_time_short_format_h_mm_ss);
- }
+ initFormatStringsLocked();
+ }
+ }
+
+ private static void initFormatStringsLocked() {
+ Resources r = Resources.getSystem();
+ Configuration cfg = r.getConfiguration();
+ if (sLastConfig == null || !sLastConfig.equals(cfg)) {
+ sLastConfig = cfg;
+ sStatusTimeFormat = java.text.DateFormat.getTimeInstance(java.text.DateFormat.SHORT);
+ sElapsedFormatMMSS = r.getString(com.android.internal.R.string.elapsed_time_short_format_mm_ss);
+ sElapsedFormatHMMSS = r.getString(com.android.internal.R.string.elapsed_time_short_format_h_mm_ss);
}
}
@@ -659,8 +663,10 @@
* @hide
*/
public static final CharSequence timeString(long millis) {
- initFormatStrings();
- return sStatusTimeFormat.format(millis);
+ synchronized (sLock) {
+ initFormatStringsLocked();
+ return sStatusTimeFormat.format(millis);
+ }
}
/**
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java
index 191c250..7e29dc7 100644
--- a/core/java/android/text/method/BaseKeyListener.java
+++ b/core/java/android/text/method/BaseKeyListener.java
@@ -33,23 +33,6 @@
implements KeyListener {
/* package */ static final Object OLD_SEL_START = new NoCopySpan.Concrete();
- private static final int MODIFIER_NONE = 0;
- private static final int MODIFIER_ALT = 1;
- private static final int MODIFIER_INVALID = 2;
-
- private static int getModifier(Editable content, KeyEvent event) {
- if (event.hasModifiers(KeyEvent.META_ALT_ON)) {
- return MODIFIER_ALT;
- }
- if (!event.hasNoModifiers()) {
- return MODIFIER_INVALID;
- }
- if (getMetaState(content, META_ALT_ON) == 1) {
- return MODIFIER_ALT;
- }
- return MODIFIER_NONE;
- }
-
/**
* Performs the action that happens when you press the {@link KeyEvent#KEYCODE_DEL} key in
* a {@link TextView}. If there is a selection, deletes the selection; otherwise,
@@ -59,27 +42,7 @@
* @return true if anything was deleted; false otherwise.
*/
public boolean backspace(View view, Editable content, int keyCode, KeyEvent event) {
- int modifier = getModifier(content, event);
- if (modifier == MODIFIER_INVALID) {
- return false;
- }
-
- if (deleteSelection(view, content)) {
- return true;
- }
-
- if (modifier == MODIFIER_ALT && deleteLine(view, content)) {
- return true;
- }
-
- final int start = Selection.getSelectionEnd(content);
- final int end = TextUtils.getOffsetBefore(content, start);
- if (start != end) {
- content.delete(Math.min(start, end), Math.max(start, end));
- return true;
- }
-
- return false;
+ return backspaceOrForwardDelete(view, content, keyCode, event, false);
}
/**
@@ -91,26 +54,42 @@
* @return true if anything was deleted; false otherwise.
*/
public boolean forwardDelete(View view, Editable content, int keyCode, KeyEvent event) {
- int modifier = getModifier(content, event);
- if (modifier == MODIFIER_INVALID) {
+ return backspaceOrForwardDelete(view, content, keyCode, event, true);
+ }
+
+ private boolean backspaceOrForwardDelete(View view, Editable content, int keyCode,
+ KeyEvent event, boolean isForwardDelete) {
+ // Ensure the key event does not have modifiers except ALT or SHIFT.
+ if (!KeyEvent.metaStateHasNoModifiers(event.getMetaState()
+ & ~(KeyEvent.META_SHIFT_MASK | KeyEvent.META_ALT_MASK))) {
return false;
}
+ // If there is a current selection, delete it.
if (deleteSelection(view, content)) {
return true;
}
- if (modifier == MODIFIER_ALT && deleteLine(view, content)) {
- return true;
+ // Alt+Backspace or Alt+ForwardDelete deletes the current line, if possible.
+ if (event.isAltPressed() || getMetaState(content, META_ALT_ON) == 1) {
+ if (deleteLine(view, content)) {
+ return true;
+ }
}
+ // Delete a character.
final int start = Selection.getSelectionEnd(content);
- final int end = TextUtils.getOffsetAfter(content, start);
+ final int end;
+ if (isForwardDelete || event.isShiftPressed()
+ || getMetaState(content, META_SHIFT_ON) == 1) {
+ end = TextUtils.getOffsetAfter(content, start);
+ } else {
+ end = TextUtils.getOffsetBefore(content, start);
+ }
if (start != end) {
content.delete(Math.min(start, end), Math.max(start, end));
return true;
}
-
return false;
}
diff --git a/core/java/android/text/method/BaseMovementMethod.java b/core/java/android/text/method/BaseMovementMethod.java
index 2be18d67..94c6ed0 100644
--- a/core/java/android/text/method/BaseMovementMethod.java
+++ b/core/java/android/text/method/BaseMovementMethod.java
@@ -18,6 +18,7 @@
import android.text.Layout;
import android.text.Spannable;
+import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.TextView;
@@ -88,6 +89,39 @@
return false;
}
+ @Override
+ public boolean onGenericMotionEvent(TextView widget, Spannable text, MotionEvent event) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_SCROLL: {
+ final float vscroll;
+ final float hscroll;
+ if ((event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0) {
+ vscroll = 0;
+ hscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+ } else {
+ vscroll = -event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+ hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
+ }
+
+ boolean handled = false;
+ if (hscroll < 0) {
+ handled |= scrollLeft(widget, text, (int)Math.ceil(-hscroll));
+ } else if (hscroll > 0) {
+ handled |= scrollRight(widget, text, (int)Math.ceil(hscroll));
+ }
+ if (vscroll < 0) {
+ handled |= scrollUp(widget, text, (int)Math.ceil(-vscroll));
+ } else if (vscroll > 0) {
+ handled |= scrollDown(widget, text, (int)Math.ceil(vscroll));
+ }
+ return handled;
+ }
+ }
+ }
+ return false;
+ }
+
/**
* Gets the meta state used for movement using the modifiers tracked by the text
* buffer as well as those present in the key event.
@@ -342,4 +376,276 @@
protected boolean end(TextView widget, Spannable buffer) {
return false;
}
+
+ private int getTopLine(TextView widget) {
+ return widget.getLayout().getLineForVertical(widget.getScrollY());
+ }
+
+ private int getBottomLine(TextView widget) {
+ return widget.getLayout().getLineForVertical(widget.getScrollY() + getInnerHeight(widget));
+ }
+
+ private int getInnerWidth(TextView widget) {
+ return widget.getWidth() - widget.getTotalPaddingLeft() - widget.getTotalPaddingRight();
+ }
+
+ private int getInnerHeight(TextView widget) {
+ return widget.getHeight() - widget.getTotalPaddingTop() - widget.getTotalPaddingBottom();
+ }
+
+ private int getCharacterWidth(TextView widget) {
+ return (int) Math.ceil(widget.getPaint().getFontSpacing());
+ }
+
+ private int getScrollBoundsLeft(TextView widget) {
+ final Layout layout = widget.getLayout();
+ final int topLine = getTopLine(widget);
+ final int bottomLine = getBottomLine(widget);
+ if (topLine > bottomLine) {
+ return 0;
+ }
+ int left = Integer.MAX_VALUE;
+ for (int line = topLine; line <= bottomLine; line++) {
+ final int lineLeft = (int) Math.floor(layout.getLineLeft(line));
+ if (lineLeft < left) {
+ left = lineLeft;
+ }
+ }
+ return left;
+ }
+
+ private int getScrollBoundsRight(TextView widget) {
+ final Layout layout = widget.getLayout();
+ final int topLine = getTopLine(widget);
+ final int bottomLine = getBottomLine(widget);
+ if (topLine > bottomLine) {
+ return 0;
+ }
+ int right = Integer.MIN_VALUE;
+ for (int line = topLine; line <= bottomLine; line++) {
+ final int lineRight = (int) Math.ceil(layout.getLineRight(line));
+ if (lineRight > right) {
+ right = lineRight;
+ }
+ }
+ return right;
+ }
+
+ /**
+ * Performs a scroll left action.
+ * Scrolls left by the specified number of characters.
+ *
+ * @param widget The text view.
+ * @param buffer The text buffer.
+ * @param amount The number of characters to scroll by. Must be at least 1.
+ * @return True if the event was handled.
+ * @hide
+ */
+ protected boolean scrollLeft(TextView widget, Spannable buffer, int amount) {
+ final int minScrollX = getScrollBoundsLeft(widget);
+ int scrollX = widget.getScrollX();
+ if (scrollX > minScrollX) {
+ scrollX = Math.max(scrollX - getCharacterWidth(widget) * amount, minScrollX);
+ widget.scrollTo(scrollX, widget.getScrollY());
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Performs a scroll right action.
+ * Scrolls right by the specified number of characters.
+ *
+ * @param widget The text view.
+ * @param buffer The text buffer.
+ * @param amount The number of characters to scroll by. Must be at least 1.
+ * @return True if the event was handled.
+ * @hide
+ */
+ protected boolean scrollRight(TextView widget, Spannable buffer, int amount) {
+ final int maxScrollX = getScrollBoundsRight(widget) - getInnerWidth(widget);
+ int scrollX = widget.getScrollX();
+ if (scrollX < maxScrollX) {
+ scrollX = Math.min(scrollX + getCharacterWidth(widget) * amount, maxScrollX);
+ widget.scrollTo(scrollX, widget.getScrollY());
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Performs a scroll up action.
+ * Scrolls up by the specified number of lines.
+ *
+ * @param widget The text view.
+ * @param buffer The text buffer.
+ * @param amount The number of lines to scroll by. Must be at least 1.
+ * @return True if the event was handled.
+ * @hide
+ */
+ protected boolean scrollUp(TextView widget, Spannable buffer, int amount) {
+ final Layout layout = widget.getLayout();
+ final int top = widget.getScrollY();
+ int topLine = layout.getLineForVertical(top);
+ if (layout.getLineTop(topLine) == top) {
+ // If the top line is partially visible, bring it all the way
+ // into view; otherwise, bring the previous line into view.
+ topLine -= 1;
+ }
+ if (topLine >= 0) {
+ topLine = Math.max(topLine - amount + 1, 0);
+ Touch.scrollTo(widget, layout, widget.getScrollX(), layout.getLineTop(topLine));
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Performs a scroll down action.
+ * Scrolls down by the specified number of lines.
+ *
+ * @param widget The text view.
+ * @param buffer The text buffer.
+ * @param amount The number of lines to scroll by. Must be at least 1.
+ * @return True if the event was handled.
+ * @hide
+ */
+ protected boolean scrollDown(TextView widget, Spannable buffer, int amount) {
+ final Layout layout = widget.getLayout();
+ final int innerHeight = getInnerHeight(widget);
+ final int bottom = widget.getScrollY() + innerHeight;
+ int bottomLine = layout.getLineForVertical(bottom);
+ if (layout.getLineTop(bottomLine + 1) < bottom + 1) {
+ // Less than a pixel of this line is out of view,
+ // so we must have tried to make it entirely in view
+ // and now want the next line to be in view instead.
+ bottomLine += 1;
+ }
+ final int limit = layout.getLineCount() - 1;
+ if (bottomLine <= limit) {
+ bottomLine = Math.min(bottomLine + amount - 1, limit);
+ Touch.scrollTo(widget, layout, widget.getScrollX(),
+ layout.getLineTop(bottomLine + 1) - innerHeight);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Performs a scroll page up action.
+ * Scrolls up by one page.
+ *
+ * @param widget The text view.
+ * @param buffer The text buffer.
+ * @return True if the event was handled.
+ * @hide
+ */
+ protected boolean scrollPageUp(TextView widget, Spannable buffer) {
+ final Layout layout = widget.getLayout();
+ final int top = widget.getScrollY() - getInnerHeight(widget);
+ int topLine = layout.getLineForVertical(top);
+ if (topLine >= 0) {
+ Touch.scrollTo(widget, layout, widget.getScrollX(), layout.getLineTop(topLine));
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Performs a scroll page up action.
+ * Scrolls down by one page.
+ *
+ * @param widget The text view.
+ * @param buffer The text buffer.
+ * @return True if the event was handled.
+ * @hide
+ */
+ protected boolean scrollPageDown(TextView widget, Spannable buffer) {
+ final Layout layout = widget.getLayout();
+ final int innerHeight = getInnerHeight(widget);
+ final int bottom = widget.getScrollY() + innerHeight + innerHeight;
+ int bottomLine = layout.getLineForVertical(bottom);
+ if (bottomLine <= layout.getLineCount() - 1) {
+ Touch.scrollTo(widget, layout, widget.getScrollX(),
+ layout.getLineTop(bottomLine + 1) - innerHeight);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Performs a scroll to top action.
+ * Scrolls to the top of the document.
+ *
+ * @param widget The text view.
+ * @param buffer The text buffer.
+ * @return True if the event was handled.
+ * @hide
+ */
+ protected boolean scrollTop(TextView widget, Spannable buffer) {
+ final Layout layout = widget.getLayout();
+ if (getTopLine(widget) >= 0) {
+ Touch.scrollTo(widget, layout, widget.getScrollX(), layout.getLineTop(0));
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Performs a scroll to bottom action.
+ * Scrolls to the bottom of the document.
+ *
+ * @param widget The text view.
+ * @param buffer The text buffer.
+ * @return True if the event was handled.
+ * @hide
+ */
+ protected boolean scrollBottom(TextView widget, Spannable buffer) {
+ final Layout layout = widget.getLayout();
+ final int lineCount = layout.getLineCount();
+ if (getBottomLine(widget) <= lineCount - 1) {
+ Touch.scrollTo(widget, layout, widget.getScrollX(),
+ layout.getLineTop(lineCount) - getInnerHeight(widget));
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Performs a scroll to line start action.
+ * Scrolls to the start of the line.
+ *
+ * @param widget The text view.
+ * @param buffer The text buffer.
+ * @return True if the event was handled.
+ * @hide
+ */
+ protected boolean scrollLineStart(TextView widget, Spannable buffer) {
+ final int minScrollX = getScrollBoundsLeft(widget);
+ int scrollX = widget.getScrollX();
+ if (scrollX > minScrollX) {
+ widget.scrollTo(minScrollX, widget.getScrollY());
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Performs a scroll to line end action.
+ * Scrolls to the end of the line.
+ *
+ * @param widget The text view.
+ * @param buffer The text buffer.
+ * @return True if the event was handled.
+ * @hide
+ */
+ protected boolean scrollLineEnd(TextView widget, Spannable buffer) {
+ final int maxScrollX = getScrollBoundsRight(widget) - getInnerWidth(widget);
+ int scrollX = widget.getScrollX();
+ if (scrollX < maxScrollX) {
+ widget.scrollTo(maxScrollX, widget.getScrollY());
+ return true;
+ }
+ return false;
+ }
}
diff --git a/core/java/android/text/method/MovementMethod.java b/core/java/android/text/method/MovementMethod.java
index 9167676..01979fd 100644
--- a/core/java/android/text/method/MovementMethod.java
+++ b/core/java/android/text/method/MovementMethod.java
@@ -47,6 +47,7 @@
public void onTakeFocus(TextView widget, Spannable text, int direction);
public boolean onTrackballEvent(TextView widget, Spannable text, MotionEvent event);
public boolean onTouchEvent(TextView widget, Spannable text, MotionEvent event);
+ public boolean onGenericMotionEvent(TextView widget, Spannable text, MotionEvent event);
/**
* Returns true if this movement method allows arbitrary selection
diff --git a/core/java/android/text/method/ScrollingMovementMethod.java b/core/java/android/text/method/ScrollingMovementMethod.java
index 194ecc1..b9f5d5f4 100644
--- a/core/java/android/text/method/ScrollingMovementMethod.java
+++ b/core/java/android/text/method/ScrollingMovementMethod.java
@@ -25,189 +25,54 @@
* A movement method that interprets movement keys by scrolling the text buffer.
*/
public class ScrollingMovementMethod extends BaseMovementMethod implements MovementMethod {
- private int getTopLine(TextView widget) {
- return widget.getLayout().getLineForVertical(widget.getScrollY());
- }
-
- private int getBottomLine(TextView widget) {
- return widget.getLayout().getLineForVertical(widget.getScrollY() + getInnerHeight(widget));
- }
-
- private int getInnerWidth(TextView widget) {
- return widget.getWidth() - widget.getTotalPaddingLeft() - widget.getTotalPaddingRight();
- }
-
- private int getInnerHeight(TextView widget) {
- return widget.getHeight() - widget.getTotalPaddingTop() - widget.getTotalPaddingBottom();
- }
-
- private int getCharacterWidth(TextView widget) {
- return (int) Math.ceil(widget.getPaint().getFontSpacing());
- }
-
- private int getScrollBoundsLeft(TextView widget) {
- final Layout layout = widget.getLayout();
- final int topLine = getTopLine(widget);
- final int bottomLine = getBottomLine(widget);
- if (topLine > bottomLine) {
- return 0;
- }
- int left = Integer.MAX_VALUE;
- for (int line = topLine; line <= bottomLine; line++) {
- final int lineLeft = (int) Math.floor(layout.getLineLeft(line));
- if (lineLeft < left) {
- left = lineLeft;
- }
- }
- return left;
- }
-
- private int getScrollBoundsRight(TextView widget) {
- final Layout layout = widget.getLayout();
- final int topLine = getTopLine(widget);
- final int bottomLine = getBottomLine(widget);
- if (topLine > bottomLine) {
- return 0;
- }
- int right = Integer.MIN_VALUE;
- for (int line = topLine; line <= bottomLine; line++) {
- final int lineRight = (int) Math.ceil(layout.getLineRight(line));
- if (lineRight > right) {
- right = lineRight;
- }
- }
- return right;
- }
-
@Override
protected boolean left(TextView widget, Spannable buffer) {
- final int minScrollX = getScrollBoundsLeft(widget);
- int scrollX = widget.getScrollX();
- if (scrollX > minScrollX) {
- scrollX = Math.max(scrollX - getCharacterWidth(widget), minScrollX);
- widget.scrollTo(scrollX, widget.getScrollY());
- return true;
- }
- return false;
+ return scrollLeft(widget, buffer, 1);
}
@Override
protected boolean right(TextView widget, Spannable buffer) {
- final int maxScrollX = getScrollBoundsRight(widget) - getInnerWidth(widget);
- int scrollX = widget.getScrollX();
- if (scrollX < maxScrollX) {
- scrollX = Math.min(scrollX + getCharacterWidth(widget), maxScrollX);
- widget.scrollTo(scrollX, widget.getScrollY());
- return true;
- }
- return false;
+ return scrollRight(widget, buffer, 1);
}
@Override
protected boolean up(TextView widget, Spannable buffer) {
- final Layout layout = widget.getLayout();
- final int top = widget.getScrollY();
- int topLine = layout.getLineForVertical(top);
- if (layout.getLineTop(topLine) == top) {
- // If the top line is partially visible, bring it all the way
- // into view; otherwise, bring the previous line into view.
- topLine -= 1;
- }
- if (topLine >= 0) {
- Touch.scrollTo(widget, layout, widget.getScrollX(), layout.getLineTop(topLine));
- return true;
- }
- return false;
+ return scrollUp(widget, buffer, 1);
}
@Override
protected boolean down(TextView widget, Spannable buffer) {
- final Layout layout = widget.getLayout();
- final int innerHeight = getInnerHeight(widget);
- final int bottom = widget.getScrollY() + innerHeight;
- int bottomLine = layout.getLineForVertical(bottom);
- if (layout.getLineTop(bottomLine + 1) < bottom + 1) {
- // Less than a pixel of this line is out of view,
- // so we must have tried to make it entirely in view
- // and now want the next line to be in view instead.
- bottomLine += 1;
- }
- if (bottomLine <= layout.getLineCount() - 1) {
- Touch.scrollTo(widget, layout, widget.getScrollX(),
- layout.getLineTop(bottomLine + 1) - innerHeight);
- return true;
- }
- return false;
+ return scrollDown(widget, buffer, 1);
}
@Override
protected boolean pageUp(TextView widget, Spannable buffer) {
- final Layout layout = widget.getLayout();
- final int top = widget.getScrollY() - getInnerHeight(widget);
- int topLine = layout.getLineForVertical(top);
- if (topLine >= 0) {
- Touch.scrollTo(widget, layout, widget.getScrollX(), layout.getLineTop(topLine));
- return true;
- }
- return false;
+ return scrollPageUp(widget, buffer);
}
@Override
protected boolean pageDown(TextView widget, Spannable buffer) {
- final Layout layout = widget.getLayout();
- final int innerHeight = getInnerHeight(widget);
- final int bottom = widget.getScrollY() + innerHeight + innerHeight;
- int bottomLine = layout.getLineForVertical(bottom);
- if (bottomLine <= layout.getLineCount() - 1) {
- Touch.scrollTo(widget, layout, widget.getScrollX(),
- layout.getLineTop(bottomLine + 1) - innerHeight);
- return true;
- }
- return false;
+ return scrollPageDown(widget, buffer);
}
@Override
protected boolean top(TextView widget, Spannable buffer) {
- final Layout layout = widget.getLayout();
- if (getTopLine(widget) >= 0) {
- Touch.scrollTo(widget, layout, widget.getScrollX(), layout.getLineTop(0));
- return true;
- }
- return false;
+ return scrollTop(widget, buffer);
}
@Override
protected boolean bottom(TextView widget, Spannable buffer) {
- final Layout layout = widget.getLayout();
- final int lineCount = layout.getLineCount();
- if (getBottomLine(widget) <= lineCount - 1) {
- Touch.scrollTo(widget, layout, widget.getScrollX(),
- layout.getLineTop(lineCount) - getInnerHeight(widget));
- return true;
- }
- return false;
+ return scrollBottom(widget, buffer);
}
@Override
protected boolean lineStart(TextView widget, Spannable buffer) {
- final int minScrollX = getScrollBoundsLeft(widget);
- int scrollX = widget.getScrollX();
- if (scrollX > minScrollX) {
- widget.scrollTo(minScrollX, widget.getScrollY());
- return true;
- }
- return false;
+ return scrollLineStart(widget, buffer);
}
@Override
protected boolean lineEnd(TextView widget, Spannable buffer) {
- final int maxScrollX = getScrollBoundsRight(widget) - getInnerWidth(widget);
- int scrollX = widget.getScrollX();
- if (scrollX < maxScrollX) {
- widget.scrollTo(maxScrollX, widget.getScrollY());
- return true;
- }
- return false;
+ return scrollLineEnd(widget, buffer);
}
@Override
diff --git a/core/java/android/util/LruCache.java b/core/java/android/util/LruCache.java
index 5578e6a..a1501e6 100644
--- a/core/java/android/util/LruCache.java
+++ b/core/java/android/util/LruCache.java
@@ -26,8 +26,7 @@
* become eligible for garbage collection.
*
* <p>If your cached values hold resources that need to be explicitly released,
- * override {@link #entryEvicted}. This method is only invoked when values are
- * evicted. Values replaced by calls to {@link #put} must be released manually.
+ * override {@link #entryRemoved}.
*
* <p>If a cache miss should be computed on demand for the corresponding keys,
* override {@link #create}. This simplifies the calling code, allowing it to
@@ -88,29 +87,52 @@
* head of the queue. This returns null if a value is not cached and cannot
* be created.
*/
- public synchronized final V get(K key) {
+ public final V get(K key) {
if (key == null) {
throw new NullPointerException("key == null");
}
- V result = map.get(key);
- if (result != null) {
- hitCount++;
- return result;
+ V mapValue;
+ synchronized (this) {
+ mapValue = map.get(key);
+ if (mapValue != null) {
+ hitCount++;
+ return mapValue;
+ }
+ missCount++;
}
- missCount++;
+ /*
+ * Attempt to create a value. This may take a long time, and the map
+ * may be different when create() returns. If a conflicting value was
+ * added to the map while create() was working, we leave that value in
+ * the map and release the created value.
+ */
- // TODO: release the lock while calling this potentially slow user code
- result = create(key);
+ V createdValue = create(key);
+ if (createdValue == null) {
+ return null;
+ }
- if (result != null) {
+ synchronized (this) {
createCount++;
- size += safeSizeOf(key, result);
- map.put(key, result);
- trimToSize(maxSize);
+ mapValue = map.put(key, createdValue);
+
+ if (mapValue != null) {
+ // There was a conflict so undo that last put
+ map.put(key, mapValue);
+ } else {
+ size += safeSizeOf(key, createdValue);
+ }
}
- return result;
+
+ if (mapValue != null) {
+ entryRemoved(false, key, createdValue, mapValue);
+ return mapValue;
+ } else {
+ trimToSize(maxSize);
+ return createdValue;
+ }
}
/**
@@ -120,42 +142,61 @@
* @return the previous value mapped by {@code key}. Although that entry is
* no longer cached, it has not been passed to {@link #entryEvicted}.
*/
- public synchronized final V put(K key, V value) {
+ public final V put(K key, V value) {
if (key == null || value == null) {
throw new NullPointerException("key == null || value == null");
}
- putCount++;
- size += safeSizeOf(key, value);
- V previous = map.put(key, value);
- if (previous != null) {
- size -= safeSizeOf(key, previous);
+ V previous;
+ synchronized (this) {
+ putCount++;
+ size += safeSizeOf(key, value);
+ previous = map.put(key, value);
+ if (previous != null) {
+ size -= safeSizeOf(key, previous);
+ }
}
+
+ if (previous != null) {
+ entryRemoved(false, key, previous, value);
+ }
+
trimToSize(maxSize);
return previous;
}
+ /**
+ * @param maxSize the maximum size of the cache before returning. May be -1
+ * to evict even 0-sized elements.
+ */
private void trimToSize(int maxSize) {
- while (size > maxSize) {
- Map.Entry<K, V> toEvict = map.eldest(); // equal to map.entrySet().iterator().next();
- if (toEvict == null) {
- break; // map is empty; if size is not 0 then throw an error below
+ while (true) {
+ K key;
+ V value;
+ synchronized (this) {
+ if (size < 0 || (map.isEmpty() && size != 0)) {
+ throw new IllegalStateException(getClass().getName()
+ + ".sizeOf() is reporting inconsistent results!");
+ }
+
+ if (size <= maxSize) {
+ break;
+ }
+
+ Map.Entry<K, V> toEvict = map.eldest();
+ if (toEvict == null) {
+ break;
+ }
+
+ key = toEvict.getKey();
+ value = toEvict.getValue();
+ map.remove(key);
+ size -= safeSizeOf(key, value);
+ evictionCount++;
}
- K key = toEvict.getKey();
- V value = toEvict.getValue();
- map.remove(key);
- size -= safeSizeOf(key, value);
- evictionCount++;
-
- // TODO: release the lock while calling this potentially slow user code
entryEvicted(key, value);
}
-
- if (size < 0 || (map.isEmpty() && size != 0)) {
- throw new IllegalStateException(getClass().getName()
- + ".sizeOf() is reporting inconsistent results!");
- }
}
/**
@@ -164,28 +205,67 @@
* @return the previous value mapped by {@code key}. Although that entry is
* no longer cached, it has not been passed to {@link #entryEvicted}.
*/
- public synchronized final V remove(K key) {
+ public final V remove(K key) {
if (key == null) {
throw new NullPointerException("key == null");
}
- V previous = map.remove(key);
- if (previous != null) {
- size -= safeSizeOf(key, previous);
+ V previous;
+ synchronized (this) {
+ previous = map.remove(key);
+ if (previous != null) {
+ size -= safeSizeOf(key, previous);
+ }
}
+
+ if (previous != null) {
+ entryRemoved(false, key, previous, null);
+ }
+
return previous;
}
/**
- * Called for entries that have reached the tail of the least recently used
- * queue and are be removed. The default implementation does nothing.
+ * Calls {@link #entryRemoved}.
+ *
+ * @deprecated replaced by entryRemoved
*/
- protected void entryEvicted(K key, V value) {}
+ @Deprecated
+ protected void entryEvicted(K key, V value) {
+ entryRemoved(true, key, value, null);
+ }
+
+ /**
+ * Called for entries that have been evicted or removed. This method is
+ * invoked when a value is evicted to make space, removed by a call to
+ * {@link #remove}, or replaced by a call to {@link #put}. The default
+ * implementation does nothing.
+ *
+ * <p>The method is called without synchronization: other threads may
+ * access the cache while this method is executing.
+ *
+ * @param evicted true if the entry is being removed to make space, false
+ * if the removal was caused by a {@link #put} or {@link #remove}.
+ * @param newValue the new value for {@code key}, if it exists. If non-null,
+ * this removal was caused by a {@link #put}. Otherwise it was caused by
+ * an eviction or a {@link #remove}.
+ */
+ protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {}
/**
* Called after a cache miss to compute a value for the corresponding key.
* Returns the computed value or null if no value can be computed. The
* default implementation returns null.
+ *
+ * <p>The method is called without synchronization: other threads may
+ * access the cache while this method is executing.
+ *
+ * <p>If a value for {@code key} exists in the cache when this method
+ * returns, the created value will be released with {@link #entryRemoved}
+ * and discarded. This can occur when multiple threads request the same key
+ * at the same time (causing multiple values to be created), or when one
+ * thread calls {@link #put} while another is creating a value for the same
+ * key.
*/
protected V create(K key) {
return null;
@@ -213,7 +293,7 @@
/**
* Clear the cache, calling {@link #entryEvicted} on each removed entry.
*/
- public synchronized final void evictAll() {
+ public final void evictAll() {
trimToSize(-1); // -1 will evict 0-sized elements
}
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index d7b0dc1..9042505 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -191,7 +191,7 @@
int pos = 0;
fieldLen -= 1;
while (pos < fieldLen) {
- formatStr[pos] = ' ';
+ formatStr[pos++] = ' ';
}
formatStr[pos] = '0';
return pos+1;
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index b74806486..126f409 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -79,6 +79,11 @@
*/
native public int getHeight();
+ /** @hide special for when we are faking the screen size. */
+ native public int getRealWidth();
+ /** @hide special for when we are faking the screen size. */
+ native public int getRealHeight();
+
/**
* Returns the rotation of the screen from its "natural" orientation.
* The returned value may be {@link Surface#ROTATION_0 Surface.ROTATION_0}
@@ -136,11 +141,6 @@
outMetrics.ydpi = mDpiY;
}
- /**
- * @hide Helper for our fake display size hack.
- */
- native public static int unmapDisplaySize(int newSize);
-
/*
* We use a class initializer to allow the native code to cache some
* field offsets.
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index cc37a28..a26dd04 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -40,6 +40,12 @@
* by a motion event with {@link #ACTION_UP} or when gesture is canceled
* with {@link #ACTION_CANCEL}.
* </p><p>
+ * Some pointing devices such as mice may support vertical and/or horizontal scrolling.
+ * A scroll event is reported as a generic motion event with {@link #ACTION_SCROLL} that
+ * includes the relative scroll offset in the {@link #AXIS_VSCROLL} and
+ * {@link #AXIS_HSCROLL} axes. See {@link #getAxisValue(int)} for information
+ * about retrieving these additional axes.
+ * </p><p>
* On trackball devices with source class {@link InputDevice#SOURCE_CLASS_TRACKBALL},
* the pointer coordinates specify relative movements as X/Y deltas.
* A trackball gesture consists of a sequence of movements described by motion
@@ -51,6 +57,8 @@
* The joystick axis values are normalized to a range of -1.0 to 1.0 where 0.0 corresponds
* to the center position. More information about the set of available axes and the
* range of motion can be obtained using {@link InputDevice#getMotionRange}.
+ * Some common joystick axes are {@link #AXIS_X}, {@link #AXIS_Y},
+ * {@link #AXIS_HAT_X}, {@link #AXIS_HAT_Y}, {@link #AXIS_Z} and {@link #AXIS_RZ}.
* </p><p>
* Motion events always report movements for all pointers at once. The number
* of pointers only ever changes by one as individual pointers go up and down,
@@ -163,10 +171,30 @@
* is not down (unlike {@link #ACTION_MOVE}). The motion contains the most
* recent point, as well as any intermediate points since the last
* hover move event.
+ * <p>
+ * This action is not a touch event so it is delivered to
+ * {@link View#onGenericMotionEvent(MotionEvent)} rather than
+ * {@link View#onTouchEvent(MotionEvent)}.
+ * </p>
*/
public static final int ACTION_HOVER_MOVE = 7;
/**
+ * Constant for {@link #getAction}: The motion event contains relative
+ * vertical and/or horizontal scroll offsets. Use {@link #getAxisValue(int)}
+ * to retrieve the information from {@link #AXIS_VSCROLL} and {@link #AXIS_HSCROLL}.
+ * The pointer may or may not be down when this event is dispatched.
+ * This action is always delivered to the winder under the pointer, which
+ * may not be the window currently touched.
+ * <p>
+ * This action is not a touch event so it is delivered to
+ * {@link View#onGenericMotionEvent(MotionEvent)} rather than
+ * {@link View#onTouchEvent(MotionEvent)}.
+ * </p>
+ */
+ public static final int ACTION_SCROLL = 8;
+
+ /**
* Bits in the action code that represent a pointer index, used with
* {@link #ACTION_POINTER_DOWN} and {@link #ACTION_POINTER_UP}. Shifting
* down by {@link #ACTION_POINTER_INDEX_SHIFT} provides the actual pointer
@@ -483,7 +511,7 @@
* <p>
* <ul>
* <li>For a mouse, reports the relative movement of the vertical scroll wheel.
- * The value is normalized to a range from -1.0 (up) to 1.0 (down).
+ * The value is normalized to a range from -1.0 (down) to 1.0 (up).
* </ul>
* </p><p>
* This axis should be used to scroll views vertically.
@@ -1237,6 +1265,32 @@
}
/**
+ * Returns true if this motion event is a touch event.
+ * <p>
+ * Specifically excludes pointer events with action {@link #ACTION_HOVER_MOVE}
+ * or {@link #ACTION_SCROLL} because they are not actually touch events
+ * (the pointer is not down).
+ * </p>
+ * @return True if this motion event is a touch event.
+ * @hide
+ */
+ public final boolean isTouchEvent() {
+ if ((getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ switch (getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_MOVE:
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_POINTER_DOWN:
+ case MotionEvent.ACTION_POINTER_UP:
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_OUTSIDE:
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Gets the motion event flags.
*
* @see #FLAG_WINDOW_IS_OBSCURED
@@ -2174,10 +2228,14 @@
return "ACTION_UP";
case ACTION_CANCEL:
return "ACTION_CANCEL";
+ case ACTION_OUTSIDE:
+ return "ACTION_OUTSIDE";
case ACTION_MOVE:
return "ACTION_MOVE";
case ACTION_HOVER_MOVE:
return "ACTION_HOVER_MOVE";
+ case ACTION_SCROLL:
+ return "ACTION_SCROLL";
}
int index = (action & ACTION_POINTER_INDEX_MASK) >> ACTION_POINTER_INDEX_SHIFT;
switch (action & ACTION_MASK) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 78eb2e5..01bc2df 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -57,6 +57,7 @@
import android.util.PoolableManager;
import android.util.Pools;
import android.util.SparseArray;
+import android.util.TypedValue;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.MeasureSpec;
import android.view.accessibility.AccessibilityEvent;
@@ -2128,6 +2129,8 @@
private OnTouchListener mOnTouchListener;
+ private OnGenericMotionListener mOnGenericMotionListener;
+
private OnDragListener mOnDragListener;
private OnSystemUiVisibilityChangeListener mOnSystemUiVisibilityChangeListener;
@@ -2257,6 +2260,11 @@
public static final int DRAG_FLAG_GLOBAL = 1;
/**
+ * Vertical scroll factor cached by {@link #getVerticalScrollFactor}.
+ */
+ private float mVerticalScrollFactor;
+
+ /**
* Position of the vertical scroll bar.
*/
private int mVerticalScrollbarPosition;
@@ -3167,6 +3175,14 @@
}
/**
+ * Register a callback to be invoked when a generic motion event is sent to this view.
+ * @param l the generic motion listener to attach to this view
+ */
+ public void setOnGenericMotionListener(OnGenericMotionListener l) {
+ mOnGenericMotionListener = l;
+ }
+
+ /**
* Register a drag event listener callback object for this View. The parameter is
* an implementation of {@link android.view.View.OnDragListener}. To send a drag event to a
* View, the system calls the
@@ -4624,16 +4640,47 @@
}
/**
- * Pass a generic motion event down to the focused view.
+ * Dispatch a generic motion event.
+ * <p>
+ * Generic motion events with source class {@link InputDevice#SOURCE_CLASS_POINTER}
+ * are delivered to the view under the pointer. All other generic motion events are
+ * delivered to the focused view.
+ * </p>
*
* @param event The motion event to be dispatched.
* @return True if the event was handled by the view, false otherwise.
*/
public boolean dispatchGenericMotionEvent(MotionEvent event) {
+ if (mOnGenericMotionListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
+ && mOnGenericMotionListener.onGenericMotion(this, event)) {
+ return true;
+ }
+
return onGenericMotionEvent(event);
}
/**
+ * Dispatch a pointer event.
+ * <p>
+ * Dispatches touch related pointer events to {@link #onTouchEvent} and all
+ * other events to {@link #onGenericMotionEvent}. This separation of concerns
+ * reinforces the invariant that {@link #onTouchEvent} is really about touches
+ * and should not be expected to handle other pointing device features.
+ * </p>
+ *
+ * @param event The motion event to be dispatched.
+ * @return True if the event was handled by the view, false otherwise.
+ * @hide
+ */
+ public final boolean dispatchPointerEvent(MotionEvent event) {
+ if (event.isTouchEvent()) {
+ return dispatchTouchEvent(event);
+ } else {
+ return dispatchGenericMotionEvent(event);
+ }
+ }
+
+ /**
* Called when the window containing this view gains or loses window focus.
* ViewGroups should override to route to their children.
*
@@ -5142,20 +5189,34 @@
/**
* Implement this method to handle generic motion events.
* <p>
- * Generic motion events are dispatched to the focused view to describe
- * the motions of input devices such as joysticks. The
+ * Generic motion events describe joystick movements, mouse hovers, track pad
+ * touches, scroll wheel movements and other input events. The
* {@link MotionEvent#getSource() source} of the motion event specifies
* the class of input that was received. Implementations of this method
* must examine the bits in the source before processing the event.
* The following code example shows how this is done.
+ * </p><p>
+ * Generic motion events with source class {@link InputDevice#SOURCE_CLASS_POINTER}
+ * are delivered to the view under the pointer. All other generic motion events are
+ * delivered to the focused view.
* </p>
* <code>
* public boolean onGenericMotionEvent(MotionEvent event) {
* if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
- * float x = event.getX();
- * float y = event.getY();
- * // process the joystick motion
- * return true;
+ * if (event.getAction() == MotionEvent.ACTION_MOVE) {
+ * // process the joystick movement...
+ * return true;
+ * }
+ * }
+ * if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ * switch (event.getAction()) {
+ * case MotionEvent.ACTION_HOVER_MOVE:
+ * // process the mouse hover movement...
+ * return true;
+ * case MotionEvent.ACTION_SCROLL:
+ * // process the scroll wheel movement...
+ * return true;
+ * }
* }
* return super.onGenericMotionEvent(event);
* }
@@ -11653,6 +11714,37 @@
}
/**
+ * Gets a scale factor that determines the distance the view should scroll
+ * vertically in response to {@link MotionEvent#ACTION_SCROLL}.
+ * @return The vertical scroll scale factor.
+ * @hide
+ */
+ protected float getVerticalScrollFactor() {
+ if (mVerticalScrollFactor == 0) {
+ TypedValue outValue = new TypedValue();
+ if (!mContext.getTheme().resolveAttribute(
+ com.android.internal.R.attr.listPreferredItemHeight, outValue, true)) {
+ throw new IllegalStateException(
+ "Expected theme to define listPreferredItemHeight.");
+ }
+ mVerticalScrollFactor = outValue.getDimension(
+ mContext.getResources().getDisplayMetrics());
+ }
+ return mVerticalScrollFactor;
+ }
+
+ /**
+ * Gets a scale factor that determines the distance the view should scroll
+ * horizontally in response to {@link MotionEvent#ACTION_SCROLL}.
+ * @return The horizontal scroll scale factor.
+ * @hide
+ */
+ protected float getHorizontalScrollFactor() {
+ // TODO: Should use something else.
+ return getVerticalScrollFactor();
+ }
+
+ /**
* A MeasureSpec encapsulates the layout requirements passed from parent to child.
* Each MeasureSpec represents a requirement for either the width or the height.
* A MeasureSpec is comprised of a size and a mode. There are three possible
@@ -11860,6 +11952,24 @@
}
/**
+ * Interface definition for a callback to be invoked when a generic motion event is
+ * dispatched to this view. The callback will be invoked before the generic motion
+ * event is given to the view.
+ */
+ public interface OnGenericMotionListener {
+ /**
+ * Called when a generic motion event is dispatched to a view. This allows listeners to
+ * get a chance to respond before the target view.
+ *
+ * @param v The view the generic motion event has been dispatched to.
+ * @param event The MotionEvent object containing full information about
+ * the event.
+ * @return True if the listener has consumed the event, false otherwise.
+ */
+ boolean onGenericMotion(View v, MotionEvent event);
+ }
+
+ /**
* Interface definition for a callback to be invoked when a view has been clicked and held.
*/
public interface OnLongClickListener {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index a0d4263..5c06151 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1145,6 +1145,53 @@
*/
@Override
public boolean dispatchGenericMotionEvent(MotionEvent event) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ // Send the event to the child under the pointer.
+ final int childrenCount = mChildrenCount;
+ if (childrenCount != 0) {
+ final View[] children = mChildren;
+ final float x = event.getX();
+ final float y = event.getY();
+
+ for (int i = childrenCount - 1; i >= 0; i--) {
+ final View child = children[i];
+ if ((child.mViewFlags & VISIBILITY_MASK) != VISIBLE
+ && child.getAnimation() == null) {
+ // Skip invisible child unless it is animating.
+ continue;
+ }
+
+ if (!isTransformedTouchPointInView(x, y, child, null)) {
+ // Scroll point is out of child's bounds.
+ continue;
+ }
+
+ final float offsetX = mScrollX - child.mLeft;
+ final float offsetY = mScrollY - child.mTop;
+ final boolean handled;
+ if (!child.hasIdentityMatrix()) {
+ MotionEvent transformedEvent = MotionEvent.obtain(event);
+ transformedEvent.offsetLocation(offsetX, offsetY);
+ transformedEvent.transform(child.getInverseMatrix());
+ handled = child.dispatchGenericMotionEvent(transformedEvent);
+ transformedEvent.recycle();
+ } else {
+ event.offsetLocation(offsetX, offsetY);
+ handled = child.dispatchGenericMotionEvent(event);
+ event.offsetLocation(-offsetX, -offsetY);
+ }
+
+ if (handled) {
+ return true;
+ }
+ }
+ }
+
+ // No child handled the event. Send it to this view group.
+ return super.dispatchGenericMotionEvent(event);
+ }
+
+ // Send the event to the focused child or to this view group if it has focus.
if ((mPrivateFlags & (FOCUSED | HAS_BOUNDS)) == (FOCUSED | HAS_BOUNDS)) {
return super.dispatchGenericMotionEvent(event);
} else if (mFocused != null && (mFocused.mPrivateFlags & HAS_BOUNDS) == HAS_BOUNDS) {
@@ -1178,7 +1225,6 @@
// Check for interception.
final boolean intercepted;
if (actionMasked == MotionEvent.ACTION_DOWN
- || actionMasked == MotionEvent.ACTION_HOVER_MOVE
|| mFirstTouchTarget != null) {
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
if (!disallowIntercept) {
@@ -1188,6 +1234,8 @@
intercepted = false;
}
} else {
+ // There are no touch targets and this action is not an initial down
+ // so this view group continues to intercept touches.
intercepted = true;
}
@@ -1548,8 +1596,6 @@
final int newAction;
if (cancel) {
newAction = MotionEvent.ACTION_CANCEL;
- } else if (oldAction == MotionEvent.ACTION_HOVER_MOVE) {
- newAction = MotionEvent.ACTION_HOVER_MOVE;
} else {
final int oldMaskedAction = oldAction & MotionEvent.ACTION_MASK;
if (oldMaskedAction == MotionEvent.ACTION_POINTER_DOWN
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 39f99b8..c7b1955 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -2247,7 +2247,7 @@
private void deliverPointerEvent(MotionEvent event, boolean sendDone) {
// If there is no view, then the event will not be handled.
if (mView == null || !mAdded) {
- finishPointerEvent(event, sendDone, false);
+ finishMotionEvent(event, sendDone, false);
return;
}
@@ -2270,7 +2270,7 @@
event.offsetLocation(0, mCurScrollY);
}
if (MEASURE_LATENCY) {
- lt.sample("A Dispatching TouchEvents", System.nanoTime() - event.getEventTimeNano());
+ lt.sample("A Dispatching PointerEvents", System.nanoTime() - event.getEventTimeNano());
}
// Remember the touch position for possible drag-initiation.
@@ -2278,12 +2278,12 @@
mLastTouchPoint.y = event.getRawY();
// Dispatch touch to view hierarchy.
- boolean handled = mView.dispatchTouchEvent(event);
+ boolean handled = mView.dispatchPointerEvent(event);
if (MEASURE_LATENCY) {
- lt.sample("B Dispatched TouchEvents ", System.nanoTime() - event.getEventTimeNano());
+ lt.sample("B Dispatched PointerEvents ", System.nanoTime() - event.getEventTimeNano());
}
if (handled) {
- finishPointerEvent(event, sendDone, true);
+ finishMotionEvent(event, sendDone, true);
return;
}
@@ -2325,23 +2325,27 @@
if (nearest != null) {
event.offsetLocation(deltas[0], deltas[1]);
event.setEdgeFlags(0);
- if (mView.dispatchTouchEvent(event)) {
- finishPointerEvent(event, sendDone, true);
+ if (mView.dispatchPointerEvent(event)) {
+ finishMotionEvent(event, sendDone, true);
return;
}
}
}
// Pointer event was unhandled.
- finishPointerEvent(event, sendDone, false);
+ finishMotionEvent(event, sendDone, false);
}
- private void finishPointerEvent(MotionEvent event, boolean sendDone, boolean handled) {
+ private void finishMotionEvent(MotionEvent event, boolean sendDone, boolean handled) {
event.recycle();
if (sendDone) {
finishInputEvent(handled);
}
- if (LOCAL_LOGV || WATCH_POINTER) Log.i(TAG, "Done dispatching!");
+ if (LOCAL_LOGV || WATCH_POINTER) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ Log.i(TAG, "Done dispatching!");
+ }
+ }
}
private void deliverTrackballEvent(MotionEvent event, boolean sendDone) {
@@ -2349,7 +2353,7 @@
// If there is no view, then the event will not be handled.
if (mView == null || !mAdded) {
- finishTrackballEvent(event, sendDone, false);
+ finishMotionEvent(event, sendDone, false);
return;
}
@@ -2361,7 +2365,7 @@
// touch mode here.
ensureTouchMode(false);
- finishTrackballEvent(event, sendDone, true);
+ finishMotionEvent(event, sendDone, true);
mLastTrackballTime = Integer.MIN_VALUE;
return;
}
@@ -2471,14 +2475,7 @@
// Unfortunately we can't tell whether the application consumed the keys, so
// we always consider the trackball event handled.
- finishTrackballEvent(event, sendDone, true);
- }
-
- private void finishTrackballEvent(MotionEvent event, boolean sendDone, boolean handled) {
- event.recycle();
- if (sendDone) {
- finishInputEvent(handled);
- }
+ finishMotionEvent(event, sendDone, true);
}
private void deliverGenericMotionEvent(MotionEvent event, boolean sendDone) {
@@ -2490,7 +2487,7 @@
if (isJoystick) {
updateJoystickDirection(event, false);
}
- finishGenericMotionEvent(event, sendDone, false);
+ finishMotionEvent(event, sendDone, false);
return;
}
@@ -2499,23 +2496,16 @@
if (isJoystick) {
updateJoystickDirection(event, false);
}
- finishGenericMotionEvent(event, sendDone, true);
+ finishMotionEvent(event, sendDone, true);
return;
}
if (isJoystick) {
// Translate the joystick event into DPAD keys and try to deliver those.
updateJoystickDirection(event, true);
- finishGenericMotionEvent(event, sendDone, true);
+ finishMotionEvent(event, sendDone, true);
} else {
- finishGenericMotionEvent(event, sendDone, false);
- }
- }
-
- private void finishGenericMotionEvent(MotionEvent event, boolean sendDone, boolean handled) {
- event.recycle();
- if (sendDone) {
- finishInputEvent(handled);
+ finishMotionEvent(event, sendDone, false);
}
}
diff --git a/core/java/android/webkit/HTML5Audio.java b/core/java/android/webkit/HTML5Audio.java
index a3906ddb..6fc0d11 100644
--- a/core/java/android/webkit/HTML5Audio.java
+++ b/core/java/android/webkit/HTML5Audio.java
@@ -173,7 +173,8 @@
mState = INITIALIZED;
mMediaPlayer.prepareAsync();
} catch (IOException e) {
- Log.e(LOGTAG, "couldn't load the resource: " + url + " exc: " + e);
+ String debugUrl = url.length() > 128 ? url.substring(0, 128) + "..." : url;
+ Log.e(LOGTAG, "couldn't load the resource: "+ debugUrl +" exc: " + e);
resetMediaPlayer();
}
}
diff --git a/core/java/android/webkit/L10nUtils.java b/core/java/android/webkit/L10nUtils.java
index 962492e..f59d7d0 100644
--- a/core/java/android/webkit/L10nUtils.java
+++ b/core/java/android/webkit/L10nUtils.java
@@ -18,8 +18,9 @@
import android.content.Context;
-import java.util.List;
-import java.util.Vector;
+import java.lang.ref.SoftReference;
+import java.util.Map;
+import java.util.HashMap;
/**
* @hide
@@ -32,23 +33,71 @@
com.android.internal.R.string.autofill_address_name_separator, // IDS_AUTOFILL_DIALOG_ADDRESS_NAME_SEPARATOR
com.android.internal.R.string.autofill_address_summary_name_format, // IDS_AUTOFILL_DIALOG_ADDRESS_SUMMARY_NAME_FORMAT
com.android.internal.R.string.autofill_address_summary_separator, // IDS_AUTOFILL_DIALOG_ADDRESS_SUMMARY_SEPARATOR
- com.android.internal.R.string.autofill_address_summary_format // IDS_AUTOFILL_DIALOG_ADDRESS_SUMMARY_FORMAT
+ com.android.internal.R.string.autofill_address_summary_format, // IDS_AUTOFILL_DIALOG_ADDRESS_SUMMARY_FORMAT
+ com.android.internal.R.string.autofill_attention_ignored_re, // IDS_AUTOFILL_ATTENTION_IGNORED_RE
+ com.android.internal.R.string.autofill_region_ignored_re, // IDS_AUTOFILL_REGION_IGNORED_RE
+ com.android.internal.R.string.autofill_company_re, // IDS_AUTOFILL_COMPANY_RE
+ com.android.internal.R.string.autofill_address_line_1_re, // IDS_AUTOFILL_ADDRESS_LINE_1_RE
+ com.android.internal.R.string.autofill_address_line_1_label_re, // IDS_AUTOFILL_ADDRESS_LINE_1_LABEL_RE
+ com.android.internal.R.string.autofill_address_line_2_re, // IDS_AUTOFILL_ADDRESS_LINE_2_RE
+ com.android.internal.R.string.autofill_address_line_3_re, // IDS_AUTOFILL_ADDRESS_LINE_3_RE
+ com.android.internal.R.string.autofill_country_re, // IDS_AUTOFILL_COUNTRY_RE
+ com.android.internal.R.string.autofill_zip_code_re, // IDS_AUTOFILL_ZIP_CODE_RE
+ com.android.internal.R.string.autofill_zip_4_re, // IDS_AUTOFILL_ZIP_4_RE
+ com.android.internal.R.string.autofill_city_re, // IDS_AUTOFILL_CITY_RE
+ com.android.internal.R.string.autofill_state_re, // IDS_AUTOFILL_STATE_RE
+ com.android.internal.R.string.autofill_address_type_same_as_re, // IDS_AUTOFILL_SAME_AS_RE
+ com.android.internal.R.string.autofill_address_type_use_my_re, // IDS_AUTOFILL_USE_MY_RE
+ com.android.internal.R.string.autofill_billing_designator_re, // IDS_AUTOFILL_BILLING_DESIGNATOR_RE
+ com.android.internal.R.string.autofill_shipping_designator_re, // IDS_AUTOFILL_SHIPPING_DESIGNATOR_RE
+ com.android.internal.R.string.autofill_email_re, // IDS_AUTOFILL_EMAIL_RE
+ com.android.internal.R.string.autofill_username_re, // IDS_AUTOFILL_USERNAME_RE
+ com.android.internal.R.string.autofill_name_re, // IDS_AUTOFILL_NAME_RE
+ com.android.internal.R.string.autofill_name_specific_re, // IDS_AUTOFILL_NAME_SPECIFIC_RE
+ com.android.internal.R.string.autofill_first_name_re, // IDS_AUTOFILL_FIRST_NAME_RE
+ com.android.internal.R.string.autofill_middle_initial_re, // IDS_AUTOFILL_MIDDLE_INITIAL_RE
+ com.android.internal.R.string.autofill_middle_name_re, // IDS_AUTOFILL_MIDDLE_NAME_RE
+ com.android.internal.R.string.autofill_last_name_re, // IDS_AUTOFILL_LAST_NAME_RE
+ com.android.internal.R.string.autofill_phone_re, // IDS_AUTOFILL_PHONE_RE
+ com.android.internal.R.string.autofill_area_code_re, // IDS_AUTOFILL_AREA_CODE_RE
+ com.android.internal.R.string.autofill_phone_prefix_re, // IDS_AUTOFILL_PHONE_PREFIX_RE
+ com.android.internal.R.string.autofill_phone_suffix_re, // IDS_AUTOFILL_PHONE_SUFFIX_RE
+ com.android.internal.R.string.autofill_phone_extension_re, // IDS_AUTOFILL_PHONE_EXTENSION_RE
+ com.android.internal.R.string.autofill_name_on_card_re, // IDS_AUTOFILL_NAME_ON_CARD_RE
+ com.android.internal.R.string.autofill_name_on_card_contextual_re, // IDS_AUTOFILL_NAME_ON_CARD_CONTEXTUAL_RE
+ com.android.internal.R.string.autofill_card_cvc_re, // IDS_AUTOFILL_CARD_CVC_RE
+ com.android.internal.R.string.autofill_card_number_re, // IDS_AUTOFILL_CARD_NUMBER_RE
+ com.android.internal.R.string.autofill_expiration_month_re, // IDS_AUTOFILL_EXPIRATION_MONTH_RE
+ com.android.internal.R.string.autofill_expiration_date_re, // IDS_AUTOFILL_EXPIRATION_DATE_RE
+ com.android.internal.R.string.autofill_card_ignored_re // IDS_AUTOFILL_CARD_IGNORED_RE
};
- private static List<String> mStrings;
+ private static Context mApplicationContext;
+ private static Map<Integer, SoftReference<String> > mStrings;
- public static void loadStrings(Context context) {
- if (mStrings != null) {
- return;
+ public static void setApplicationContext(Context applicationContext) {
+ mApplicationContext = applicationContext.getApplicationContext();
+ }
+
+ private static String loadString(int id) {
+ if (mStrings == null) {
+ mStrings = new HashMap<Integer, SoftReference<String> >(mIdsArray.length);
}
- mStrings = new Vector<String>(mIdsArray.length);
- for (int i = 0; i < mIdsArray.length; i++) {
- mStrings.add(context.getResources().getString(mIdsArray[i]));
- }
+ String localisedString = mApplicationContext.getResources().getString(mIdsArray[id]);
+ mStrings.put(id, new SoftReference<String>(localisedString));
+ return localisedString;
}
public static String getLocalisedString(int id) {
- return mStrings.get(id);
+ if (mStrings == null) {
+ // This is the first time we need a localised string.
+ // loadString will create the Map.
+ return loadString(id);
+ }
+
+ SoftReference<String> ref = mStrings.get(id);
+ boolean needToLoad = ref == null || ref.get() == null;
+ return needToLoad ? loadString(id) : ref.get();
}
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 06cb64e8..f877fc8 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -62,6 +62,7 @@
import android.util.Log;
import android.view.Gravity;
import android.view.HardwareCanvas;
+import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -986,7 +987,7 @@
mCallbackProxy = new CallbackProxy(context, this);
mViewManager = new ViewManager(this);
- L10nUtils.loadStrings(context);
+ L10nUtils.setApplicationContext(context.getApplicationContext());
mWebViewCore = new WebViewCore(context, this, mCallbackProxy, javaScriptInterfaces);
mDatabase = WebViewDatabase.getInstance(context);
mScroller = new OverScroller(context, null, 0, 0, false); //TODO Use OverScroller's flywheel
@@ -6147,6 +6148,33 @@
nativeHideCursor();
}
+ @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_SCROLL: {
+ final float vscroll;
+ final float hscroll;
+ if ((event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0) {
+ vscroll = 0;
+ hscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+ } else {
+ vscroll = -event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+ hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
+ }
+ if (hscroll != 0 || vscroll != 0) {
+ final int vdelta = (int) (vscroll * getVerticalScrollFactor());
+ final int hdelta = (int) (hscroll * getHorizontalScrollFactor());
+ if (pinScrollBy(hdelta, vdelta, true, 0)) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return super.onGenericMotionEvent(event);
+ }
+
private long mTrackballFirstTime = 0;
private long mTrackballLastTime = 0;
private float mTrackballRemainsX = 0.0f;
@@ -7740,11 +7768,11 @@
* and allow filtering.
*/
private class MyArrayListAdapter extends ArrayAdapter<Container> {
- public MyArrayListAdapter(Context context, Container[] objects, boolean multiple) {
- super(context,
- multiple ? com.android.internal.R.layout.select_dialog_multichoice :
- com.android.internal.R.layout.select_dialog_singlechoice,
- objects);
+ public MyArrayListAdapter() {
+ super(mContext,
+ mMultiple ? com.android.internal.R.layout.select_dialog_multichoice :
+ com.android.internal.R.layout.webview_select_singlechoice,
+ mContainers);
}
@Override
@@ -7770,13 +7798,12 @@
}
if (Container.OPTGROUP == c.mEnabled) {
- // Currently select_dialog_multichoice and
- // select_dialog_singlechoice are CheckedTextViews. If
- // that changes, the class cast will no longer be valid.
- Assert.assertTrue(
- convertView instanceof CheckedTextView);
- ((CheckedTextView) convertView).setCheckMarkDrawable(
- null);
+ // Currently select_dialog_multichoice uses CheckedTextViews.
+ // If that changes, the class cast will no longer be valid.
+ if (mMultiple) {
+ Assert.assertTrue(convertView instanceof CheckedTextView);
+ ((CheckedTextView) convertView).setCheckMarkDrawable(null);
+ }
} else {
// c.mEnabled == Container.OPTION_DISABLED
// Draw the disabled element in a disabled state.
@@ -7883,6 +7910,7 @@
mAdapter = a;
}
+ @Override
public void onChanged() {
// The filter may have changed which item is checked. Find the
// item that the ListView thinks is checked.
@@ -7903,15 +7931,12 @@
}
}
}
-
- public void onInvalidate() {}
}
public void run() {
final ListView listView = (ListView) LayoutInflater.from(mContext)
.inflate(com.android.internal.R.layout.select_dialog, null);
- final MyArrayListAdapter adapter = new
- MyArrayListAdapter(mContext, mContainers, mMultiple);
+ final MyArrayListAdapter adapter = new MyArrayListAdapter();
AlertDialog.Builder b = new AlertDialog.Builder(mContext)
.setView(listView).setCancelable(true)
.setInverseBackgroundForced(true);
@@ -7949,7 +7974,7 @@
}
} else {
listView.setOnItemClickListener(new OnItemClickListener() {
- public void onItemClick(AdapterView parent, View v,
+ public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
// Rather than sending the message right away, send it
// after the page regains focus.
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index eb53e56..c2c8d16 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -43,6 +43,7 @@
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
+import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -3261,6 +3262,26 @@
}
@Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_SCROLL: {
+ if (mTouchMode == TOUCH_MODE_REST) {
+ final float vscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+ if (vscroll != 0) {
+ final int delta = (int) (vscroll * getVerticalScrollFactor());
+ if (trackMotionScroll(delta, delta)) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return super.onGenericMotionEvent(event);
+ }
+
+ @Override
public void draw(Canvas canvas) {
super.draw(canvas);
if (mEdgeGlowTop != null) {
diff --git a/core/java/android/widget/EdgeGlow.java b/core/java/android/widget/EdgeGlow.java
index 2a0e849..c2cb0a0 100644
--- a/core/java/android/widget/EdgeGlow.java
+++ b/core/java/android/widget/EdgeGlow.java
@@ -339,6 +339,7 @@
mEdgeScaleY = mEdgeScaleYStart +
(mEdgeScaleYFinish - mEdgeScaleYStart) *
interp * factor;
+ mState = STATE_RECEDE;
break;
case STATE_RECEDE:
mState = STATE_IDLE;
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index e26e99b..3255f6f 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -26,6 +26,7 @@
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.FocusFinder;
+import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.VelocityTracker;
@@ -634,6 +635,40 @@
}
@Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_SCROLL: {
+ if (!mIsBeingDragged) {
+ final float hscroll;
+ if ((event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0) {
+ hscroll = -event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+ } else {
+ hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
+ }
+ if (hscroll != 0) {
+ final int delta = (int) (hscroll * getHorizontalScrollFactor());
+ final int range = getScrollRange();
+ int oldScrollX = mScrollX;
+ int newScrollX = oldScrollX + delta;
+ if (newScrollX < 0) {
+ newScrollX = 0;
+ } else if (newScrollX > range) {
+ newScrollX = range;
+ }
+ if (newScrollX != oldScrollX) {
+ super.scrollTo(newScrollX, mScrollY);
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return super.onGenericMotionEvent(event);
+ }
+
+ @Override
protected void onOverScrolled(int scrollX, int scrollY,
boolean clampedX, boolean clampedY) {
// Treat animating scrolls differently; see #computeScroll() for why.
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 7a59178..2947ebe 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -608,7 +608,7 @@
case MotionEvent.ACTION_DOWN:
mLastMotionEventY = mLastDownEventY = event.getY();
removeAllCallbacks();
- hideInputControls();
+ mShowInputControlsAnimator.cancel();
mBeginEditOnUpEvent = false;
mAdjustScrollerOnUpEvent = true;
if (mDrawSelectorWheel) {
@@ -621,6 +621,7 @@
}
mBeginEditOnUpEvent = scrollersFinished;
mAdjustScrollerOnUpEvent = true;
+ hideInputControls();
return true;
}
if (isEventInViewHitRect(event, mInputText)
@@ -630,6 +631,7 @@
&& isEventInViewHitRect(event, mDecrementButton))) {
mAdjustScrollerOnUpEvent = false;
setDrawSelectorWheel(true);
+ hideInputControls();
return true;
}
break;
@@ -640,6 +642,7 @@
mBeginEditOnUpEvent = false;
onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
setDrawSelectorWheel(true);
+ hideInputControls();
return true;
}
break;
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 9932320..7aca0db 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -27,6 +27,7 @@
import android.os.StrictMode;
import android.util.AttributeSet;
import android.view.FocusFinder;
+import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.VelocityTracker;
@@ -631,6 +632,35 @@
}
@Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_SCROLL: {
+ if (!mIsBeingDragged) {
+ final float vscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+ if (vscroll != 0) {
+ final int delta = (int) (vscroll * getVerticalScrollFactor());
+ final int range = getScrollRange();
+ int oldScrollY = mScrollY;
+ int newScrollY = oldScrollY - delta;
+ if (newScrollY < 0) {
+ newScrollY = 0;
+ } else if (newScrollY > range) {
+ newScrollY = range;
+ }
+ if (newScrollY != oldScrollY) {
+ super.scrollTo(mScrollX, newScrollY);
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return super.onGenericMotionEvent(event);
+ }
+
+ @Override
protected void onOverScrolled(int scrollX, int scrollY,
boolean clampedX, boolean clampedY) {
// Treat animating scrolls differently; see #computeScroll() for why.
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 11e05e5..33d1225 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7389,6 +7389,22 @@
return superResult;
}
+ @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ if (mMovement != null && mText instanceof Spannable && mLayout != null) {
+ try {
+ if (mMovement.onGenericMotionEvent(this, (Spannable) mText, event)) {
+ return true;
+ }
+ } catch (AbstractMethodError ex) {
+ // onGenericMotionEvent was added to the MovementMethod interface in API 12.
+ // Ignore its absence in case third party applications implemented the
+ // interface directly.
+ }
+ }
+ return super.onGenericMotionEvent(event);
+ }
+
private void prepareCursorControllers() {
boolean windowSupportsHandles = false;
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index c72d0e8..5ac903d 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -318,10 +318,56 @@
}
}
- private void logPointerCoords(MotionEvent.PointerCoords coords, int id) {
+ private void logPointerCoords(int action, int index, MotionEvent.PointerCoords coords, int id) {
+ final String prefix;
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN:
+ prefix = "DOWN";
+ break;
+ case MotionEvent.ACTION_UP:
+ prefix = "UP";
+ break;
+ case MotionEvent.ACTION_MOVE:
+ prefix = "MOVE";
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ prefix = "CANCEL";
+ break;
+ case MotionEvent.ACTION_OUTSIDE:
+ prefix = "OUTSIDE";
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ if (index == ((action & MotionEvent.ACTION_POINTER_INDEX_MASK)
+ >> MotionEvent.ACTION_POINTER_INDEX_SHIFT)) {
+ prefix = "DOWN";
+ } else {
+ prefix = "MOVE";
+ }
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ if (index == ((action & MotionEvent.ACTION_POINTER_INDEX_MASK)
+ >> MotionEvent.ACTION_POINTER_INDEX_SHIFT)) {
+ prefix = "UP";
+ } else {
+ prefix = "MOVE";
+ }
+ break;
+ case MotionEvent.ACTION_HOVER_MOVE:
+ prefix = "HOVER MOVE";
+ break;
+ case MotionEvent.ACTION_SCROLL:
+ prefix = "SCROLL";
+ break;
+ default:
+ prefix = Integer.toString(action);
+ break;
+ }
+
Log.i(TAG, mText.clear()
.append("Pointer ").append(id + 1)
- .append(": (").append(coords.x, 3).append(", ").append(coords.y, 3)
+ .append(": ")
+ .append(prefix)
+ .append(" (").append(coords.x, 3).append(", ").append(coords.y, 3)
.append(") Pressure=").append(coords.pressure, 3)
.append(" Size=").append(coords.size, 3)
.append(" TouchMajor=").append(coords.touchMajor, 3)
@@ -335,7 +381,7 @@
.toString());
}
- public void addTouchEvent(MotionEvent event) {
+ public void addPointerEvent(MotionEvent event) {
synchronized (mPointers) {
int action = event.getAction();
@@ -363,10 +409,16 @@
ps.mCurDown = false;
}
mCurDown = true;
+ mCurNumPointers = 0;
mMaxNumPointers = 0;
mVelocity.clear();
}
-
+
+ mCurNumPointers += 1;
+ if (mMaxNumPointers < mCurNumPointers) {
+ mMaxNumPointers = mCurNumPointers;
+ }
+
final int id = event.getPointerId(index);
while (NP <= id) {
PointerState ps = new PointerState();
@@ -375,49 +427,41 @@
}
if (mActivePointerId < 0 ||
- ! mPointers.get(mActivePointerId).mCurDown) {
+ !mPointers.get(mActivePointerId).mCurDown) {
mActivePointerId = id;
}
final PointerState ps = mPointers.get(id);
ps.mCurDown = true;
- if (mPrintCoords) {
- Log.i(TAG, mText.clear().append("Pointer ")
- .append(id + 1).append(": DOWN").toString());
- }
}
-
- final int NI = event.getPointerCount();
- final boolean hover = (action == MotionEvent.ACTION_HOVER_MOVE);
- mCurDown = action != MotionEvent.ACTION_UP
- && action != MotionEvent.ACTION_CANCEL
- && !hover;
- mCurNumPointers = mCurDown ? NI : 0;
- if (mMaxNumPointers < mCurNumPointers) {
- mMaxNumPointers = mCurNumPointers;
- }
+ final int NI = event.getPointerCount();
mVelocity.addMovement(event);
mVelocity.computeCurrentVelocity(1);
-
- for (int i=0; i<NI; i++) {
- final int id = event.getPointerId(i);
- final PointerState ps = hover ? null : mPointers.get(id);
- final PointerCoords coords = ps != null ? ps.mCoords : mHoverCoords;
- final int N = event.getHistorySize();
- for (int j=0; j<N; j++) {
- event.getHistoricalPointerCoords(i, j, coords);
+
+ final int N = event.getHistorySize();
+ for (int historyPos = 0; historyPos < N; historyPos++) {
+ for (int i = 0; i < NI; i++) {
+ final int id = event.getPointerId(i);
+ final PointerState ps = mCurDown ? mPointers.get(id) : null;
+ final PointerCoords coords = ps != null ? ps.mCoords : mHoverCoords;
+ event.getHistoricalPointerCoords(i, historyPos, coords);
if (mPrintCoords) {
- logPointerCoords(coords, id);
+ logPointerCoords(action, i, coords, id);
}
if (ps != null) {
- ps.addTrace(event.getHistoricalX(i, j), event.getHistoricalY(i, j));
+ ps.addTrace(coords.x, coords.y);
}
}
+ }
+ for (int i = 0; i < NI; i++) {
+ final int id = event.getPointerId(i);
+ final PointerState ps = mCurDown ? mPointers.get(id) : null;
+ final PointerCoords coords = ps != null ? ps.mCoords : mHoverCoords;
event.getPointerCoords(i, coords);
if (mPrintCoords) {
- logPointerCoords(coords, id);
+ logPointerCoords(action, i, coords, id);
}
if (ps != null) {
ps.addTrace(coords.x, coords.y);
@@ -425,7 +469,7 @@
ps.mYVelocity = mVelocity.getYVelocity(id);
}
}
-
+
if (action == MotionEvent.ACTION_UP
|| action == MotionEvent.ACTION_CANCEL
|| (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {
@@ -435,15 +479,13 @@
final int id = event.getPointerId(index);
final PointerState ps = mPointers.get(id);
ps.mCurDown = false;
- if (mPrintCoords) {
- Log.i(TAG, mText.clear().append("Pointer ")
- .append(id + 1).append(": UP").toString());
- }
if (action == MotionEvent.ACTION_UP
|| action == MotionEvent.ACTION_CANCEL) {
mCurDown = false;
+ mCurNumPointers = 0;
} else {
+ mCurNumPointers -= 1;
if (mActivePointerId == id) {
mActivePointerId = event.getPointerId(index == 0 ? 1 : 0);
}
@@ -462,11 +504,20 @@
@Override
public boolean onTouchEvent(MotionEvent event) {
- addTouchEvent(event);
+ addPointerEvent(event);
return true;
}
@Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ addPointerEvent(event);
+ return true;
+ }
+ return super.onGenericMotionEvent(event);
+ }
+
+ @Override
public boolean onTrackballEvent(MotionEvent event) {
Log.i(TAG, "Trackball: " + event);
return super.onTrackballEvent(event);
diff --git a/core/jni/android_view_Display.cpp b/core/jni/android_view_Display.cpp
index ac8835a..160d654 100644
--- a/core/jni/android_view_Display.cpp
+++ b/core/jni/android_view_Display.cpp
@@ -44,6 +44,8 @@
};
static offsets_t offsets;
+static int gShortSize = -1;
+static int gLongSize = -1;
static int gOldSize = -1;
static int gNewSize = -1;
@@ -76,6 +78,10 @@
{
DisplayID dpy = env->GetIntField(clazz, offsets.display);
jint w = SurfaceComposerClient::getDisplayWidth(dpy);
+ if (gShortSize > 0) {
+ jint h = SurfaceComposerClient::getDisplayHeight(dpy);
+ return w < h ? gShortSize : gLongSize;
+ }
return w == gOldSize ? gNewSize : w;
}
@@ -84,9 +90,27 @@
{
DisplayID dpy = env->GetIntField(clazz, offsets.display);
int h = SurfaceComposerClient::getDisplayHeight(dpy);
+ if (gShortSize > 0) {
+ jint w = SurfaceComposerClient::getDisplayWidth(dpy);
+ return h < w ? gShortSize : gLongSize;
+ }
return h == gOldSize ? gNewSize : h;
}
+static jint android_view_Display_getRealWidth(
+ JNIEnv* env, jobject clazz)
+{
+ DisplayID dpy = env->GetIntField(clazz, offsets.display);
+ return SurfaceComposerClient::getDisplayWidth(dpy);
+}
+
+static jint android_view_Display_getRealHeight(
+ JNIEnv* env, jobject clazz)
+{
+ DisplayID dpy = env->GetIntField(clazz, offsets.display);
+ return SurfaceComposerClient::getDisplayHeight(dpy);
+}
+
static jint android_view_Display_getOrientation(
JNIEnv* env, jobject clazz)
{
@@ -100,13 +124,6 @@
return SurfaceComposerClient::getNumberOfDisplays();
}
-static jint android_view_Display_unmapDisplaySize(
- JNIEnv* env, jclass clazz, jint newSize)
-{
- if (newSize == gNewSize) return gOldSize;
- return newSize;
-}
-
// ----------------------------------------------------------------------------
const char* const kClassPathName = "android/view/Display";
@@ -124,10 +141,12 @@
(void*)android_view_Display_getWidth },
{ "getHeight", "()I",
(void*)android_view_Display_getHeight },
+ { "getRealWidth", "()I",
+ (void*)android_view_Display_getRealWidth },
+ { "getRealHeight", "()I",
+ (void*)android_view_Display_getRealHeight },
{ "getOrientation", "()I",
- (void*)android_view_Display_getOrientation },
- { "unmapDisplaySize", "(I)I",
- (void*)android_view_Display_unmapDisplaySize }
+ (void*)android_view_Display_getOrientation }
};
void nativeClassInit(JNIEnv* env, jclass clazz)
@@ -146,7 +165,15 @@
int len = property_get("persist.demo.screensizehack", buf, "");
if (len > 0) {
int temp1, temp2;
- if (sscanf(buf, "%d=%d", &temp1, &temp2) == 2) {
+ if (sscanf(buf, "%dx%d", &temp1, &temp2) == 2) {
+ if (temp1 < temp2) {
+ gShortSize = temp1;
+ gLongSize = temp2;
+ } else {
+ gShortSize = temp2;
+ gLongSize = temp1;
+ }
+ } else if (sscanf(buf, "%d=%d", &temp1, &temp2) == 2) {
gOldSize = temp1;
gNewSize = temp2;
}
@@ -157,4 +184,3 @@
}
};
-
diff --git a/core/jni/android_view_InputChannel.cpp b/core/jni/android_view_InputChannel.cpp
index 4a4393a..0c2801c 100644
--- a/core/jni/android_view_InputChannel.cpp
+++ b/core/jni/android_view_InputChannel.cpp
@@ -186,9 +186,21 @@
bool isInitialized = parcel->readInt32();
if (isInitialized) {
String8 name = parcel->readString8();
- int32_t ashmemFd = dup(parcel->readFileDescriptor());
- int32_t receivePipeFd = dup(parcel->readFileDescriptor());
- int32_t sendPipeFd = dup(parcel->readFileDescriptor());
+ int32_t parcelAshmemFd = parcel->readFileDescriptor();
+ int32_t ashmemFd = dup(parcelAshmemFd);
+ if (ashmemFd < 0) {
+ LOGE("Error %d dup ashmem fd %d.", errno, parcelAshmemFd);
+ }
+ int32_t parcelReceivePipeFd = parcel->readFileDescriptor();
+ int32_t receivePipeFd = dup(parcelReceivePipeFd);
+ if (receivePipeFd < 0) {
+ LOGE("Error %d dup receive pipe fd %d.", errno, parcelReceivePipeFd);
+ }
+ int32_t parcelSendPipeFd = parcel->readFileDescriptor();
+ int32_t sendPipeFd = dup(parcelSendPipeFd);
+ if (sendPipeFd < 0) {
+ LOGE("Error %d dup send pipe fd %d.", errno, parcelSendPipeFd);
+ }
if (ashmemFd < 0 || receivePipeFd < 0 || sendPipeFd < 0) {
if (ashmemFd >= 0) ::close(ashmemFd);
if (receivePipeFd >= 0) ::close(receivePipeFd);
diff --git a/core/res/res/layout/webview_select_singlechoice.xml b/core/res/res/layout/webview_select_singlechoice.xml
new file mode 100644
index 0000000..c0753a8
--- /dev/null
+++ b/core/res/res/layout/webview_select_singlechoice.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:textColor="?android:attr/textColorAlertDialogListItem"
+ android:gravity="center_vertical"
+ android:paddingLeft="12dip"
+ android:paddingRight="7dip"
+ android:ellipsize="marquee"
+ style="?android:attr/spinnerDropDownItemStyle"
+ android:background="?android:attr/activatedBackgroundIndicator"
+/>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 361bb6c..28690f5 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1869,6 +1869,115 @@
e.g. (John Smith)(, )(123 Main Street) -->
<string name="autofill_address_summary_format">$1$2$3</string>
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_attention_ignored_re">attention|attn</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_region_ignored_re">province|region|other<!-- es -->|provincia<!-- pt-BR, pt-PT -->|bairro|suburb</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_company_re">company|business|organization|organisation|department<!-- de-DE -->|firma|firmenname<!-- es -->|empresa<!-- fr-FR -->|societe|société<!-- it-IT -->|ragione.?sociale<!-- ja-JP -->|会社<!-- ru -->|название.?компании<!-- zh-CN -->|单位|公司</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_address_line_1_re">address.?line|address1|addr1|street<!-- de-DE -->|strasse|straße|hausnummer|housenumber<!-- en-GB -->|house.?name<!-- es -->|direccion|dirección<!-- fr-FR -->|adresse<!-- it-IT -->|indirizzo<!-- ja-JP -->|住所1<!-- pt-BR, pt-PT -->|morada|endereço<!-- ru -->|Адрес<!-- zh-CN -->|地址</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_address_line_1_label_re">address<!-- fr-FR -->|adresse<!-- it-IT -->|indirizzo<!-- ja-JP -->|住所<!-- zh-CN -->|地址</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_address_line_2_re">address.?line2|address2|addr2|street|suite|unit<!-- de-DE -->|adresszusatz|ergänzende.?angaben<!-- es -->|direccion2|colonia|adicional<!-- fr-FR -->|addresssuppl|complementnom|appartement<!-- it-IT -->|indirizzo2<!-- ja-JP -->|住所2</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_address_line_3_re">address.?line3|address3|addr3|street|line3<!-- es -->|municipio<!-- fr-FR -->|batiment|residence<!-- it-IT -->|indirizzo3</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_country_re">country|location<!-- ja-JP -->|国<!-- zh-CN -->|国家</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_zip_code_re">zip|postal|post code|pcode|^1z$<!-- de-DE -->|postleitzahl<!-- es -->|cp<!-- fr-FR -->|cdp<!-- it-IT -->|cap<!-- ja-JP -->|郵便番号<!-- pt-BR, pt-PT -->|codigo|codpos|cep<!-- ru -->|Почтовый.?Индекс<!--zh-CN -->|邮政编码|邮编<!-- zh-TW -->|郵遞區號</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_zip_4_re">zip|^-$|post2<!-- pt-BR, pt-PT -->|codpos2</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_city_re">city|town<!-- de-DE -->|ort|stadt<!-- en-AU -->|suburb<!-- es -->|ciudad|provincia|localidad|poblacion<!-- fr-FR -->|ville|commune<!-- it-IT -->|localita<!-- ja-JP -->|市区町村<!-- pt-BR, pt-PT -->|cidade<!-- ru -->|Город<!-- zh-CN -->|市<!-- zh-TW -->|分區</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_state_re">state|county|region|province<!-- de-DE -->|land<!-- en-UK -->|county|principality<!-- ja-JP -->|都道府県<!-- pt-BR, pt-PT -->|estado|provincia<!-- ru -->|область<!-- zh-CN -->|省<!-- zh-TW -->|地區</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_address_type_same_as_re">same as</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_address_type_use_my_re">use my</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_billing_designator_re">bill</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_shipping_designator_re">ship</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_email_re">e.?mail<!-- ja-JP -->|メールアドレス<!-- ru -->|Электронной.?Почты<!-- zh-CN -->|邮件|邮箱<!-- zh-TW -->|電郵地址</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_username_re">user.?name|user.?id<!-- de-DE -->|vollständiger.?name<!-- zh-CN -->|用户名</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_name_re">^name|full.?name|your.?name|customer.?name|firstandlastname<!-- es -->|nombre.*y.*apellidos<!-- fr-FR -->|^nom<!-- ja-JP -->|お名前|氏名<!-- pt-BR, pt-PT -->|^nome<!-- zh-CN -->|姓名</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_name_specific_re">^name<!-- fr-FR -->|^nom<!-- pt-BR, pt-PT -->|^nome</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+
+ <string name="autofill_first_name_re">irst.*name|initials|fname|first$<!-- de-DE -->|vorname<!-- es -->|nombre<!-- fr-FR -->|forename|prénom|prenom<!-- ja-JP -->|名<!-- pt-BR, pt-PT -->|nome<!-- ru -->|Имя</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_middle_initial_re">middle.*initial|m\\.i\\.|mi$</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_middle_name_re">middle.*name|mname|middle$<!-- es -->|apellido.?materno|lastlastname</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_last_name_re">last.*name|lname|surname|last$<!-- de-DE -->|nachname<!-- es -->|apellidos<!-- fr-FR -->|famille|^nom<!-- it-IT -->|cognome<!-- ja-JP -->|姓<!-- pt-BR, pt-PT -->|morada|apelidos|surename|sobrenome<!-- ru -->|Фамилия</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_phone_re">phone<!-- de-DE -->|telefonnummer<!-- es -->|telefono|teléfono<!-- fr-FR -->|telfixe<!-- ja-JP -->|電話<!-- pt-BR, pt-PT -->|telefone|telemovel<!-- ru -->|телефон<!-- zh-CN -->|电话</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_area_code_re">area code</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_phone_prefix_re">^-$|\\)$|prefix<!-- fr-FR -->|preselection<!-- pt-BR, pt-PT -->|ddd</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_phone_suffix_re">^-$|suffix</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_phone_extension_re">ext<!-- pt-BR, pt-PT -->|ramal</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_name_on_card_re">card.?holder|name.?on.?card|ccname|owner<!-- de-DE -->|karteninhaber<!-- es -->|nombre.*tarjeta<!-- fr-FR -->|nom.*carte<!-- it-IT -->|nome.*cart<!-- ja-JP -->|名前<!-- ru -->|Имя.*карты<!-- zh-CN -->|信用卡开户名|开户名|持卡人姓名<!-- zh-TW -->|持卡人姓名</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_name_on_card_contextual_re">name</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_card_cvc_re">verification|card identification|cvn|security code|cvv code|cvc</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_card_number_re">number|card.?#|card.?no|ccnum<!-- de-DE -->|nummer<!-- es -->|credito|numero|número<!-- fr-FR -->|numéro<!-- ja-JP -->|カード番号<!-- ru -->|Номер.*карты<!-- zh-CN -->|信用卡号|信用卡号码<!-- zh-TW -->|信用卡卡號</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_expiration_month_re">expir|exp.*month|exp.*date|ccmonth<!-- de-DE -->|gueltig|gültig|monat<!-- es -->|fecha<!-- fr-FR -->|date.*exp<!-- it-IT -->|scadenza<!-- ja-JP -->|有効期限<!-- pt-BR, pt-PT -->|validade<!-- ru -->|Срок действия карты<!-- zh-CN -->|月</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_expiration_date_re">exp|^/|year<!-- de-DE -->|ablaufdatum|gueltig|gültig|yahr<!-- es -->|fecha<!-- it-IT -->|scadenza<!-- ja-JP -->|有効期限<!-- pt-BR, pt-PT -->|validade<!-- ru -->|Срок действия карты<!-- zh-CN -->|年|有效期</string>
+
+ <!-- Do not translate. Regex used by AutoFill. -->
+ <string name="autofill_card_ignored_re">^card</string>
+
<!-- Title of an application permission, listed so the user can choose whether
they want to allow the application to do this. -->
<string name="permlab_readHistoryBookmarks">read Browser\'s history and bookmarks</string>
diff --git a/core/tests/coretests/src/android/util/LruCacheTest.java b/core/tests/coretests/src/android/util/LruCacheTest.java
index cf252e6..7e46e26 100644
--- a/core/tests/coretests/src/android/util/LruCacheTest.java
+++ b/core/tests/coretests/src/android/util/LruCacheTest.java
@@ -18,6 +18,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import junit.framework.TestCase;
@@ -166,22 +167,16 @@
}
public void testEntryEvictedWhenFull() {
- List<String> expectedEvictionLog = new ArrayList<String>();
- final List<String> evictionLog = new ArrayList<String>();
- LruCache<String, String> cache = new LruCache<String, String>(3) {
- @Override protected void entryEvicted(String key, String value) {
- evictionLog.add(key + "=" + value);
- }
- };
+ List<String> log = new ArrayList<String>();
+ LruCache<String, String> cache = newRemovalLogCache(log);
cache.put("a", "A");
cache.put("b", "B");
cache.put("c", "C");
- assertEquals(expectedEvictionLog, evictionLog);
+ assertEquals(Collections.<String>emptyList(), log);
cache.put("d", "D");
- expectedEvictionLog.add("a=A");
- assertEquals(expectedEvictionLog, evictionLog);
+ assertEquals(Arrays.asList("a=A"), log);
}
/**
@@ -309,19 +304,14 @@
}
public void testEvictAll() {
- final List<String> evictionLog = new ArrayList<String>();
- LruCache<String, String> cache = new LruCache<String, String>(10) {
- @Override protected void entryEvicted(String key, String value) {
- evictionLog.add(key + "=" + value);
- }
- };
-
+ List<String> log = new ArrayList<String>();
+ LruCache<String, String> cache = newRemovalLogCache(log);
cache.put("a", "A");
cache.put("b", "B");
cache.put("c", "C");
cache.evictAll();
assertEquals(0, cache.size());
- assertEquals(Arrays.asList("a=A", "b=B", "c=C"), evictionLog);
+ assertEquals(Arrays.asList("a=A", "b=B", "c=C"), log);
}
public void testEvictAllEvictsSizeZeroElements() {
@@ -337,16 +327,6 @@
assertSnapshot(cache);
}
- public void testRemoveDoesNotCallEntryEvicted() {
- LruCache<String, String> cache = new LruCache<String, String>(10) {
- @Override protected void entryEvicted(String key, String value) {
- fail();
- }
- };
- cache.put("a", "A");
- assertEquals("A", cache.remove("a"));
- }
-
public void testRemoveWithCustomSizes() {
LruCache<String, String> cache = new LruCache<String, String>(10) {
@Override protected int sizeOf(String key, String value) {
@@ -376,6 +356,99 @@
}
}
+ public void testRemoveCallsEntryRemoved() {
+ List<String> log = new ArrayList<String>();
+ LruCache<String, String> cache = newRemovalLogCache(log);
+ cache.put("a", "A");
+ cache.remove("a");
+ assertEquals(Arrays.asList("a=A>null"), log);
+ }
+
+ public void testPutCallsEntryRemoved() {
+ List<String> log = new ArrayList<String>();
+ LruCache<String, String> cache = newRemovalLogCache(log);
+ cache.put("a", "A");
+ cache.put("a", "A2");
+ assertEquals(Arrays.asList("a=A>A2"), log);
+ }
+
+ public void testEntryRemovedIsCalledWithoutSynchronization() {
+ LruCache<String, String> cache = new LruCache<String, String>(3) {
+ @Override protected void entryRemoved(
+ boolean evicted, String key, String oldValue, String newValue) {
+ assertFalse(Thread.holdsLock(this));
+ }
+ };
+
+ cache.put("a", "A");
+ cache.put("a", "A2"); // replaced
+ cache.put("b", "B");
+ cache.put("c", "C");
+ cache.put("d", "D"); // single eviction
+ cache.remove("a"); // removed
+ cache.evictAll(); // multiple eviction
+ }
+
+ public void testCreateIsCalledWithoutSynchronization() {
+ LruCache<String, String> cache = new LruCache<String, String>(3) {
+ @Override protected String create(String key) {
+ assertFalse(Thread.holdsLock(this));
+ return null;
+ }
+ };
+
+ cache.get("a");
+ }
+
+ /**
+ * Test what happens when a value is added to the map while create is
+ * working. The map value should be returned by get(), and the created value
+ * should be released with entryRemoved().
+ */
+ public void testCreateWithConcurrentPut() {
+ final List<String> log = new ArrayList<String>();
+ LruCache<String, String> cache = new LruCache<String, String>(3) {
+ @Override protected String create(String key) {
+ put(key, "B");
+ return "A";
+ }
+ @Override protected void entryRemoved(
+ boolean evicted, String key, String oldValue, String newValue) {
+ log.add(key + "=" + oldValue + ">" + newValue);
+ }
+ };
+
+ assertEquals("B", cache.get("a"));
+ assertEquals(Arrays.asList("a=A>B"), log);
+ }
+
+ /**
+ * Test what happens when two creates happen concurrently. The result from
+ * the first create to return is returned by both gets. The other created
+ * values should be released with entryRemove().
+ */
+ public void testCreateWithConcurrentCreate() {
+ final List<String> log = new ArrayList<String>();
+ LruCache<String, Integer> cache = new LruCache<String, Integer>(3) {
+ int callCount = 0;
+ @Override protected Integer create(String key) {
+ if (callCount++ == 0) {
+ assertEquals(2, get(key).intValue());
+ return 1;
+ } else {
+ return 2;
+ }
+ }
+ @Override protected void entryRemoved(
+ boolean evicted, String key, Integer oldValue, Integer newValue) {
+ log.add(key + "=" + oldValue + ">" + newValue);
+ }
+ };
+
+ assertEquals(2, cache.get("a").intValue());
+ assertEquals(Arrays.asList("a=1>2"), log);
+ }
+
private LruCache<String, String> newCreatingCache() {
return new LruCache<String, String>(3) {
@Override protected String create(String key) {
@@ -384,6 +457,18 @@
};
}
+ private LruCache<String, String> newRemovalLogCache(final List<String> log) {
+ return new LruCache<String, String>(3) {
+ @Override protected void entryRemoved(
+ boolean evicted, String key, String oldValue, String newValue) {
+ String message = evicted
+ ? (key + "=" + oldValue)
+ : (key + "=" + oldValue + ">" + newValue);
+ log.add(message);
+ }
+ };
+ }
+
private void assertHit(LruCache<String, String> cache, String key, String value) {
assertEquals(value, cache.get(key));
expectedHitCount++;
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 2248752..f1bb59f 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -11,14 +11,10 @@
</div><!-- end homeTitle -->
<div id="announcement-block">
<!-- total max width is 520px -->
- <img src="{@docRoot}images/home/market-intl.png" alt="Android
-Market" width="104" height="120" style="padding:10px 60px 5px" />
- <div id="announcement" style="width:295px">
-<p>We're pleased to announce that paid apps are available in more locations of the world! Developers
-from 20 more locations can now sell paid apps on Android Market. Users in more locations will also
-soon be able to purchase apps.</p><p><a
-href="http://android-developers.blogspot.com/2010/09/more-countries-more-sellers-more-buyers.html">
-Learn more »</a></p>
+ <img src="{@docRoot}assets/images/home/GDC2011.png" alt="Android at GDC 2011" width="203px" style="padding-left:22px;padding-bottom:28px;padding-top:22px;"/>
+ <div id="announcement" style="width:275px">
+ <p>Android will be at the <a href="http://www.gdconf.com/">2011 Game Developers Conference</a> in San Francisco, from March 1st to 4th. We're looking forward to seeing you there!</p>
+ <p><a href="http://android-developers.blogspot.com/2011/02/heading-for-gdc.html">Learn more »</a></p>
</div> <!-- end annoucement -->
</div> <!-- end annoucement-block -->
</div><!-- end topAnnouncement -->
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 2d23fe9..970b207 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -45,7 +45,13 @@
* be done by transforming (1, 1, 0, 1).
*
* <p>The texture object uses the GL_TEXTURE_EXTERNAL_OES texture target, which is defined by the
- * OES_EGL_image_external OpenGL ES extension. This limits how the texture may be used.
+ * <a href="http://www.khronos.org/registry/gles/extensions/OES/OES_EGL_image_external.txt">
+ * GL_OES_EGL_image_external</a> OpenGL ES extension. This limits how the texture may be used.
+ * Each time the texture is bound it must be bound to the GL_TEXTURE_EXTERNAL_OES target rather than
+ * the GL_TEXTURE_2D target. Additionally, any OpenGL ES 2.0 shader that samples from the texture
+ * must declare its use of this extension using, for example, an "#extension
+ * GL_OES_EGL_image_external : require" directive. Such shaders must also access the texture using
+ * the samplerExternalOES GLSL sampler type.
*
* <p>SurfaceTexture objects may be created on any thread. {@link #updateTexImage} may only be
* called on the thread with the OpenGL ES context that contains the texture object. The
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
index 25c8beb..5ab4804 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/Android.mk
@@ -152,9 +152,4 @@
include $(BUILD_HOST_STATIC_LIBRARY)
-# include the java examples
-include $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk,\
- java \
- ))
-
endif #simulator
diff --git a/libs/rs/java/Android.mk b/libs/rs/java/Android.mk
deleted file mode 100644
index 5053e7d..0000000
--- a/libs/rs/java/Android.mk
+++ /dev/null
@@ -1 +0,0 @@
-include $(call all-subdir-makefiles)
diff --git a/libs/rs/java/Balls/Android.mk b/libs/rs/java/Balls/Android.mk
deleted file mode 100644
index 5b65628..0000000
--- a/libs/rs/java/Balls/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright (C) 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.
-# 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.
-#
-
-ifneq ($(TARGET_SIMULATOR),true)
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
-#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
-
-LOCAL_PACKAGE_NAME := Balls
-
-include $(BUILD_PACKAGE)
-
-endif
diff --git a/libs/rs/java/Balls/AndroidManifest.xml b/libs/rs/java/Balls/AndroidManifest.xml
deleted file mode 100644
index f3384ec..0000000
--- a/libs/rs/java/Balls/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.balls">
- <uses-sdk android:minSdkVersion="11" />
- <application
- android:label="Balls"
- android:icon="@drawable/test_pattern">
- <activity android:name="Balls"
- android:screenOrientation="landscape">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/libs/rs/java/Balls/_index.html b/libs/rs/java/Balls/_index.html
deleted file mode 100644
index 8760485..0000000
--- a/libs/rs/java/Balls/_index.html
+++ /dev/null
@@ -1 +0,0 @@
-<p>A brute force physics simulation that renders many balls onto the screen and moves them according to user touch and gravity.</p>
\ No newline at end of file
diff --git a/libs/rs/java/Balls/res/drawable/flares.png b/libs/rs/java/Balls/res/drawable/flares.png
deleted file mode 100644
index 3a5c970..0000000
--- a/libs/rs/java/Balls/res/drawable/flares.png
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/Balls/res/drawable/test_pattern.png b/libs/rs/java/Balls/res/drawable/test_pattern.png
deleted file mode 100644
index e7d1455..0000000
--- a/libs/rs/java/Balls/res/drawable/test_pattern.png
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/Balls/src/com/android/balls/Balls.java b/libs/rs/java/Balls/src/com/android/balls/Balls.java
deleted file mode 100644
index c24e616..0000000
--- a/libs/rs/java/Balls/src/com/android/balls/Balls.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 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.
- * 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.balls;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-
-import android.app.Activity;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.Settings.System;
-import android.util.Config;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.widget.Button;
-import android.widget.ListView;
-
-import java.lang.Runtime;
-
-import android.app.Activity;
-import android.content.Context;
-import android.os.Bundle;
-import android.view.View;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-
-public class Balls extends Activity implements SensorEventListener {
- //EventListener mListener = new EventListener();
-
- private static final String LOG_TAG = "libRS_jni";
- private static final boolean DEBUG = false;
- private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
-
- private BallsView mView;
- private SensorManager mSensorManager;
-
- // get the current looper (from your Activity UI thread for instance
-
-
- public void onSensorChanged(SensorEvent event) {
- //android.util.Log.d("rs", "sensor: " + event.sensor + ", x: " + event.values[0] + ", y: " + event.values[1] + ", z: " + event.values[2]);
- synchronized (this) {
- if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
- if(mView != null) {
- mView.setAccel(event.values[0], event.values[1], event.values[2]);
- }
- }
- }
- }
-
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- }
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
-
- // Create our Preview view and set it as the content of our
- // Activity
- mView = new BallsView(this);
- setContentView(mView);
- }
-
- @Override
- protected void onResume() {
- mSensorManager.registerListener(this,
- mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
- SensorManager.SENSOR_DELAY_FASTEST);
-
- // Ideally a game should implement onResume() and onPause()
- // to take appropriate action when the activity looses focus
- super.onResume();
- mView.resume();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- mView.pause();
- Runtime.getRuntime().exit(0);
- }
-
- @Override
- protected void onStop() {
- mSensorManager.unregisterListener(this);
- super.onStop();
- }
-
- static void log(String message) {
- if (LOG_ENABLED) {
- Log.v(LOG_TAG, message);
- }
- }
-
-
-}
-
diff --git a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
deleted file mode 100644
index 50ee921..0000000
--- a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 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.
- * 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.balls;
-
-import android.content.res.Resources;
-import android.renderscript.*;
-import android.util.Log;
-
-public class BallsRS {
- public static final int PART_COUNT = 900;
-
- public BallsRS() {
- }
-
- private Resources mRes;
- private RenderScriptGL mRS;
- private ScriptC_balls mScript;
- private ScriptC_ball_physics mPhysicsScript;
- private ProgramFragment mPFLines;
- private ProgramFragment mPFPoints;
- private ProgramVertex mPV;
- private ScriptField_Point mPoints;
- private ScriptField_VpConsts mVpConsts;
-
- void updateProjectionMatrices() {
- mVpConsts = new ScriptField_VpConsts(mRS, 1,
- Allocation.USAGE_SCRIPT |
- Allocation.USAGE_GRAPHICS_CONSTANTS);
- ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item();
- Matrix4f mvp = new Matrix4f();
- mvp.loadOrtho(0, mRS.getWidth(), mRS.getHeight(), 0, -1, 1);
- i.MVP = mvp;
- mVpConsts.set(i, 0, true);
- }
-
- private void createProgramVertex() {
- updateProjectionMatrices();
-
- ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS);
- String t = "varying vec4 varColor;\n" +
- "void main() {\n" +
- " vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" +
- " pos.xy = ATTRIB_position;\n" +
- " gl_Position = UNI_MVP * pos;\n" +
- " varColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
- " gl_PointSize = ATTRIB_size;\n" +
- "}\n";
- sb.setShader(t);
- sb.addConstant(mVpConsts.getType());
- sb.addInput(mPoints.getElement());
- ProgramVertex pvs = sb.create();
- pvs.bindConstants(mVpConsts.getAllocation(), 0);
- mRS.bindProgramVertex(pvs);
- }
-
- private Allocation loadTexture(int id) {
- final Allocation allocation =
- Allocation.createFromBitmapResource(mRS, mRes,
- id, Allocation.MipmapControl.MIPMAP_NONE,
- Allocation.USAGE_GRAPHICS_TEXTURE);
- return allocation;
- }
-
- ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
- ProgramStore.Builder builder = new ProgramStore.Builder(rs);
- builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
- builder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ONE);
- builder.setDitherEnabled(false);
- builder.setDepthMaskEnabled(false);
- return builder.create();
- }
-
- public void init(RenderScriptGL rs, Resources res, int width, int height) {
- mRS = rs;
- mRes = res;
-
- ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
- pfb.setPointSpriteTexCoordinateReplacement(true);
- pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
- ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
- pfb.setVaryingColor(true);
- mPFPoints = pfb.create();
-
- pfb = new ProgramFragmentFixedFunction.Builder(rs);
- pfb.setVaryingColor(true);
- mPFLines = pfb.create();
-
- android.util.Log.e("rs", "Load texture");
- mPFPoints.bindTexture(loadTexture(R.drawable.flares), 0);
-
- mPoints = new ScriptField_Point(mRS, PART_COUNT, Allocation.USAGE_SCRIPT);
-
- Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
- smb.addVertexAllocation(mPoints.getAllocation());
- smb.addIndexSetType(Mesh.Primitive.POINT);
- Mesh smP = smb.create();
-
- mPhysicsScript = new ScriptC_ball_physics(mRS, mRes, R.raw.ball_physics);
-
- mScript = new ScriptC_balls(mRS, mRes, R.raw.balls);
- mScript.set_partMesh(smP);
- mScript.set_physics_script(mPhysicsScript);
- mScript.bind_point(mPoints);
- mScript.bind_balls1(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT));
- mScript.bind_balls2(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT));
-
- mScript.set_gPFLines(mPFLines);
- mScript.set_gPFPoints(mPFPoints);
- createProgramVertex();
-
- mRS.bindProgramStore(BLEND_ADD_DEPTH_NONE(mRS));
-
- mPhysicsScript.set_gMinPos(new Float2(5, 5));
- mPhysicsScript.set_gMaxPos(new Float2(width - 5, height - 5));
-
- mScript.invoke_initParts(width, height);
-
- mRS.bindRootScript(mScript);
- }
-
- public void newTouchPosition(float x, float y, float pressure, int id) {
- mPhysicsScript.invoke_touch(x, y, pressure, id);
- }
-
- public void setAccel(float x, float y) {
- mPhysicsScript.set_gGravityVector(new Float2(x, y));
- }
-
-}
diff --git a/libs/rs/java/Balls/src/com/android/balls/BallsView.java b/libs/rs/java/Balls/src/com/android/balls/BallsView.java
deleted file mode 100644
index 4442eec..0000000
--- a/libs/rs/java/Balls/src/com/android/balls/BallsView.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 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.
- * 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.balls;
-
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-import android.renderscript.RenderScriptGL;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-public class BallsView extends RSSurfaceView {
-
- public BallsView(Context context) {
- super(context);
- //setFocusable(true);
- }
-
- private RenderScriptGL mRS;
- private BallsRS mRender;
-
- public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
- super.surfaceChanged(holder, format, w, h);
- if (mRS == null) {
- RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
- mRS = createRenderScriptGL(sc);
- mRS.setSurface(holder, w, h);
- mRender = new BallsRS();
- mRender.init(mRS, getResources(), w, h);
- }
- mRender.updateProjectionMatrices();
- }
-
- @Override
- protected void onDetachedFromWindow() {
- if(mRS != null) {
- mRS = null;
- destroyRenderScriptGL();
- }
- }
-
-
- @Override
- public boolean onTouchEvent(MotionEvent ev)
- {
- int act = ev.getActionMasked();
- if (act == ev.ACTION_UP) {
- mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0));
- return false;
- } else if (act == MotionEvent.ACTION_POINTER_UP) {
- // only one pointer going up, we can get the index like this
- int pointerIndex = ev.getActionIndex();
- int pointerId = ev.getPointerId(pointerIndex);
- mRender.newTouchPosition(0, 0, 0, pointerId);
- return false;
- }
- int count = ev.getHistorySize();
- int pcount = ev.getPointerCount();
-
- for (int p=0; p < pcount; p++) {
- int id = ev.getPointerId(p);
- mRender.newTouchPosition(ev.getX(p),
- ev.getY(p),
- ev.getPressure(p),
- id);
-
- for (int i=0; i < count; i++) {
- mRender.newTouchPosition(ev.getHistoricalX(p, i),
- ev.getHistoricalY(p, i),
- ev.getHistoricalPressure(p, i),
- id);
- }
- }
- return true;
- }
-
- void setAccel(float x, float y, float z) {
- if (mRender == null) {
- return;
- }
- mRender.setAccel(x, -y);
- }
-
-}
-
-
diff --git a/libs/rs/java/Balls/src/com/android/balls/ball_physics.rs b/libs/rs/java/Balls/src/com/android/balls/ball_physics.rs
deleted file mode 100644
index ff38be5..0000000
--- a/libs/rs/java/Balls/src/com/android/balls/ball_physics.rs
+++ /dev/null
@@ -1,146 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(com.android.balls)
-
-#include "balls.rsh"
-
-float2 gGravityVector = {0.f, 9.8f};
-
-float2 gMinPos = {0.f, 0.f};
-float2 gMaxPos = {1280.f, 700.f};
-
-static float2 touchPos[10];
-static float touchPressure[10];
-
-void touch(float x, float y, float pressure, int id) {
- if (id >= 10) {
- return;
- }
-
- touchPos[id].x = x;
- touchPos[id].y = y;
- touchPressure[id] = pressure;
-}
-
-void root(const Ball_t *ballIn, Ball_t *ballOut, const BallControl_t *ctl, uint32_t x) {
- float2 fv = {0, 0};
- float2 pos = ballIn->position;
-
- int arcID = -1;
- float arcInvStr = 100000;
-
- const Ball_t * bPtr = rsGetElementAt(ctl->ain, 0);
- for (uint32_t xin = 0; xin < ctl->dimX; xin++) {
- float2 vec = bPtr[xin].position - pos;
- float2 vec2 = vec * vec;
- float len2 = vec2.x + vec2.y;
-
- if (len2 < 10000) {
- //float minDist = ballIn->size + bPtr[xin].size;
- float forceScale = ballIn->size * bPtr[xin].size;
- forceScale *= forceScale;
-
- if (len2 > 16 /* (minDist*minDist)*/) {
- // Repulsion
- float len = sqrt(len2);
- fv -= (vec / (len * len * len)) * 20000.f * forceScale;
- } else {
- if (len2 < 1) {
- if (xin == x) {
- continue;
- }
- ballOut->delta = 0.f;
- ballOut->position = ballIn->position;
- if (xin > x) {
- ballOut->position.x += 1.f;
- } else {
- ballOut->position.x -= 1.f;
- }
- //ballOut->color.rgb = 1.f;
- //ballOut->arcID = -1;
- //ballOut->arcStr = 0;
- return;
- }
- // Collision
- float2 axis = normalize(vec);
- float e1 = dot(axis, ballIn->delta);
- float e2 = dot(axis, bPtr[xin].delta);
- float e = (e1 - e2) * 0.45f;
- if (e1 > 0) {
- fv -= axis * e;
- } else {
- fv += axis * e;
- }
- }
- }
- }
-
- fv /= ballIn->size * ballIn->size * ballIn->size;
- fv -= gGravityVector * 4.f;
- fv *= ctl->dt;
-
- for (int i=0; i < 10; i++) {
- if (touchPressure[i] > 0.1f) {
- float2 vec = touchPos[i] - ballIn->position;
- float2 vec2 = vec * vec;
- float len2 = max(2.f, vec2.x + vec2.y);
- fv -= (vec / len2) * touchPressure[i] * 300.f;
- }
- }
-
- ballOut->delta = (ballIn->delta * (1.f - 0.004f)) + fv;
- ballOut->position = ballIn->position + (ballOut->delta * ctl->dt);
-
- const float wallForce = 400.f;
- if (ballOut->position.x > (gMaxPos.x - 20.f)) {
- float d = gMaxPos.x - ballOut->position.x;
- if (d < 0.f) {
- if (ballOut->delta.x > 0) {
- ballOut->delta.x *= -0.7;
- }
- ballOut->position.x = gMaxPos.x;
- } else {
- ballOut->delta.x -= min(wallForce / (d * d), 10.f);
- }
- }
-
- if (ballOut->position.x < (gMinPos.x + 20.f)) {
- float d = ballOut->position.x - gMinPos.x;
- if (d < 0.f) {
- if (ballOut->delta.x < 0) {
- ballOut->delta.x *= -0.7;
- }
- ballOut->position.x = gMinPos.x + 1.f;
- } else {
- ballOut->delta.x += min(wallForce / (d * d), 10.f);
- }
- }
-
- if (ballOut->position.y > (gMaxPos.y - 20.f)) {
- float d = gMaxPos.y - ballOut->position.y;
- if (d < 0.f) {
- if (ballOut->delta.y > 0) {
- ballOut->delta.y *= -0.7;
- }
- ballOut->position.y = gMaxPos.y;
- } else {
- ballOut->delta.y -= min(wallForce / (d * d), 10.f);
- }
- }
-
- if (ballOut->position.y < (gMinPos.y + 20.f)) {
- float d = ballOut->position.y - gMinPos.y;
- if (d < 0.f) {
- if (ballOut->delta.y < 0) {
- ballOut->delta.y *= -0.7;
- }
- ballOut->position.y = gMinPos.y + 1.f;
- } else {
- ballOut->delta.y += min(wallForce / (d * d * d), 10.f);
- }
- }
-
- ballOut->size = ballIn->size;
-
- //rsDebug("physics pos out", ballOut->position);
-}
-
diff --git a/libs/rs/java/Balls/src/com/android/balls/balls.rs b/libs/rs/java/Balls/src/com/android/balls/balls.rs
deleted file mode 100644
index 7dc7660..0000000
--- a/libs/rs/java/Balls/src/com/android/balls/balls.rs
+++ /dev/null
@@ -1,85 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(com.android.balls)
-#include "rs_graphics.rsh"
-
-#include "balls.rsh"
-
-#pragma stateVertex(parent)
-#pragma stateStore(parent)
-
-rs_program_fragment gPFPoints;
-rs_program_fragment gPFLines;
-rs_mesh partMesh;
-
-typedef struct __attribute__((packed, aligned(4))) Point {
- float2 position;
- float size;
-} Point_t;
-Point_t *point;
-
-typedef struct VpConsts {
- rs_matrix4x4 MVP;
-} VpConsts_t;
-VpConsts_t *vpConstants;
-
-rs_script physics_script;
-
-Ball_t *balls1;
-Ball_t *balls2;
-
-static int frame = 0;
-
-void initParts(int w, int h)
-{
- uint32_t dimX = rsAllocationGetDimX(rsGetAllocation(balls1));
-
- for (uint32_t ct=0; ct < dimX; ct++) {
- balls1[ct].position.x = rsRand(0.f, (float)w);
- balls1[ct].position.y = rsRand(0.f, (float)h);
- balls1[ct].delta.x = 0.f;
- balls1[ct].delta.y = 0.f;
- balls1[ct].size = 1.f;
-
- float r = rsRand(100.f);
- if (r > 90.f) {
- balls1[ct].size += pow(10.f, rsRand(0.f, 2.f)) * 0.07;
- }
- }
-}
-
-
-
-int root() {
- rsgClearColor(0.f, 0.f, 0.f, 1.f);
-
- BallControl_t bc;
- Ball_t *bout;
-
- if (frame & 1) {
- rsSetObject(&bc.ain, rsGetAllocation(balls2));
- rsSetObject(&bc.aout, rsGetAllocation(balls1));
- bout = balls2;
- } else {
- rsSetObject(&bc.ain, rsGetAllocation(balls1));
- rsSetObject(&bc.aout, rsGetAllocation(balls2));
- bout = balls1;
- }
-
- bc.dimX = rsAllocationGetDimX(bc.ain);
- bc.dt = 1.f / 30.f;
-
- rsForEach(physics_script, bc.ain, bc.aout, &bc);
-
- for (uint32_t ct=0; ct < bc.dimX; ct++) {
- point[ct].position = bout[ct].position;
- point[ct].size = 6.f /*+ bout[ct].color.g * 6.f*/ * bout[ct].size;
- }
-
- frame++;
- rsgBindProgramFragment(gPFPoints);
- rsgDrawMesh(partMesh);
- rsClearObject(&bc.ain);
- rsClearObject(&bc.aout);
- return 1;
-}
-
diff --git a/libs/rs/java/Balls/src/com/android/balls/balls.rsh b/libs/rs/java/Balls/src/com/android/balls/balls.rsh
deleted file mode 100644
index fc886f9..0000000
--- a/libs/rs/java/Balls/src/com/android/balls/balls.rsh
+++ /dev/null
@@ -1,18 +0,0 @@
-
-typedef struct __attribute__((packed, aligned(4))) Ball {
- float2 delta;
- float2 position;
- //float3 color;
- float size;
- //int arcID;
- //float arcStr;
-} Ball_t;
-Ball_t *balls;
-
-
-typedef struct BallControl {
- uint32_t dimX;
- rs_allocation ain;
- rs_allocation aout;
- float dt;
-} BallControl_t;
diff --git a/libs/rs/java/Fountain/Android.mk b/libs/rs/java/Fountain/Android.mk
deleted file mode 100644
index 71944b2..0000000
--- a/libs/rs/java/Fountain/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright (C) 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.
-# 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.
-#
-
-ifneq ($(TARGET_SIMULATOR),true)
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
-#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
-
-LOCAL_PACKAGE_NAME := Fountain
-
-include $(BUILD_PACKAGE)
-
-endif
diff --git a/libs/rs/java/Fountain/AndroidManifest.xml b/libs/rs/java/Fountain/AndroidManifest.xml
deleted file mode 100644
index 5126e5c..0000000
--- a/libs/rs/java/Fountain/AndroidManifest.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.fountain">
- <uses-sdk android:minSdkVersion="11" />
- <application
- android:label="Fountain"
- android:icon="@drawable/test_pattern">
- <activity android:name="Fountain">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/libs/rs/java/Fountain/_index.html b/libs/rs/java/Fountain/_index.html
deleted file mode 100644
index 223242f..0000000
--- a/libs/rs/java/Fountain/_index.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<p>An example that renders many dots on the screen that follow a user's touch. The dots fall
-to the bottom of the screen when the user releases the finger.</p>
-
-
-
diff --git a/libs/rs/java/Fountain/res/drawable/test_pattern.png b/libs/rs/java/Fountain/res/drawable/test_pattern.png
deleted file mode 100644
index e7d1455..0000000
--- a/libs/rs/java/Fountain/res/drawable/test_pattern.png
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java b/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java
deleted file mode 100644
index 116c478..0000000
--- a/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 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.
- * 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.fountain;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-
-import android.app.Activity;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.Settings.System;
-import android.util.Config;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.widget.Button;
-import android.widget.ListView;
-
-import java.lang.Runtime;
-
-public class Fountain extends Activity {
- //EventListener mListener = new EventListener();
-
- private static final String LOG_TAG = "libRS_jni";
- private static final boolean DEBUG = false;
- private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
-
- private FountainView mView;
-
- // get the current looper (from your Activity UI thread for instance
-
-
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- // Create our Preview view and set it as the content of our
- // Activity
- mView = new FountainView(this);
- setContentView(mView);
- }
-
- @Override
- protected void onResume() {
- Log.e("rs", "onResume");
-
- // Ideally a game should implement onResume() and onPause()
- // to take appropriate action when the activity looses focus
- super.onResume();
- mView.resume();
- }
-
- @Override
- protected void onPause() {
- Log.e("rs", "onPause");
-
- // Ideally a game should implement onResume() and onPause()
- // to take appropriate action when the activity looses focus
- super.onPause();
- mView.pause();
-
-
-
- //Runtime.getRuntime().exit(0);
- }
-
-
- static void log(String message) {
- if (LOG_ENABLED) {
- Log.v(LOG_TAG, message);
- }
- }
-
-
-}
-
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
deleted file mode 100644
index be2f9ca..0000000
--- a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 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.
- * 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.fountain;
-
-import android.content.res.Resources;
-import android.renderscript.*;
-import android.util.Log;
-
-
-public class FountainRS {
- public static final int PART_COUNT = 50000;
-
- public FountainRS() {
- }
-
- private Resources mRes;
- private RenderScriptGL mRS;
- private ScriptC_fountain mScript;
- public void init(RenderScriptGL rs, Resources res, int width, int height) {
- mRS = rs;
- mRes = res;
-
- ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
- pfb.setVaryingColor(true);
- rs.bindProgramFragment(pfb.create());
-
- ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);//
- // Allocation.USAGE_GRAPHICS_VERTEX);
-
- Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
- smb.addVertexAllocation(points.getAllocation());
- smb.addIndexSetType(Mesh.Primitive.POINT);
- Mesh sm = smb.create();
-
- mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);
- mScript.set_partMesh(sm);
- mScript.bind_point(points);
- mRS.bindRootScript(mScript);
- }
-
- boolean holdingColor[] = new boolean[10];
- public void newTouchPosition(float x, float y, float pressure, int id) {
- if (id >= holdingColor.length) {
- return;
- }
- int rate = (int)(pressure * pressure * 500.f);
- if (rate > 500) {
- rate = 500;
- }
- if (rate > 0) {
- mScript.invoke_addParticles(rate, x, y, id, !holdingColor[id]);
- holdingColor[id] = true;
- } else {
- holdingColor[id] = false;
- }
-
- }
-}
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
deleted file mode 100644
index 69b181d..0000000
--- a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 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.
- * 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.fountain;
-
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
-import android.renderscript.RenderScriptGL;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-public class FountainView extends RSSurfaceView {
-
- public FountainView(Context context) {
- super(context);
- //setFocusable(true);
- }
-
- private RenderScriptGL mRS;
- private FountainRS mRender;
-
- public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
- super.surfaceChanged(holder, format, w, h);
- if (mRS == null) {
- RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
- mRS = createRenderScriptGL(sc);
- mRS.setSurface(holder, w, h);
- mRender = new FountainRS();
- mRender.init(mRS, getResources(), w, h);
- }
- }
-
- @Override
- protected void onDetachedFromWindow() {
- if (mRS != null) {
- mRS = null;
- destroyRenderScriptGL();
- }
- }
-
-
- @Override
- public boolean onTouchEvent(MotionEvent ev)
- {
- int act = ev.getActionMasked();
- if (act == ev.ACTION_UP) {
- mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0));
- return false;
- } else if (act == MotionEvent.ACTION_POINTER_UP) {
- // only one pointer going up, we can get the index like this
- int pointerIndex = ev.getActionIndex();
- int pointerId = ev.getPointerId(pointerIndex);
- mRender.newTouchPosition(0, 0, 0, pointerId);
- }
- int count = ev.getHistorySize();
- int pcount = ev.getPointerCount();
-
- for (int p=0; p < pcount; p++) {
- int id = ev.getPointerId(p);
- mRender.newTouchPosition(ev.getX(p),
- ev.getY(p),
- ev.getPressure(p),
- id);
-
- for (int i=0; i < count; i++) {
- mRender.newTouchPosition(ev.getHistoricalX(p, i),
- ev.getHistoricalY(p, i),
- ev.getHistoricalPressure(p, i),
- id);
- }
- }
- return true;
- }
-}
-
-
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/fountain.rs b/libs/rs/java/Fountain/src/com/android/fountain/fountain.rs
deleted file mode 100644
index b8f57a3..0000000
--- a/libs/rs/java/Fountain/src/com/android/fountain/fountain.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-// Fountain test script
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.fountain)
-
-#pragma stateFragment(parent)
-
-#include "rs_graphics.rsh"
-
-static int newPart = 0;
-rs_mesh partMesh;
-
-typedef struct __attribute__((packed, aligned(4))) Point {
- float2 delta;
- float2 position;
- uchar4 color;
-} Point_t;
-Point_t *point;
-
-int root() {
- float dt = min(rsGetDt(), 0.1f);
- rsgClearColor(0.f, 0.f, 0.f, 1.f);
- const float height = rsgGetHeight();
- const int size = rsAllocationGetDimX(rsGetAllocation(point));
- float dy2 = dt * (10.f);
- Point_t * p = point;
- for (int ct=0; ct < size; ct++) {
- p->delta.y += dy2;
- p->position += p->delta;
- if ((p->position.y > height) && (p->delta.y > 0)) {
- p->delta.y *= -0.3f;
- }
- p++;
- }
-
- rsgDrawMesh(partMesh);
- return 1;
-}
-
-static float4 partColor[10];
-void addParticles(int rate, float x, float y, int index, bool newColor)
-{
- if (newColor) {
- partColor[index].x = rsRand(0.5f, 1.0f);
- partColor[index].y = rsRand(1.0f);
- partColor[index].z = rsRand(1.0f);
- }
- float rMax = ((float)rate) * 0.02f;
- int size = rsAllocationGetDimX(rsGetAllocation(point));
- uchar4 c = rsPackColorTo8888(partColor[index]);
-
- Point_t * np = &point[newPart];
- float2 p = {x, y};
- while (rate--) {
- float angle = rsRand(3.14f * 2.f);
- float len = rsRand(rMax);
- np->delta.x = len * sin(angle);
- np->delta.y = len * cos(angle);
- np->position = p;
- np->color = c;
- newPart++;
- np++;
- if (newPart >= size) {
- newPart = 0;
- np = &point[newPart];
- }
- }
-}
-
diff --git a/libs/rs/java/HelloCompute/Android.mk b/libs/rs/java/HelloCompute/Android.mk
deleted file mode 100644
index 3881bb0..0000000
--- a/libs/rs/java/HelloCompute/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright (C) 2011 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.
-#
-
-ifneq ($(TARGET_SIMULATOR),true)
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
- $(call all-renderscript-files-under, src)
-
-LOCAL_PACKAGE_NAME := HelloCompute
-
-include $(BUILD_PACKAGE)
-
-endif
diff --git a/libs/rs/java/HelloCompute/AndroidManifest.xml b/libs/rs/java/HelloCompute/AndroidManifest.xml
deleted file mode 100644
index 8c7ac2f..0000000
--- a/libs/rs/java/HelloCompute/AndroidManifest.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.example.hellocompute">
-
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-sdk android:minSdkVersion="11" />
- <application android:label="HelloCompute">
- <activity android:name="HelloCompute">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/libs/rs/java/HelloCompute/_index.html b/libs/rs/java/HelloCompute/_index.html
deleted file mode 100644
index abfd978..0000000
--- a/libs/rs/java/HelloCompute/_index.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<p>A Renderscript compute sample that filters a bitmap. No Renderscript graphics APIs are used
-in this sample.</p>
\ No newline at end of file
diff --git a/libs/rs/java/HelloCompute/res/drawable/data.jpg b/libs/rs/java/HelloCompute/res/drawable/data.jpg
deleted file mode 100644
index 81a87b1..0000000
--- a/libs/rs/java/HelloCompute/res/drawable/data.jpg
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/HelloCompute/res/layout/main.xml b/libs/rs/java/HelloCompute/res/layout/main.xml
deleted file mode 100644
index 3f7de43..0000000
--- a/libs/rs/java/HelloCompute/res/layout/main.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <ImageView
- android:id="@+id/displayin"
- android:layout_width="320dip"
- android:layout_height="266dip" />
-
- <ImageView
- android:id="@+id/displayout"
- android:layout_width="320dip"
- android:layout_height="266dip" />
-
-</LinearLayout>
diff --git a/libs/rs/java/HelloCompute/src/com/android/example/hellocompute/HelloCompute.java b/libs/rs/java/HelloCompute/src/com/android/example/hellocompute/HelloCompute.java
deleted file mode 100644
index 123c37b..0000000
--- a/libs/rs/java/HelloCompute/src/com/android/example/hellocompute/HelloCompute.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2011 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.example.hellocompute;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.graphics.BitmapFactory;
-import android.graphics.Bitmap;
-import android.renderscript.RenderScript;
-import android.renderscript.Allocation;
-import android.widget.ImageView;
-
-public class HelloCompute extends Activity {
- private Bitmap mBitmapIn;
- private Bitmap mBitmapOut;
-
- private RenderScript mRS;
- private Allocation mInAllocation;
- private Allocation mOutAllocation;
- private ScriptC_mono mScript;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- mBitmapIn = loadBitmap(R.drawable.data);
- mBitmapOut = Bitmap.createBitmap(mBitmapIn.getWidth(), mBitmapIn.getHeight(),
- mBitmapIn.getConfig());
-
- ImageView in = (ImageView) findViewById(R.id.displayin);
- in.setImageBitmap(mBitmapIn);
-
- ImageView out = (ImageView) findViewById(R.id.displayout);
- out.setImageBitmap(mBitmapOut);
-
- createScript();
- }
-
-
- private void createScript() {
- mRS = RenderScript.create(this);
-
- mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
- Allocation.MipmapControl.MIPMAP_NONE,
- Allocation.USAGE_SCRIPT);
- mOutAllocation = Allocation.createTyped(mRS, mInAllocation.getType());
-
- mScript = new ScriptC_mono(mRS, getResources(), R.raw.mono);
-
- mScript.set_gIn(mInAllocation);
- mScript.set_gOut(mOutAllocation);
- mScript.set_gScript(mScript);
- mScript.invoke_filter();
- mOutAllocation.copyTo(mBitmapOut);
- }
-
- private Bitmap loadBitmap(int resource) {
- final BitmapFactory.Options options = new BitmapFactory.Options();
- options.inPreferredConfig = Bitmap.Config.ARGB_8888;
- return BitmapFactory.decodeResource(getResources(), resource, options);
- }
-}
diff --git a/libs/rs/java/HelloCompute/src/com/android/example/hellocompute/mono.rs b/libs/rs/java/HelloCompute/src/com/android/example/hellocompute/mono.rs
deleted file mode 100644
index 9647c61..0000000
--- a/libs/rs/java/HelloCompute/src/com/android/example/hellocompute/mono.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(com.android.example.hellocompute)
-
-rs_allocation gIn;
-rs_allocation gOut;
-rs_script gScript;
-
-const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
-
-void root(const uchar4 *v_in, uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y) {
- float4 f4 = rsUnpackColor8888(*v_in);
-
- float3 mono = dot(f4.rgb, gMonoMult);
- *v_out = rsPackColorTo8888(mono);
-}
-
-void filter() {
- rsForEach(gScript, gIn, gOut, 0);
-}
-
diff --git a/libs/rs/java/HelloWorld/Android.mk b/libs/rs/java/HelloWorld/Android.mk
deleted file mode 100644
index 72f0f03..0000000
--- a/libs/rs/java/HelloWorld/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (C) 2011 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.
-#
-
-ifneq ($(TARGET_SIMULATOR),true)
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
-
-LOCAL_PACKAGE_NAME := HelloWorld
-
-include $(BUILD_PACKAGE)
-
-endif
diff --git a/libs/rs/java/HelloWorld/AndroidManifest.xml b/libs/rs/java/HelloWorld/AndroidManifest.xml
deleted file mode 100644
index e7c9a95..0000000
--- a/libs/rs/java/HelloWorld/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.rs.helloworld">
- <uses-sdk android:minSdkVersion="11" />
- <application android:label="HelloWorld"
- android:icon="@drawable/test_pattern">
- <activity android:name="HelloWorld"
- android:label="HelloWorld"
- android:theme="@android:style/Theme.Black.NoTitleBar">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/libs/rs/java/HelloWorld/_index.html b/libs/rs/java/HelloWorld/_index.html
deleted file mode 100644
index 4cab738..0000000
--- a/libs/rs/java/HelloWorld/_index.html
+++ /dev/null
@@ -1 +0,0 @@
-<p>A Renderscript graphics application that draws the text "Hello, World!" where the user touches.</p>
\ No newline at end of file
diff --git a/libs/rs/java/HelloWorld/res/drawable/test_pattern.png b/libs/rs/java/HelloWorld/res/drawable/test_pattern.png
deleted file mode 100644
index e7d1455..0000000
--- a/libs/rs/java/HelloWorld/res/drawable/test_pattern.png
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorld.java b/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorld.java
deleted file mode 100644
index f63015e7..0000000
--- a/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorld.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2011 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.rs.helloworld;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-// Renderscript activity
-public class HelloWorld extends Activity {
-
- // Custom view to use with RenderScript
- private HelloWorldView mView;
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- // Create our view and set it as the content of our Activity
- mView = new HelloWorldView(this);
- setContentView(mView);
- }
-
- @Override
- protected void onResume() {
- // Ideally an app should implement onResume() and onPause()
- // to take appropriate action when the activity loses focus
- super.onResume();
- mView.resume();
- }
-
- @Override
- protected void onPause() {
- // Ideally an app should implement onResume() and onPause()
- // to take appropriate action when the activity loses focus
- super.onPause();
- mView.pause();
- }
-
-}
-
diff --git a/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorldRS.java b/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorldRS.java
deleted file mode 100644
index c9c1316..0000000
--- a/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorldRS.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2011 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.rs.helloworld;
-
-import android.content.res.Resources;
-import android.renderscript.*;
-
-// This is the renderer for the HelloWorldView
-public class HelloWorldRS {
- private Resources mRes;
- private RenderScriptGL mRS;
-
- private ScriptC_helloworld mScript;
-
- public HelloWorldRS() {
- }
-
- // This provides us with the renderscript context and resources that
- // allow us to create the script that does rendering
- public void init(RenderScriptGL rs, Resources res) {
- mRS = rs;
- mRes = res;
- initRS();
- }
-
- public void onActionDown(int x, int y) {
- mScript.set_gTouchX(x);
- mScript.set_gTouchY(y);
- }
-
- private void initRS() {
- mScript = new ScriptC_helloworld(mRS, mRes, R.raw.helloworld);
- mRS.bindRootScript(mScript);
- }
-}
-
-
-
diff --git a/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorldView.java b/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorldView.java
deleted file mode 100644
index 8cddb2a..0000000
--- a/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorldView.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2011 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.rs.helloworld;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScriptGL;
-
-import android.content.Context;
-import android.view.MotionEvent;
-
-public class HelloWorldView extends RSSurfaceView {
- // Renderscipt context
- private RenderScriptGL mRS;
- // Script that does the rendering
- private HelloWorldRS mRender;
-
- public HelloWorldView(Context context) {
- super(context);
- ensureRenderScript();
- }
-
- private void ensureRenderScript() {
- if (mRS == null) {
- // Initialize renderscript with desired surface characteristics.
- // In this case, just use the defaults
- RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
- mRS = createRenderScriptGL(sc);
- // Create an instance of the script that does the rendering
- mRender = new HelloWorldRS();
- mRender.init(mRS, getResources());
- }
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- ensureRenderScript();
- }
-
- @Override
- protected void onDetachedFromWindow() {
- // Handle the system event and clean up
- mRender = null;
- if (mRS != null) {
- mRS = null;
- destroyRenderScriptGL();
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- // Pass touch events from the system to the rendering script
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- mRender.onActionDown((int)ev.getX(), (int)ev.getY());
- return true;
- }
-
- return false;
- }
-}
-
-
diff --git a/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/helloworld.rs b/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/helloworld.rs
deleted file mode 100644
index fa171f5..0000000
--- a/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/helloworld.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (C) 2011 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.
-
-#pragma version(1)
-
-// Tell which java package name the reflected files should belong to
-#pragma rs java_package_name(com.android.rs.helloworld)
-
-// Built-in header with graphics API's
-#include "rs_graphics.rsh"
-
-// gTouchX and gTouchY are variables that will be reflected for use
-// by the java API. We can use them to notify the script of touch events.
-int gTouchX;
-int gTouchY;
-
-// This is invoked automatically when the script is created
-void init() {
- gTouchX = 50.0f;
- gTouchY = 50.0f;
-}
-
-int root(int launchID) {
-
- // Clear the background color
- rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- // Tell the runtime what the font color should be
- rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
- // Introuduce ourselves to the world by drawing a greeting
- // at the position user touched on the screen
- rsgDrawText("Hello World!", gTouchX, gTouchY);
-
- // Return value tells RS roughly how often to redraw
- // in this case 20 ms
- return 20;
-}
diff --git a/libs/rs/java/Samples/Android.mk b/libs/rs/java/Samples/Android.mk
deleted file mode 100644
index 65ae734..0000000
--- a/libs/rs/java/Samples/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright (C) 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.
-# 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.
-#
-
-ifneq ($(TARGET_SIMULATOR),true)
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
-#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
-
-LOCAL_PACKAGE_NAME := Samples
-
-include $(BUILD_PACKAGE)
-
-endif
diff --git a/libs/rs/java/Samples/AndroidManifest.xml b/libs/rs/java/Samples/AndroidManifest.xml
deleted file mode 100644
index c08a264..0000000
--- a/libs/rs/java/Samples/AndroidManifest.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.samples">
- <uses-sdk android:minSdkVersion="11" />
- <application android:label="Samples"
- android:icon="@drawable/test_pattern">
- <activity android:name="RsList"
- android:label="RsList"
- android:theme="@android:style/Theme.Black.NoTitleBar">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
-
- <activity android:name="RsRenderStates"
- android:label="RsStates"
- android:theme="@android:style/Theme.Black.NoTitleBar">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/libs/rs/java/Samples/_index.html b/libs/rs/java/Samples/_index.html
deleted file mode 100644
index 5872431..0000000
--- a/libs/rs/java/Samples/_index.html
+++ /dev/null
@@ -1 +0,0 @@
-<p>A set of samples that demonstrate how to use various features of the Renderscript APIs.</p>
\ No newline at end of file
diff --git a/libs/rs/java/Samples/res/drawable/checker.png b/libs/rs/java/Samples/res/drawable/checker.png
deleted file mode 100644
index b631e1e..0000000
--- a/libs/rs/java/Samples/res/drawable/checker.png
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/Samples/res/drawable/cubemap_test.png b/libs/rs/java/Samples/res/drawable/cubemap_test.png
deleted file mode 100644
index baf35d0..0000000
--- a/libs/rs/java/Samples/res/drawable/cubemap_test.png
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/Samples/res/drawable/data.png b/libs/rs/java/Samples/res/drawable/data.png
deleted file mode 100644
index 8e34714..0000000
--- a/libs/rs/java/Samples/res/drawable/data.png
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/Samples/res/drawable/leaf.png b/libs/rs/java/Samples/res/drawable/leaf.png
deleted file mode 100644
index 3cd3775..0000000
--- a/libs/rs/java/Samples/res/drawable/leaf.png
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/Samples/res/drawable/test_pattern.png b/libs/rs/java/Samples/res/drawable/test_pattern.png
deleted file mode 100644
index e7d1455..0000000
--- a/libs/rs/java/Samples/res/drawable/test_pattern.png
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/Samples/res/drawable/torusmap.png b/libs/rs/java/Samples/res/drawable/torusmap.png
deleted file mode 100644
index 1e08f3b..0000000
--- a/libs/rs/java/Samples/res/drawable/torusmap.png
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/Samples/res/raw/multitexf.glsl b/libs/rs/java/Samples/res/raw/multitexf.glsl
deleted file mode 100644
index e492a47..0000000
--- a/libs/rs/java/Samples/res/raw/multitexf.glsl
+++ /dev/null
@@ -1,13 +0,0 @@
-varying vec2 varTex0;
-
-void main() {
- vec2 t0 = varTex0.xy;
- lowp vec4 col0 = texture2D(UNI_Tex0, t0).rgba;
- lowp vec4 col1 = texture2D(UNI_Tex1, t0*4.0).rgba;
- lowp vec4 col2 = texture2D(UNI_Tex2, t0).rgba;
- col0.xyz = col0.xyz*col1.xyz*1.5;
- col0.xyz = mix(col0.xyz, col2.xyz, col2.w);
- col0.w = 0.5;
- gl_FragColor = col0;
-}
-
diff --git a/libs/rs/java/Samples/res/raw/shader2f.glsl b/libs/rs/java/Samples/res/raw/shader2f.glsl
deleted file mode 100644
index 5fc05f1..0000000
--- a/libs/rs/java/Samples/res/raw/shader2f.glsl
+++ /dev/null
@@ -1,29 +0,0 @@
-varying vec3 varWorldPos;
-varying vec3 varWorldNormal;
-varying vec2 varTex0;
-
-void main() {
-
- vec3 V = normalize(-varWorldPos.xyz);
- vec3 worldNorm = normalize(varWorldNormal);
-
- vec3 light0Vec = normalize(UNI_light0_Posision.xyz - varWorldPos);
- vec3 light0R = -reflect(light0Vec, worldNorm);
- float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0) * UNI_light0_Diffuse;
- float light0Spec = clamp(dot(light0R, V), 0.001, 1.0);
- float light0_Specular = pow(light0Spec, UNI_light0_CosinePower) * UNI_light0_Specular;
-
- vec3 light1Vec = normalize(UNI_light1_Posision.xyz - varWorldPos);
- vec3 light1R = reflect(light1Vec, worldNorm);
- float light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0) * UNI_light1_Diffuse;
- float light1Spec = clamp(dot(light1R, V), 0.001, 1.0);
- float light1_Specular = pow(light1Spec, UNI_light1_CosinePower) * UNI_light1_Specular;
-
- vec2 t0 = varTex0.xy;
- lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
- col.xyz = col.xyz * (light0_Diffuse * UNI_light0_DiffuseColor.xyz + light1_Diffuse * UNI_light1_DiffuseColor.xyz);
- col.xyz += light0_Specular * UNI_light0_SpecularColor.xyz;
- col.xyz += light1_Specular * UNI_light1_SpecularColor.xyz;
- gl_FragColor = col;
-}
-
diff --git a/libs/rs/java/Samples/res/raw/shader2movev.glsl b/libs/rs/java/Samples/res/raw/shader2movev.glsl
deleted file mode 100644
index a2c807e..0000000
--- a/libs/rs/java/Samples/res/raw/shader2movev.glsl
+++ /dev/null
@@ -1,21 +0,0 @@
-varying vec3 varWorldPos;
-varying vec3 varWorldNormal;
-varying vec2 varTex0;
-
-// This is where actual shader code begins
-void main() {
- vec4 objPos = ATTRIB_position;
- vec3 oldPos = objPos.xyz;
- objPos.xyz += 0.1*sin(objPos.xyz*2.0 + UNI_time);
- objPos.xyz += 0.05*sin(objPos.xyz*4.0 + UNI_time*0.5);
- objPos.xyz += 0.02*sin(objPos.xyz*7.0 + UNI_time*0.75);
- vec4 worldPos = UNI_model * objPos;
- gl_Position = UNI_proj * worldPos;
-
- mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
- vec3 worldNorm = model3 * (ATTRIB_normal + oldPos - objPos.xyz);
-
- varWorldPos = worldPos.xyz;
- varWorldNormal = worldNorm;
- varTex0 = ATTRIB_texture0;
-}
diff --git a/libs/rs/java/Samples/res/raw/shader2v.glsl b/libs/rs/java/Samples/res/raw/shader2v.glsl
deleted file mode 100644
index e6885a3..0000000
--- a/libs/rs/java/Samples/res/raw/shader2v.glsl
+++ /dev/null
@@ -1,17 +0,0 @@
-varying vec3 varWorldPos;
-varying vec3 varWorldNormal;
-varying vec2 varTex0;
-
-// This is where actual shader code begins
-void main() {
- vec4 objPos = ATTRIB_position;
- vec4 worldPos = UNI_model * objPos;
- gl_Position = UNI_proj * worldPos;
-
- mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
- vec3 worldNorm = model3 * ATTRIB_normal;
-
- varWorldPos = worldPos.xyz;
- varWorldNormal = worldNorm;
- varTex0 = ATTRIB_texture0;
-}
diff --git a/libs/rs/java/Samples/res/raw/shaderarrayf.glsl b/libs/rs/java/Samples/res/raw/shaderarrayf.glsl
deleted file mode 100644
index 238ecad..0000000
--- a/libs/rs/java/Samples/res/raw/shaderarrayf.glsl
+++ /dev/null
@@ -1,16 +0,0 @@
-
-varying lowp float light0_Diffuse;
-varying lowp float light0_Specular;
-varying lowp float light1_Diffuse;
-varying lowp float light1_Specular;
-varying vec2 varTex0;
-
-void main() {
- vec2 t0 = varTex0.xy;
- lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
- col.xyz = col.xyz * (light0_Diffuse * UNI_light_DiffuseColor[0].xyz + light1_Diffuse * UNI_light_DiffuseColor[1].xyz);
- col.xyz += light0_Specular * UNI_light_SpecularColor[0].xyz;
- col.xyz += light1_Specular * UNI_light_SpecularColor[1].xyz;
- gl_FragColor = col;
-}
-
diff --git a/libs/rs/java/Samples/res/raw/shaderarrayv.glsl b/libs/rs/java/Samples/res/raw/shaderarrayv.glsl
deleted file mode 100644
index 7a1310a..0000000
--- a/libs/rs/java/Samples/res/raw/shaderarrayv.glsl
+++ /dev/null
@@ -1,32 +0,0 @@
-varying float light0_Diffuse;
-varying float light0_Specular;
-varying float light1_Diffuse;
-varying float light1_Specular;
-varying vec2 varTex0;
-
-// This is where actual shader code begins
-void main() {
- vec4 worldPos = UNI_model[0] * ATTRIB_position;
- worldPos = UNI_model[1] * worldPos;
- gl_Position = UNI_proj * worldPos;
-
- mat4 model0 = UNI_model[0];
- mat3 model3 = mat3(model0[0].xyz, model0[1].xyz, model0[2].xyz);
- vec3 worldNorm = model3 * ATTRIB_normal;
- vec3 V = normalize(-worldPos.xyz);
-
- vec3 light0Vec = normalize(UNI_light_Posision[0].xyz - worldPos.xyz);
- vec3 light0R = -reflect(light0Vec, worldNorm);
- light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0) * UNI_light_Diffuse[0];
- float light0Spec = clamp(dot(light0R, V), 0.001, 1.0);
- light0_Specular = pow(light0Spec, UNI_light_CosinePower[0]) * UNI_light_Specular[0];
-
- vec3 light1Vec = normalize(UNI_light_Posision[1].xyz - worldPos.xyz);
- vec3 light1R = reflect(light1Vec, worldNorm);
- light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0) * UNI_light_Diffuse[1];
- float light1Spec = clamp(dot(light1R, V), 0.001, 1.0);
- light1_Specular = pow(light1Spec, UNI_light_CosinePower[1]) * UNI_light_Specular[1];
-
- gl_PointSize = 1.0;
- varTex0 = ATTRIB_texture0;
-}
diff --git a/libs/rs/java/Samples/res/raw/shadercubef.glsl b/libs/rs/java/Samples/res/raw/shadercubef.glsl
deleted file mode 100644
index 15696a4..0000000
--- a/libs/rs/java/Samples/res/raw/shadercubef.glsl
+++ /dev/null
@@ -1,8 +0,0 @@
-
-varying vec3 worldNormal;
-
-void main() {
- lowp vec4 col = textureCube(UNI_Tex0, worldNormal);
- gl_FragColor = col;
-}
-
diff --git a/libs/rs/java/Samples/res/raw/shadercubev.glsl b/libs/rs/java/Samples/res/raw/shadercubev.glsl
deleted file mode 100644
index 70f5cd6..0000000
--- a/libs/rs/java/Samples/res/raw/shadercubev.glsl
+++ /dev/null
@@ -1,10 +0,0 @@
-varying vec3 worldNormal;
-
-// This is where actual shader code begins
-void main() {
- vec4 worldPos = UNI_model * ATTRIB_position;
- gl_Position = UNI_proj * worldPos;
-
- mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
- worldNormal = model3 * ATTRIB_normal;
-}
diff --git a/libs/rs/java/Samples/res/raw/shaderf.glsl b/libs/rs/java/Samples/res/raw/shaderf.glsl
deleted file mode 100644
index d56e203..0000000
--- a/libs/rs/java/Samples/res/raw/shaderf.glsl
+++ /dev/null
@@ -1,16 +0,0 @@
-
-varying lowp float light0_Diffuse;
-varying lowp float light0_Specular;
-varying lowp float light1_Diffuse;
-varying lowp float light1_Specular;
-varying vec2 varTex0;
-
-void main() {
- vec2 t0 = varTex0.xy;
- lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
- col.xyz = col.xyz * (light0_Diffuse * UNI_light0_DiffuseColor.xyz + light1_Diffuse * UNI_light1_DiffuseColor.xyz);
- col.xyz += light0_Specular * UNI_light0_SpecularColor.xyz;
- col.xyz += light1_Specular * UNI_light1_SpecularColor.xyz;
- gl_FragColor = col;
-}
-
diff --git a/libs/rs/java/Samples/res/raw/shaderv.glsl b/libs/rs/java/Samples/res/raw/shaderv.glsl
deleted file mode 100644
index f7d01de..0000000
--- a/libs/rs/java/Samples/res/raw/shaderv.glsl
+++ /dev/null
@@ -1,30 +0,0 @@
-varying float light0_Diffuse;
-varying float light0_Specular;
-varying float light1_Diffuse;
-varying float light1_Specular;
-varying vec2 varTex0;
-
-// This is where actual shader code begins
-void main() {
- vec4 worldPos = UNI_model * ATTRIB_position;
- gl_Position = UNI_proj * worldPos;
-
- mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
- vec3 worldNorm = model3 * ATTRIB_normal;
- vec3 V = normalize(-worldPos.xyz);
-
- vec3 light0Vec = normalize(UNI_light0_Posision.xyz - worldPos.xyz);
- vec3 light0R = -reflect(light0Vec, worldNorm);
- light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0) * UNI_light0_Diffuse;
- float light0Spec = clamp(dot(light0R, V), 0.001, 1.0);
- light0_Specular = pow(light0Spec, UNI_light0_CosinePower) * UNI_light0_Specular;
-
- vec3 light1Vec = normalize(UNI_light1_Posision.xyz - worldPos.xyz);
- vec3 light1R = reflect(light1Vec, worldNorm);
- light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0) * UNI_light1_Diffuse;
- float light1Spec = clamp(dot(light1R, V), 0.001, 1.0);
- light1_Specular = pow(light1Spec, UNI_light1_CosinePower) * UNI_light1_Specular;
-
- gl_PointSize = 1.0;
- varTex0 = ATTRIB_texture0;
-}
diff --git a/libs/rs/java/Samples/res/raw/torus.a3d b/libs/rs/java/Samples/res/raw/torus.a3d
deleted file mode 100644
index 0322b01..0000000
--- a/libs/rs/java/Samples/res/raw/torus.a3d
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsList.java b/libs/rs/java/Samples/src/com/android/samples/RsList.java
deleted file mode 100644
index 2d7add0..0000000
--- a/libs/rs/java/Samples/src/com/android/samples/RsList.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 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.
- * 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.samples;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-public class RsList extends Activity {
-
- private RsListView mView;
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- // Create our Preview view and set it as the content of our
- // Activity
- mView = new RsListView(this);
- setContentView(mView);
- }
-
- @Override
- protected void onResume() {
- // Ideally a game should implement onResume() and onPause()
- // to take appropriate action when the activity loses focus
- super.onResume();
- mView.resume();
- }
-
- @Override
- protected void onPause() {
- // Ideally a game should implement onResume() and onPause()
- // to take appropriate action when the activity loses focus
- super.onPause();
- mView.pause();
- }
-
-}
-
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsListRS.java b/libs/rs/java/Samples/src/com/android/samples/RsListRS.java
deleted file mode 100644
index 6ee545ac..0000000
--- a/libs/rs/java/Samples/src/com/android/samples/RsListRS.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 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.
- * 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.samples;
-
-import java.io.Writer;
-import java.util.Vector;
-
-import android.content.res.Resources;
-import android.renderscript.*;
-import android.renderscript.ProgramStore.DepthFunc;
-import android.util.Log;
-
-
-public class RsListRS {
-
- private final int STATE_LAST_FOCUS = 1;
-
- private static final String[] DATA_LIST = {
- "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
- "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
- "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
- "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
- "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
- "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil",
- "British Indian Ocean Territory", "British Virgin Islands", "Brunei", "Bulgaria",
- "Burkina Faso", "Burundi", "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
- "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
- "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
- "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic",
- "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
- "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea",
- "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland",
- "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia",
- "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar",
- "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau",
- "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary",
- "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
- "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",
- "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
- "Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
- "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
- "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia",
- "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand",
- "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas",
- "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru",
- "Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar",
- "Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena",
- "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon",
- "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal",
- "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
- "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea",
- "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden",
- "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas",
- "The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",
- "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda",
- "Ukraine", "United Arab Emirates", "United Kingdom",
- "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan",
- "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara",
- "Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
- };
-
- public RsListRS() {
- }
-
- public void init(RenderScriptGL rs, Resources res) {
- mRS = rs;
- mRes = res;
- initRS();
- }
-
- private Resources mRes;
- private RenderScriptGL mRS;
- private Font mItalic;
-
- ScriptField_ListAllocs_s mListAllocs;
-
- private ScriptC_rslist mScript;
-
- int mLastX;
- int mLastY;
-
- public void onActionDown(int x, int y) {
- mScript.set_gDY(0.0f);
-
- mLastX = x;
- mLastY = y;
- }
-
- public void onActionMove(int x, int y) {
- int dx = mLastX - x;
- int dy = mLastY - y;
-
- if (Math.abs(dy) <= 2) {
- dy = 0;
- }
-
- mScript.set_gDY(dy);
-
- mLastX = x;
- mLastY = y;
- }
-
- private void initRS() {
-
- mScript = new ScriptC_rslist(mRS, mRes, R.raw.rslist);
-
- mListAllocs = new ScriptField_ListAllocs_s(mRS, DATA_LIST.length);
- for (int i = 0; i < DATA_LIST.length; i ++) {
- ScriptField_ListAllocs_s.Item listElem = new ScriptField_ListAllocs_s.Item();
- listElem.text = Allocation.createFromString(mRS, DATA_LIST[i], Allocation.USAGE_SCRIPT);
- mListAllocs.set(listElem, i, false);
- }
-
- mListAllocs.copyAll();
-
- mScript.bind_gList(mListAllocs);
-
- mItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
- mScript.set_gItalic(mItalic);
-
- mRS.bindRootScript(mScript);
- }
-}
-
-
-
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsListView.java b/libs/rs/java/Samples/src/com/android/samples/RsListView.java
deleted file mode 100644
index b67bd48..0000000
--- a/libs/rs/java/Samples/src/com/android/samples/RsListView.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 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.
- * 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.samples;
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScriptGL;
-
-import android.content.Context;
-import android.view.MotionEvent;
-
-public class RsListView extends RSSurfaceView {
-
- public RsListView(Context context) {
- super(context);
- ensureRenderScript();
- }
-
- private RenderScriptGL mRS;
- private RsListRS mRender;
-
- private void ensureRenderScript() {
- if (mRS == null) {
- RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
- mRS = createRenderScriptGL(sc);
- mRender = new RsListRS();
- mRender.init(mRS, getResources());
- }
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- ensureRenderScript();
- }
-
- @Override
- protected void onDetachedFromWindow() {
- mRender = null;
- if (mRS != null) {
- mRS = null;
- destroyRenderScriptGL();
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev)
- {
- boolean ret = false;
- int act = ev.getAction();
- if (act == MotionEvent.ACTION_DOWN) {
- mRender.onActionDown((int)ev.getX(), (int)ev.getY());
- ret = true;
- } else if (act == MotionEvent.ACTION_MOVE) {
- mRender.onActionMove((int)ev.getX(), (int)ev.getY());
- ret = true;
- }
-
- return ret;
- }
-}
-
-
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStates.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStates.java
deleted file mode 100644
index ff8c2de..0000000
--- a/libs/rs/java/Samples/src/com/android/samples/RsRenderStates.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 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.
- * 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.samples;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-public class RsRenderStates extends Activity {
-
- private RsRenderStatesView mView;
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- // Create our Preview view and set it as the content of our
- // Activity
- mView = new RsRenderStatesView(this);
- setContentView(mView);
- }
-
- @Override
- protected void onResume() {
- // Ideally a game should implement onResume() and onPause()
- // to take appropriate action when the activity looses focus
- super.onResume();
- mView.resume();
- }
-
- @Override
- protected void onPause() {
- // Ideally a game should implement onResume() and onPause()
- // to take appropriate action when the activity looses focus
- super.onPause();
- mView.pause();
- }
-
-}
-
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
deleted file mode 100644
index 49b65d6..0000000
--- a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Copyright (C) 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.
- * 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.samples;
-
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.renderscript.*;
-import android.renderscript.Font.Style;
-import android.renderscript.Program.TextureType;
-import android.renderscript.ProgramStore.DepthFunc;
-import android.renderscript.ProgramStore.BlendSrcFunc;
-import android.renderscript.ProgramStore.BlendDstFunc;
-import android.renderscript.Sampler.Value;
-import android.util.Log;
-
-
-public class RsRenderStatesRS {
-
- int mWidth;
- int mHeight;
-
- public RsRenderStatesRS() {
- }
-
- public void init(RenderScriptGL rs, Resources res) {
- mRS = rs;
- mWidth = mRS.getWidth();
- mHeight = mRS.getHeight();
- mRes = res;
- mOptionsARGB.inScaled = false;
- mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
- mMode = 0;
- mMaxModes = 0;
- initRS();
- }
-
- public void surfaceChanged() {
- mWidth = mRS.getWidth();
- mHeight = mRS.getHeight();
-
- Matrix4f proj = new Matrix4f();
- proj.loadOrthoWindow(mWidth, mHeight);
- mPVA.setProjection(proj);
- }
-
- private Resources mRes;
- private RenderScriptGL mRS;
-
- private Sampler mLinearClamp;
- private Sampler mLinearWrap;
- private Sampler mMipLinearWrap;
- private Sampler mNearestClamp;
- private Sampler mMipLinearAniso8;
- private Sampler mMipLinearAniso15;
-
- private ProgramStore mProgStoreBlendNoneDepth;
- private ProgramStore mProgStoreBlendNone;
- private ProgramStore mProgStoreBlendAlpha;
- private ProgramStore mProgStoreBlendAdd;
-
- private ProgramFragment mProgFragmentTexture;
- private ProgramFragment mProgFragmentColor;
-
- private ProgramVertex mProgVertex;
- private ProgramVertexFixedFunction.Constants mPVA;
-
- // Custom shaders
- private ProgramVertex mProgVertexCustom;
- private ProgramFragment mProgFragmentCustom;
- private ProgramFragment mProgFragmentMultitex;
- private ScriptField_VertexShaderConstants_s mVSConst;
- private ScriptField_VertexShaderConstants2_s mVSConst2;
- private ScriptField_FragentShaderConstants_s mFSConst;
- private ScriptField_FragentShaderConstants2_s mFSConst2;
-
- private ProgramVertex mProgVertexCustom2;
- private ProgramFragment mProgFragmentCustom2;
-
- private ProgramVertex mProgVertexCube;
- private ProgramFragment mProgFragmentCube;
-
- private ProgramRaster mCullBack;
- private ProgramRaster mCullFront;
- private ProgramRaster mCullNone;
-
- private Allocation mTexTorus;
- private Allocation mTexOpaque;
- private Allocation mTexTransparent;
- private Allocation mTexChecker;
- private Allocation mTexCube;
-
- private Mesh mMbyNMesh;
- private Mesh mTorus;
-
- Font mFontSans;
- Font mFontSerif;
- Font mFontSerifBold;
- Font mFontSerifItalic;
- Font mFontSerifBoldItalic;
- Font mFontMono;
- private Allocation mTextAlloc;
-
- private ScriptC_rsrenderstates mScript;
-
- private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
-
- int mMode;
- int mMaxModes;
-
- public void onActionDown(int x, int y) {
- mMode ++;
- mMode = mMode % mMaxModes;
- mScript.set_gDisplayMode(mMode);
- }
-
- ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
- ProgramStore.Builder builder = new ProgramStore.Builder(rs);
- builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
- builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
- builder.setDitherEnabled(false);
- builder.setDepthMaskEnabled(false);
- return builder.create();
- }
-
- private Mesh getMbyNMesh(float width, float height, int wResolution, int hResolution) {
-
- Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
- 2, Mesh.TriangleMeshBuilder.TEXTURE_0);
-
- for (int y = 0; y <= hResolution; y++) {
- final float normalizedY = (float)y / hResolution;
- final float yOffset = (normalizedY - 0.5f) * height;
- for (int x = 0; x <= wResolution; x++) {
- float normalizedX = (float)x / wResolution;
- float xOffset = (normalizedX - 0.5f) * width;
- tmb.setTexture(normalizedX, normalizedY);
- tmb.addVertex(xOffset, yOffset);
- }
- }
-
- for (int y = 0; y < hResolution; y++) {
- final int curY = y * (wResolution + 1);
- final int belowY = (y + 1) * (wResolution + 1);
- for (int x = 0; x < wResolution; x++) {
- int curV = curY + x;
- int belowV = belowY + x;
- tmb.addTriangle(curV, belowV, curV + 1);
- tmb.addTriangle(belowV, belowV + 1, curV + 1);
- }
- }
-
- return tmb.create(true);
- }
-
- private void initProgramStore() {
- // Use stock the stock program store object
- mProgStoreBlendNoneDepth = ProgramStore.BLEND_NONE_DEPTH_TEST(mRS);
- mProgStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(mRS);
-
- // Create a custom program store
- ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
- builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
- builder.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA,
- ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA);
- builder.setDitherEnabled(false);
- builder.setDepthMaskEnabled(false);
- mProgStoreBlendAlpha = builder.create();
-
- mProgStoreBlendAdd = BLEND_ADD_DEPTH_NONE(mRS);
-
- mScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth);
- mScript.set_gProgStoreBlendNone(mProgStoreBlendNone);
- mScript.set_gProgStoreBlendAlpha(mProgStoreBlendAlpha);
- mScript.set_gProgStoreBlendAdd(mProgStoreBlendAdd);
- }
-
- private void initProgramFragment() {
-
- ProgramFragmentFixedFunction.Builder texBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
- texBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
- ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
- mProgFragmentTexture = texBuilder.create();
- mProgFragmentTexture.bindSampler(mLinearClamp, 0);
-
- ProgramFragmentFixedFunction.Builder colBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
- colBuilder.setVaryingColor(false);
- mProgFragmentColor = colBuilder.create();
-
- mScript.set_gProgFragmentColor(mProgFragmentColor);
- mScript.set_gProgFragmentTexture(mProgFragmentTexture);
- }
-
- private void initProgramVertex() {
- ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
- mProgVertex = pvb.create();
-
- mPVA = new ProgramVertexFixedFunction.Constants(mRS);
- ((ProgramVertexFixedFunction)mProgVertex).bindConstants(mPVA);
- Matrix4f proj = new Matrix4f();
- proj.loadOrthoWindow(mWidth, mHeight);
- mPVA.setProjection(proj);
-
- mScript.set_gProgVertex(mProgVertex);
- }
-
- private void initCustomShaders() {
- mVSConst = new ScriptField_VertexShaderConstants_s(mRS, 1);
- mVSConst2 = new ScriptField_VertexShaderConstants2_s(mRS, 1);
- mFSConst = new ScriptField_FragentShaderConstants_s(mRS, 1);
- mFSConst2 = new ScriptField_FragentShaderConstants2_s(mRS, 1);
-
- mScript.bind_gVSConstants(mVSConst);
- mScript.bind_gVSConstants2(mVSConst2);
- mScript.bind_gFSConstants(mFSConst);
- mScript.bind_gFSConstants2(mFSConst2);
-
- // Initialize the shader builder
- ProgramVertex.Builder pvbCustom = new ProgramVertex.Builder(mRS);
- // Specify the resource that contains the shader string
- pvbCustom.setShader(mRes, R.raw.shaderv);
- // Use a script field to spcify the input layout
- pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
- // Define the constant input layout
- pvbCustom.addConstant(mVSConst.getAllocation().getType());
- mProgVertexCustom = pvbCustom.create();
- // Bind the source of constant data
- mProgVertexCustom.bindConstants(mVSConst.getAllocation(), 0);
-
- ProgramFragment.Builder pfbCustom = new ProgramFragment.Builder(mRS);
- // Specify the resource that contains the shader string
- pfbCustom.setShader(mRes, R.raw.shaderf);
- //Tell the builder how many textures we have
- pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
- // Define the constant input layout
- pfbCustom.addConstant(mFSConst.getAllocation().getType());
- mProgFragmentCustom = pfbCustom.create();
- // Bind the source of constant data
- mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 0);
-
- pvbCustom = new ProgramVertex.Builder(mRS);
- pvbCustom.setShader(mRes, R.raw.shaderarrayv);
- pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
- pvbCustom.addConstant(mVSConst2.getAllocation().getType());
- mProgVertexCustom2 = pvbCustom.create();
- mProgVertexCustom2.bindConstants(mVSConst2.getAllocation(), 0);
-
- pfbCustom = new ProgramFragment.Builder(mRS);
- pfbCustom.setShader(mRes, R.raw.shaderarrayf);
- pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
- pfbCustom.addConstant(mFSConst2.getAllocation().getType());
- mProgFragmentCustom2 = pfbCustom.create();
- mProgFragmentCustom2.bindConstants(mFSConst2.getAllocation(), 0);
-
- // Cubemap test shaders
- pvbCustom = new ProgramVertex.Builder(mRS);
- pvbCustom.setShader(mRes, R.raw.shadercubev);
- pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
- pvbCustom.addConstant(mVSConst.getAllocation().getType());
- mProgVertexCube = pvbCustom.create();
- mProgVertexCube.bindConstants(mVSConst.getAllocation(), 0);
-
- pfbCustom = new ProgramFragment.Builder(mRS);
- pfbCustom.setShader(mRes, R.raw.shadercubef);
- pfbCustom.addTexture(Program.TextureType.TEXTURE_CUBE);
- mProgFragmentCube = pfbCustom.create();
-
- pfbCustom = new ProgramFragment.Builder(mRS);
- pfbCustom.setShader(mRes, R.raw.multitexf);
- for (int texCount = 0; texCount < 3; texCount ++) {
- pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
- }
- mProgFragmentMultitex = pfbCustom.create();
-
- mScript.set_gProgVertexCustom(mProgVertexCustom);
- mScript.set_gProgFragmentCustom(mProgFragmentCustom);
- mScript.set_gProgVertexCustom2(mProgVertexCustom2);
- mScript.set_gProgFragmentCustom2(mProgFragmentCustom2);
- mScript.set_gProgVertexCube(mProgVertexCube);
- mScript.set_gProgFragmentCube(mProgFragmentCube);
- mScript.set_gProgFragmentMultitex(mProgFragmentMultitex);
- }
-
- private Allocation loadTextureRGB(int id) {
- return Allocation.createFromBitmapResource(mRS, mRes, id,
- Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
- Allocation.USAGE_GRAPHICS_TEXTURE);
- }
-
- private Allocation loadTextureARGB(int id) {
- Bitmap b = BitmapFactory.decodeResource(mRes, id, mOptionsARGB);
- return Allocation.createFromBitmap(mRS, b,
- Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
- Allocation.USAGE_GRAPHICS_TEXTURE);
- }
-
- private void loadImages() {
- mTexTorus = loadTextureRGB(R.drawable.torusmap);
- mTexOpaque = loadTextureRGB(R.drawable.data);
- mTexTransparent = loadTextureARGB(R.drawable.leaf);
- mTexChecker = loadTextureRGB(R.drawable.checker);
- Bitmap b = BitmapFactory.decodeResource(mRes, R.drawable.cubemap_test);
- mTexCube = Allocation.createCubemapFromBitmap(mRS, b);
-
- mScript.set_gTexTorus(mTexTorus);
- mScript.set_gTexOpaque(mTexOpaque);
- mScript.set_gTexTransparent(mTexTransparent);
- mScript.set_gTexChecker(mTexChecker);
- mScript.set_gTexCube(mTexCube);
- }
-
- private void initFonts() {
- // Sans font by family name
- mFontSans = Font.create(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8);
- mFontSerif = Font.create(mRS, mRes, "serif", Font.Style.NORMAL, 8);
- // Create fonts by family and style
- mFontSerifBold = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8);
- mFontSerifItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
- mFontSerifBoldItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
- mFontMono = Font.create(mRS, mRes, "mono", Font.Style.NORMAL, 8);
-
- mTextAlloc = Allocation.createFromString(mRS, "String from allocation", Allocation.USAGE_SCRIPT);
-
- mScript.set_gFontSans(mFontSans);
- mScript.set_gFontSerif(mFontSerif);
- mScript.set_gFontSerifBold(mFontSerifBold);
- mScript.set_gFontSerifItalic(mFontSerifItalic);
- mScript.set_gFontSerifBoldItalic(mFontSerifBoldItalic);
- mScript.set_gFontMono(mFontMono);
- mScript.set_gTextAlloc(mTextAlloc);
- }
-
- private void initMesh() {
- mMbyNMesh = getMbyNMesh(256, 256, 10, 10);
- mScript.set_gMbyNMesh(mMbyNMesh);
-
- FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus);
- FileA3D.IndexEntry entry = model.getIndexEntry(0);
- if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
- Log.e("rs", "could not load model");
- } else {
- mTorus = (Mesh)entry.getObject();
- mScript.set_gTorusMesh(mTorus);
- }
- }
-
- private void initSamplers() {
- Sampler.Builder bs = new Sampler.Builder(mRS);
- bs.setMinification(Sampler.Value.LINEAR);
- bs.setMagnification(Sampler.Value.LINEAR);
- bs.setWrapS(Sampler.Value.WRAP);
- bs.setWrapT(Sampler.Value.WRAP);
- mLinearWrap = bs.create();
-
- mLinearClamp = Sampler.CLAMP_LINEAR(mRS);
- mNearestClamp = Sampler.CLAMP_NEAREST(mRS);
- mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS);
-
- bs = new Sampler.Builder(mRS);
- bs.setMinification(Sampler.Value.LINEAR_MIP_LINEAR);
- bs.setMagnification(Sampler.Value.LINEAR);
- bs.setWrapS(Sampler.Value.WRAP);
- bs.setWrapT(Sampler.Value.WRAP);
- bs.setAnisotropy(8.0f);
- mMipLinearAniso8 = bs.create();
- bs.setAnisotropy(15.0f);
- mMipLinearAniso15 = bs.create();
-
- mScript.set_gLinearClamp(mLinearClamp);
- mScript.set_gLinearWrap(mLinearWrap);
- mScript.set_gMipLinearWrap(mMipLinearWrap);
- mScript.set_gMipLinearAniso8(mMipLinearAniso8);
- mScript.set_gMipLinearAniso15(mMipLinearAniso15);
- mScript.set_gNearestClamp(mNearestClamp);
- }
-
- private void initProgramRaster() {
- mCullBack = ProgramRaster.CULL_BACK(mRS);
- mCullFront = ProgramRaster.CULL_FRONT(mRS);
- mCullNone = ProgramRaster.CULL_NONE(mRS);
-
- mScript.set_gCullBack(mCullBack);
- mScript.set_gCullFront(mCullFront);
- mScript.set_gCullNone(mCullNone);
- }
-
- private void initRS() {
-
- mScript = new ScriptC_rsrenderstates(mRS, mRes, R.raw.rsrenderstates);
-
- mMaxModes = mScript.get_gMaxModes();
-
- initSamplers();
- initProgramStore();
- initProgramFragment();
- initProgramVertex();
- initFonts();
- loadImages();
- initMesh();
- initProgramRaster();
- initCustomShaders();
-
- mRS.bindRootScript(mScript);
- }
-}
-
-
-
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesView.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesView.java
deleted file mode 100644
index 4d339dd..0000000
--- a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesView.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 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.
- * 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.samples;
-
-import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScriptGL;
-
-import android.content.Context;
-import android.view.MotionEvent;
-import android.view.SurfaceHolder;
-
-public class RsRenderStatesView extends RSSurfaceView {
-
- public RsRenderStatesView(Context context) {
- super(context);
- ensureRenderScript();
- }
-
- private RenderScriptGL mRS;
- private RsRenderStatesRS mRender;
-
- private void ensureRenderScript() {
- if (mRS == null) {
- RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
- sc.setDepth(16, 24);
- mRS = createRenderScriptGL(sc);
- mRender = new RsRenderStatesRS();
- mRender.init(mRS, getResources());
- }
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- ensureRenderScript();
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
- super.surfaceChanged(holder, format, w, h);
- mRender.surfaceChanged();
- }
-
- @Override
- protected void onDetachedFromWindow() {
- mRender = null;
- if (mRS != null) {
- mRS = null;
- destroyRenderScriptGL();
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- mRender.onActionDown((int)ev.getX(), (int)ev.getY());
- return true;
- }
-
- return false;
- }
-}
-
-
diff --git a/libs/rs/java/Samples/src/com/android/samples/rslist.rs b/libs/rs/java/Samples/src/com/android/samples/rslist.rs
deleted file mode 100644
index 52c870a..0000000
--- a/libs/rs/java/Samples/src/com/android/samples/rslist.rs
+++ /dev/null
@@ -1,70 +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.
-
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.samples)
-
-#include "rs_graphics.rsh"
-
-float gDY;
-
-rs_font gItalic;
-
-typedef struct ListAllocs_s {
- rs_allocation text;
-} ListAllocs;
-
-ListAllocs *gList;
-
-void init() {
- gDY = 0.0f;
-}
-
-int textPos = 0;
-
-int root(int launchID) {
-
- rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-
- textPos -= (int)gDY*2;
- gDY *= 0.95;
-
- rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f);
- rsgBindFont(gItalic);
-
- rs_allocation listAlloc;
- rsSetObject(&listAlloc, rsGetAllocation(gList));
- int allocSize = rsAllocationGetDimX(listAlloc);
-
- int width = rsgGetWidth();
- int height = rsgGetHeight();
-
- int itemHeight = 80;
- int currentYPos = itemHeight + textPos;
-
- for (int i = 0; i < allocSize; i ++) {
- if (currentYPos - itemHeight > height) {
- break;
- }
-
- if (currentYPos > 0) {
- rsgDrawRect(0, currentYPos - 1, width, currentYPos, 0);
- rsgDrawText(gList[i].text, 30, currentYPos - 32);
- }
- currentYPos += itemHeight;
- }
-
- return 10;
-}
diff --git a/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs b/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs
deleted file mode 100644
index 9019533..0000000
--- a/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs
+++ /dev/null
@@ -1,680 +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.
-
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.samples)
-
-#include "rs_graphics.rsh"
-#include "shader_def.rsh"
-
-const int gMaxModes = 11;
-
-rs_program_vertex gProgVertex;
-rs_program_fragment gProgFragmentColor;
-rs_program_fragment gProgFragmentTexture;
-
-rs_program_store gProgStoreBlendNoneDepth;
-rs_program_store gProgStoreBlendNone;
-rs_program_store gProgStoreBlendAlpha;
-rs_program_store gProgStoreBlendAdd;
-
-rs_allocation gTexOpaque;
-rs_allocation gTexTorus;
-rs_allocation gTexTransparent;
-rs_allocation gTexChecker;
-rs_allocation gTexCube;
-
-rs_mesh gMbyNMesh;
-rs_mesh gTorusMesh;
-
-rs_font gFontSans;
-rs_font gFontSerif;
-rs_font gFontSerifBold;
-rs_font gFontSerifItalic;
-rs_font gFontSerifBoldItalic;
-rs_font gFontMono;
-rs_allocation gTextAlloc;
-
-int gDisplayMode;
-
-rs_sampler gLinearClamp;
-rs_sampler gLinearWrap;
-rs_sampler gMipLinearWrap;
-rs_sampler gMipLinearAniso8;
-rs_sampler gMipLinearAniso15;
-rs_sampler gNearestClamp;
-
-rs_program_raster gCullBack;
-rs_program_raster gCullFront;
-rs_program_raster gCullNone;
-
-// Custom vertex shader compunents
-VertexShaderConstants *gVSConstants;
-VertexShaderConstants2 *gVSConstants2;
-FragentShaderConstants *gFSConstants;
-FragentShaderConstants2 *gFSConstants2;
-// Export these out to easily set the inputs to shader
-VertexShaderInputs *gVSInputs;
-// Custom shaders we use for lighting
-rs_program_vertex gProgVertexCustom;
-rs_program_fragment gProgFragmentCustom;
-rs_program_vertex gProgVertexCustom2;
-rs_program_fragment gProgFragmentCustom2;
-rs_program_vertex gProgVertexCube;
-rs_program_fragment gProgFragmentCube;
-rs_program_fragment gProgFragmentMultitex;
-
-float gDt = 0;
-
-void init() {
-}
-
-static void displayFontSamples() {
- rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
- int yPos = 100;
- rsgBindFont(gFontSans);
- rsgDrawText("Sans font sample", 30, yPos);
- yPos += 30;
- rsgFontColor(0.5f, 0.9f, 0.5f, 1.0f);
- rsgBindFont(gFontSerif);
- rsgDrawText("Serif font sample", 30, yPos);
- yPos += 30;
- rsgFontColor(0.7f, 0.7f, 0.7f, 1.0f);
- rsgBindFont(gFontSerifBold);
- rsgDrawText("Serif Bold font sample", 30, yPos);
- yPos += 30;
- rsgFontColor(0.5f, 0.5f, 0.9f, 1.0f);
- rsgBindFont(gFontSerifItalic);
- rsgDrawText("Serif Italic font sample", 30, yPos);
- yPos += 30;
- rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
- rsgBindFont(gFontSerifBoldItalic);
- rsgDrawText("Serif Bold Italic font sample", 30, yPos);
- yPos += 30;
- rsgBindFont(gFontMono);
- rsgDrawText("Monospace font sample", 30, yPos);
- yPos += 50;
-
- // Now use text metrics to center the text
- uint width = rsgGetWidth();
- uint height = rsgGetHeight();
- int left = 0, right = 0, top = 0, bottom = 0;
-
- rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
- rsgBindFont(gFontSerifBoldItalic);
-
- rsgMeasureText(gTextAlloc, &left, &right, &top, &bottom);
- int centeredPos = width / 2 - (right - left) / 2;
- rsgDrawText(gTextAlloc, centeredPos, yPos);
- yPos += 30;
-
- const char* text = "Centered Text Sample";
- rsgMeasureText(text, &left, &right, &top, &bottom);
- centeredPos = width / 2 - (right - left) / 2;
- rsgDrawText(text, centeredPos, yPos);
- yPos += 30;
-
- rsgBindFont(gFontSans);
- text = "More Centered Text Samples";
- rsgMeasureText(text, &left, &right, &top, &bottom);
- centeredPos = width / 2 - (right - left) / 2;
- rsgDrawText(text, centeredPos, yPos);
- yPos += 30;
-
- // Now draw bottom and top right aligned text
- text = "Top-right aligned text";
- rsgMeasureText(text, &left, &right, &top, &bottom);
- rsgDrawText(text, width - right, top);
-
- text = "Top-left";
- rsgMeasureText(text, &left, &right, &top, &bottom);
- rsgDrawText(text, -left, top);
-
- text = "Bottom-right aligned text";
- rsgMeasureText(text, &left, &right, &top, &bottom);
- rsgDrawText(text, width - right, height + bottom);
-
-}
-
-static void bindProgramVertexOrtho() {
- // Default vertex sahder
- rsgBindProgramVertex(gProgVertex);
- // Setup the projectioni matrix
- rs_matrix4x4 proj;
- rsMatrixLoadOrtho(&proj, 0, rsgGetWidth(), rsgGetHeight(), 0, -500, 500);
- rsgProgramVertexLoadProjectionMatrix(&proj);
-}
-
-static void displayShaderSamples() {
- bindProgramVertexOrtho();
- rs_matrix4x4 matrix;
- rsMatrixLoadIdentity(&matrix);
- rsgProgramVertexLoadModelMatrix(&matrix);
-
- // Fragment shader with texture
- rsgBindProgramStore(gProgStoreBlendNone);
- rsgBindProgramFragment(gProgFragmentTexture);
- rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
- rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
-
- float startX = 0, startY = 0;
- float width = 256, height = 256;
- rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
- startX, startY + height, 0, 0, 1,
- startX + width, startY + height, 0, 1, 1,
- startX + width, startY, 0, 1, 0);
-
- startX = 200; startY = 0;
- width = 128; height = 128;
- rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
- startX, startY + height, 0, 0, 1,
- startX + width, startY + height, 0, 1, 1,
- startX + width, startY, 0, 1, 0);
-
- rsgBindProgramStore(gProgStoreBlendAlpha);
- rsgBindTexture(gProgFragmentTexture, 0, gTexTransparent);
- startX = 0; startY = 200;
- width = 128; height = 128;
- rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
- startX, startY + height, 0, 0, 1,
- startX + width, startY + height, 0, 1, 1,
- startX + width, startY, 0, 1, 0);
-
- // Fragment program with simple color
- rsgBindProgramFragment(gProgFragmentColor);
- rsgProgramFragmentConstantColor(gProgFragmentColor, 0.9, 0.3, 0.3, 1);
- rsgDrawRect(200, 300, 350, 450, 0);
- rsgProgramFragmentConstantColor(gProgFragmentColor, 0.3, 0.9, 0.3, 1);
- rsgDrawRect(50, 400, 400, 600, 0);
-
- rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
- rsgBindFont(gFontMono);
- rsgDrawText("Texture shader", 10, 50);
- rsgDrawText("Alpha-blended texture shader", 10, 280);
- rsgDrawText("Flat color shader", 100, 450);
-}
-
-static void displayBlendingSamples() {
- int i;
-
- bindProgramVertexOrtho();
- rs_matrix4x4 matrix;
- rsMatrixLoadIdentity(&matrix);
- rsgProgramVertexLoadModelMatrix(&matrix);
-
- rsgBindProgramFragment(gProgFragmentColor);
-
- rsgBindProgramStore(gProgStoreBlendNone);
- for (i = 0; i < 3; i ++) {
- float iPlusOne = (float)(i + 1);
- rsgProgramFragmentConstantColor(gProgFragmentColor,
- 0.1f*iPlusOne, 0.2f*iPlusOne, 0.3f*iPlusOne, 1);
- float yPos = 150 * (float)i;
- rsgDrawRect(0, yPos, 200, yPos + 200, 0);
- }
-
- rsgBindProgramStore(gProgStoreBlendAlpha);
- for (i = 0; i < 3; i ++) {
- float iPlusOne = (float)(i + 1);
- rsgProgramFragmentConstantColor(gProgFragmentColor,
- 0.2f*iPlusOne, 0.3f*iPlusOne, 0.1f*iPlusOne, 0.5);
- float yPos = 150 * (float)i;
- rsgDrawRect(150, yPos, 350, yPos + 200, 0);
- }
-
- rsgBindProgramStore(gProgStoreBlendAdd);
- for (i = 0; i < 3; i ++) {
- float iPlusOne = (float)(i + 1);
- rsgProgramFragmentConstantColor(gProgFragmentColor,
- 0.3f*iPlusOne, 0.1f*iPlusOne, 0.2f*iPlusOne, 0.5);
- float yPos = 150 * (float)i;
- rsgDrawRect(300, yPos, 500, yPos + 200, 0);
- }
-
-
- rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
- rsgBindFont(gFontMono);
- rsgDrawText("No Blending", 10, 50);
- rsgDrawText("Alpha Blending", 160, 150);
- rsgDrawText("Additive Blending", 320, 250);
-
-}
-
-static void displayMeshSamples() {
-
- bindProgramVertexOrtho();
- rs_matrix4x4 matrix;
- rsMatrixLoadTranslate(&matrix, 128, 128, 0);
- rsgProgramVertexLoadModelMatrix(&matrix);
-
- // Fragment shader with texture
- rsgBindProgramStore(gProgStoreBlendNone);
- rsgBindProgramFragment(gProgFragmentTexture);
- rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
- rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
-
- rsgDrawMesh(gMbyNMesh);
-
- rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
- rsgBindFont(gFontMono);
- rsgDrawText("User gen 10 by 10 grid mesh", 10, 250);
-}
-
-static void displayTextureSamplers() {
-
- bindProgramVertexOrtho();
- rs_matrix4x4 matrix;
- rsMatrixLoadIdentity(&matrix);
- rsgProgramVertexLoadModelMatrix(&matrix);
-
- // Fragment shader with texture
- rsgBindProgramStore(gProgStoreBlendNone);
- rsgBindProgramFragment(gProgFragmentTexture);
- rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
-
- // Linear clamp
- rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
- float startX = 0, startY = 0;
- float width = 300, height = 300;
- rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
- startX, startY + height, 0, 0, 1.1,
- startX + width, startY + height, 0, 1.1, 1.1,
- startX + width, startY, 0, 1.1, 0);
-
- // Linear Wrap
- rsgBindSampler(gProgFragmentTexture, 0, gLinearWrap);
- startX = 0; startY = 300;
- width = 300; height = 300;
- rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
- startX, startY + height, 0, 0, 1.1,
- startX + width, startY + height, 0, 1.1, 1.1,
- startX + width, startY, 0, 1.1, 0);
-
- // Nearest
- rsgBindSampler(gProgFragmentTexture, 0, gNearestClamp);
- startX = 300; startY = 0;
- width = 300; height = 300;
- rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
- startX, startY + height, 0, 0, 1.1,
- startX + width, startY + height, 0, 1.1, 1.1,
- startX + width, startY, 0, 1.1, 0);
-
- rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
- startX = 300; startY = 300;
- width = 300; height = 300;
- rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
- startX, startY + height, 0, 0, 1.5,
- startX + width, startY + height, 0, 1.5, 1.5,
- startX + width, startY, 0, 1.5, 0);
-
- rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
- rsgBindFont(gFontMono);
- rsgDrawText("Filtering: linear clamp", 10, 290);
- rsgDrawText("Filtering: linear wrap", 10, 590);
- rsgDrawText("Filtering: nearest clamp", 310, 290);
- rsgDrawText("Filtering: miplinear wrap", 310, 590);
-}
-
-static float gTorusRotation = 0;
-
-static void displayCullingSamples() {
- rsgBindProgramVertex(gProgVertex);
- // Setup the projectioni matrix with 60 degree field of view
- rs_matrix4x4 proj;
- float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
- rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
- rsgProgramVertexLoadProjectionMatrix(&proj);
-
- // Fragment shader with texture
- rsgBindProgramStore(gProgStoreBlendNoneDepth);
- rsgBindProgramFragment(gProgFragmentTexture);
- rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
- rsgBindTexture(gProgFragmentTexture, 0, gTexTorus);
-
- // Aplly a rotation to our mesh
- gTorusRotation += 50.0f * gDt;
- if (gTorusRotation > 360.0f) {
- gTorusRotation -= 360.0f;
- }
-
- rs_matrix4x4 matrix;
- // Position our model on the screen
- rsMatrixLoadTranslate(&matrix, -2.0f, 0.0f, -10.0f);
- rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
- rsgProgramVertexLoadModelMatrix(&matrix);
- // Use front face culling
- rsgBindProgramRaster(gCullFront);
- rsgDrawMesh(gTorusMesh);
-
- rsMatrixLoadTranslate(&matrix, 2.0f, 0.0f, -10.0f);
- rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
- rsgProgramVertexLoadModelMatrix(&matrix);
- // Use back face culling
- rsgBindProgramRaster(gCullBack);
- rsgDrawMesh(gTorusMesh);
-
- rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
- rsgBindFont(gFontMono);
- rsgDrawText("Displaying mesh front/back face culling", 10, rsgGetHeight() - 10);
-}
-
-static float gLight0Rotation = 0;
-static float gLight1Rotation = 0;
-
-static void setupCustomShaderLights() {
- float4 light0Pos = {-5.0f, 5.0f, -10.0f, 1.0f};
- float4 light1Pos = {2.0f, 5.0f, 15.0f, 1.0f};
- float4 light0DiffCol = {0.9f, 0.7f, 0.7f, 1.0f};
- float4 light0SpecCol = {0.9f, 0.6f, 0.6f, 1.0f};
- float4 light1DiffCol = {0.5f, 0.5f, 0.9f, 1.0f};
- float4 light1SpecCol = {0.5f, 0.5f, 0.9f, 1.0f};
-
- gLight0Rotation += 50.0f * gDt;
- if (gLight0Rotation > 360.0f) {
- gLight0Rotation -= 360.0f;
- }
- gLight1Rotation -= 50.0f * gDt;
- if (gLight1Rotation > 360.0f) {
- gLight1Rotation -= 360.0f;
- }
-
- rs_matrix4x4 l0Mat;
- rsMatrixLoadRotate(&l0Mat, gLight0Rotation, 1.0f, 0.0f, 0.0f);
- light0Pos = rsMatrixMultiply(&l0Mat, light0Pos);
- rs_matrix4x4 l1Mat;
- rsMatrixLoadRotate(&l1Mat, gLight1Rotation, 0.0f, 0.0f, 1.0f);
- light1Pos = rsMatrixMultiply(&l1Mat, light1Pos);
-
- // Set light 0 properties
- gVSConstants->light0_Posision = light0Pos;
- gVSConstants->light0_Diffuse = 1.0f;
- gVSConstants->light0_Specular = 0.5f;
- gVSConstants->light0_CosinePower = 10.0f;
- // Set light 1 properties
- gVSConstants->light1_Posision = light1Pos;
- gVSConstants->light1_Diffuse = 1.0f;
- gVSConstants->light1_Specular = 0.7f;
- gVSConstants->light1_CosinePower = 25.0f;
- rsgAllocationSyncAll(rsGetAllocation(gVSConstants));
-
- gVSConstants2->light_Posision[0] = light0Pos;
- gVSConstants2->light_Diffuse[0] = 1.0f;
- gVSConstants2->light_Specular[0] = 0.5f;
- gVSConstants2->light_CosinePower[0] = 10.0f;
- gVSConstants2->light_Posision[1] = light1Pos;
- gVSConstants2->light_Diffuse[1] = 1.0f;
- gVSConstants2->light_Specular[1] = 0.7f;
- gVSConstants2->light_CosinePower[1] = 25.0f;
- rsgAllocationSyncAll(rsGetAllocation(gVSConstants2));
-
- // Update fragmetn shader constants
- // Set light 0 colors
- gFSConstants->light0_DiffuseColor = light0DiffCol;
- gFSConstants->light0_SpecularColor = light0SpecCol;
- // Set light 1 colors
- gFSConstants->light1_DiffuseColor = light1DiffCol;
- gFSConstants->light1_SpecularColor = light1SpecCol;
- rsgAllocationSyncAll(rsGetAllocation(gFSConstants));
-
- gFSConstants2->light_DiffuseColor[0] = light0DiffCol;
- gFSConstants2->light_SpecularColor[0] = light0SpecCol;
- // Set light 1 colors
- gFSConstants2->light_DiffuseColor[1] = light1DiffCol;
- gFSConstants2->light_SpecularColor[1] = light1SpecCol;
- rsgAllocationSyncAll(rsGetAllocation(gFSConstants2));
-}
-
-static void displayCustomShaderSamples() {
-
- // Update vertex shader constants
- // Load model matrix
- // Aplly a rotation to our mesh
- gTorusRotation += 50.0f * gDt;
- if (gTorusRotation > 360.0f) {
- gTorusRotation -= 360.0f;
- }
-
- // Position our model on the screen
- rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -10.0f);
- rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
- rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
- // Setup the projectioni matrix
- float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
- rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f);
- setupCustomShaderLights();
-
- rsgBindProgramVertex(gProgVertexCustom);
-
- // Fragment shader with texture
- rsgBindProgramStore(gProgStoreBlendNoneDepth);
- rsgBindProgramFragment(gProgFragmentCustom);
- rsgBindSampler(gProgFragmentCustom, 0, gLinearClamp);
- rsgBindTexture(gProgFragmentCustom, 0, gTexTorus);
-
- // Use back face culling
- rsgBindProgramRaster(gCullBack);
- rsgDrawMesh(gTorusMesh);
-
- rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
- rsgBindFont(gFontMono);
- rsgDrawText("Custom shader sample", 10, rsgGetHeight() - 10);
-}
-
-static void displayCustomShaderSamples2() {
-
- // Update vertex shader constants
- // Load model matrix
- // Aplly a rotation to our mesh
- gTorusRotation += 50.0f * gDt;
- if (gTorusRotation > 360.0f) {
- gTorusRotation -= 360.0f;
- }
-
- // Position our model on the screen
- rsMatrixLoadTranslate(&gVSConstants2->model[1], 0.0f, 0.0f, -10.0f);
- rsMatrixLoadIdentity(&gVSConstants2->model[0]);
- rsMatrixRotate(&gVSConstants2->model[0], gTorusRotation, 1.0f, 0.0f, 0.0f);
- rsMatrixRotate(&gVSConstants2->model[0], gTorusRotation, 0.0f, 0.0f, 1.0f);
- // Setup the projectioni matrix
- float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
- rsMatrixLoadPerspective(&gVSConstants2->proj, 30.0f, aspect, 0.1f, 100.0f);
- setupCustomShaderLights();
-
- rsgBindProgramVertex(gProgVertexCustom2);
-
- // Fragment shader with texture
- rsgBindProgramStore(gProgStoreBlendNoneDepth);
- rsgBindProgramFragment(gProgFragmentCustom2);
- rsgBindSampler(gProgFragmentCustom2, 0, gLinearClamp);
- rsgBindTexture(gProgFragmentCustom2, 0, gTexTorus);
-
- // Use back face culling
- rsgBindProgramRaster(gCullBack);
- rsgDrawMesh(gTorusMesh);
-
- rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
- rsgBindFont(gFontMono);
- rsgDrawText("Custom shader sample with array uniforms", 10, rsgGetHeight() - 10);
-}
-
-static void displayCubemapShaderSample() {
- // Update vertex shader constants
- // Load model matrix
- // Aplly a rotation to our mesh
- gTorusRotation += 50.0f * gDt;
- if (gTorusRotation > 360.0f) {
- gTorusRotation -= 360.0f;
- }
-
- // Position our model on the screen
- // Position our model on the screen
- rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -10.0f);
- rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
- rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
- // Setup the projectioni matrix
- float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
- rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f);
- rsgAllocationSyncAll(rsGetAllocation(gFSConstants));
-
- rsgBindProgramVertex(gProgVertexCube);
-
- // Fragment shader with texture
- rsgBindProgramStore(gProgStoreBlendNoneDepth);
- rsgBindProgramFragment(gProgFragmentCube);
- rsgBindSampler(gProgFragmentCube, 0, gLinearClamp);
- rsgBindTexture(gProgFragmentCube, 0, gTexCube);
-
- // Use back face culling
- rsgBindProgramRaster(gCullBack);
- rsgDrawMesh(gTorusMesh);
-
- rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
- rsgBindFont(gFontMono);
- rsgDrawText("Cubemap shader sample", 10, rsgGetHeight() - 10);
-}
-
-static void displayMultitextureSample() {
- bindProgramVertexOrtho();
- rs_matrix4x4 matrix;
- rsMatrixLoadIdentity(&matrix);
- rsgProgramVertexLoadModelMatrix(&matrix);
-
- // Fragment shader with texture
- rsgBindProgramStore(gProgStoreBlendNone);
- rsgBindProgramFragment(gProgFragmentMultitex);
- rsgBindSampler(gProgFragmentMultitex, 0, gLinearClamp);
- rsgBindSampler(gProgFragmentMultitex, 1, gLinearWrap);
- rsgBindSampler(gProgFragmentMultitex, 2, gLinearClamp);
- rsgBindTexture(gProgFragmentMultitex, 0, gTexChecker);
- rsgBindTexture(gProgFragmentMultitex, 1, gTexTorus);
- rsgBindTexture(gProgFragmentMultitex, 2, gTexTransparent);
-
- float startX = 0, startY = 0;
- float width = 256, height = 256;
- rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
- startX, startY + height, 0, 0, 1,
- startX + width, startY + height, 0, 1, 1,
- startX + width, startY, 0, 1, 0);
-
- rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
- rsgBindFont(gFontMono);
- rsgDrawText("Custom shader with multitexturing", 10, 280);
-}
-
-static float gAnisoTime = 0.0f;
-static uint anisoMode = 0;
-static void displayAnisoSample() {
-
- gAnisoTime += gDt;
-
- rsgBindProgramVertex(gProgVertex);
- float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
- rs_matrix4x4 proj;
- rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
- rsgProgramVertexLoadProjectionMatrix(&proj);
-
- rs_matrix4x4 matrix;
- // Fragment shader with texture
- rsgBindProgramStore(gProgStoreBlendNone);
- rsgBindProgramFragment(gProgFragmentTexture);
- rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, -10.0f);
- rsMatrixRotate(&matrix, -80, 1.0f, 0.0f, 0.0f);
- rsgProgramVertexLoadModelMatrix(&matrix);
-
- rsgBindProgramRaster(gCullNone);
-
- rsgBindTexture(gProgFragmentTexture, 0, gTexChecker);
-
- if (gAnisoTime >= 5.0f) {
- gAnisoTime = 0.0f;
- anisoMode ++;
- anisoMode = anisoMode % 3;
- }
-
- if (anisoMode == 0) {
- rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso8);
- } else if (anisoMode == 1) {
- rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso15);
- } else {
- rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
- }
-
- float startX = -15;
- float startY = -15;
- float width = 30;
- float height = 30;
- rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
- startX, startY + height, 0, 0, 10,
- startX + width, startY + height, 0, 10, 10,
- startX + width, startY, 0, 10, 0);
-
- rsgBindProgramRaster(gCullBack);
-
- rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
- rsgBindFont(gFontMono);
- if (anisoMode == 0) {
- rsgDrawText("Anisotropic filtering 8", 10, 40);
- } else if (anisoMode == 1) {
- rsgDrawText("Anisotropic filtering 15", 10, 40);
- } else {
- rsgDrawText("Miplinear filtering", 10, 40);
- }
-}
-
-int root(int launchID) {
-
- gDt = rsGetDt();
-
- rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
- rsgClearDepth(1.0f);
-
- switch (gDisplayMode) {
- case 0:
- displayFontSamples();
- break;
- case 1:
- displayShaderSamples();
- break;
- case 2:
- displayBlendingSamples();
- break;
- case 3:
- displayMeshSamples();
- break;
- case 4:
- displayTextureSamplers();
- break;
- case 5:
- displayCullingSamples();
- break;
- case 6:
- displayCustomShaderSamples();
- break;
- case 7:
- displayMultitextureSample();
- break;
- case 8:
- displayAnisoSample();
- break;
- case 9:
- displayCustomShaderSamples2();
- break;
- case 10:
- displayCubemapShaderSample();
- break;
- }
-
- return 10;
-}
diff --git a/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh b/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh
deleted file mode 100644
index 1d804c6..0000000
--- a/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh
+++ /dev/null
@@ -1,83 +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.
-
-#pragma version(1)
-
-#pragma rs java_package_name(com.android.samples)
-
-typedef struct VertexShaderConstants_s {
- rs_matrix4x4 model;
- rs_matrix4x4 proj;
- float4 light0_Posision;
- float light0_Diffuse;
- float light0_Specular;
- float light0_CosinePower;
-
- float4 light1_Posision;
- float light1_Diffuse;
- float light1_Specular;
- float light1_CosinePower;
-} VertexShaderConstants;
-
-typedef struct VertexShaderConstants2_s {
- rs_matrix4x4 model[2];
- rs_matrix4x4 proj;
- float4 light_Posision[2];
- float light_Diffuse[2];
- float light_Specular[2];
- float light_CosinePower[2];
-} VertexShaderConstants2;
-
-typedef struct VertexShaderConstants3_s {
- rs_matrix4x4 model;
- rs_matrix4x4 proj;
- float time;
-} VertexShaderConstants3;
-
-
-typedef struct FragentShaderConstants_s {
- float4 light0_DiffuseColor;
- float4 light0_SpecularColor;
-
- float4 light1_DiffuseColor;
- float4 light1_SpecularColor;
-} FragentShaderConstants;
-
-typedef struct FragentShaderConstants2_s {
- float4 light_DiffuseColor[2];
- float4 light_SpecularColor[2];
-} FragentShaderConstants2;
-
-typedef struct FragentShaderConstants3_s {
- float4 light0_DiffuseColor;
- float4 light0_SpecularColor;
- float4 light0_Posision;
- float light0_Diffuse;
- float light0_Specular;
- float light0_CosinePower;
-
- float4 light1_DiffuseColor;
- float4 light1_SpecularColor;
- float4 light1_Posision;
- float light1_Diffuse;
- float light1_Specular;
- float light1_CosinePower;
-} FragentShaderConstants3;
-
-typedef struct VertexShaderInputs_s {
- float4 position;
- float3 normal;
- float2 texture0;
-} VertexShaderInputs;
-
diff --git a/libs/rs/java/_index.html b/libs/rs/java/_index.html
deleted file mode 100644
index 5872431..0000000
--- a/libs/rs/java/_index.html
+++ /dev/null
@@ -1 +0,0 @@
-<p>A set of samples that demonstrate how to use various features of the Renderscript APIs.</p>
\ No newline at end of file
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index d539833..ffc3346 100755
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -29,6 +29,7 @@
import android.util.Log;
import com.android.internal.R;
+import com.android.internal.telephony.GsmAlphabet;
/**
* A GPS Network-initiated Handler class used by LocationManager.
@@ -288,58 +289,32 @@
*/
static String decodeGSMPackedString(byte[] input)
{
- final char CHAR_CR = 0x0D;
- int nStridx = 0;
- int nPckidx = 0;
- int num_bytes = input.length;
- int cPrev = 0;
- int cCurr = 0;
- byte nShift;
- byte nextChar;
- byte[] stringBuf = new byte[input.length * 2];
- String result = "";
+ final char PADDING_CHAR = 0x00;
+ int lengthBytes = input.length;
+ int lengthSeptets = (lengthBytes * 8) / 7;
+ String decoded;
- while(nPckidx < num_bytes)
- {
- nShift = (byte) (nStridx & 0x07);
- cCurr = input[nPckidx++];
- if (cCurr < 0) cCurr += 256;
-
- /* A 7-bit character can be split at the most between two bytes of packed
- ** data.
- */
- nextChar = (byte) (( (cCurr << nShift) | (cPrev >> (8-nShift)) ) & 0x7F);
- stringBuf[nStridx++] = nextChar;
-
- /* Special case where the whole of the next 7-bit character fits inside
- ** the current byte of packed data.
- */
- if(nShift == 6)
- {
- /* If the next 7-bit character is a CR (0x0D) and it is the last
- ** character, then it indicates a padding character. Drop it.
- */
- if (nPckidx == num_bytes || (cCurr >> 1) == CHAR_CR)
- {
- break;
+ /* Special case where the last 7 bits in the last byte could hold a valid
+ * 7-bit character or a padding character. Drop the last 7-bit character
+ * if it is a padding character.
+ */
+ if (lengthBytes % 7 == 0) {
+ if (lengthBytes > 0) {
+ if ((input[lengthBytes - 1] >> 1) == PADDING_CHAR) {
+ lengthSeptets = lengthSeptets - 1;
}
-
- nextChar = (byte) (cCurr >> 1);
- stringBuf[nStridx++] = nextChar;
}
-
- cPrev = cCurr;
}
- try {
- result = new String(stringBuf, 0, nStridx, "US-ASCII");
- }
- catch (UnsupportedEncodingException e)
- {
- Log.e(TAG, e.getMessage());
+ decoded = GsmAlphabet.gsm7BitPackedToString(input, 0, lengthSeptets);
+
+ // Return "" if decoding of GSM packed string fails
+ if (null == decoded) {
+ Log.e(TAG, "Decoding of GSM packed string failed");
+ decoded = "";
}
- return result;
+ return decoded;
}
static String decodeUTF8String(byte[] input)
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 1fe3ccc..5a73d2d 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -1218,7 +1218,7 @@
if (!checkAudioSettingsPermission("startBluetoothSco()")) {
return;
}
- ScoClient client = getScoClient(cb);
+ ScoClient client = getScoClient(cb, true);
client.incCount();
}
@@ -1227,8 +1227,10 @@
if (!checkAudioSettingsPermission("stopBluetoothSco()")) {
return;
}
- ScoClient client = getScoClient(cb);
- client.decCount();
+ ScoClient client = getScoClient(cb, false);
+ if (client != null) {
+ client.decCount();
+ }
}
private class ScoClient implements IBinder.DeathRecipient {
@@ -1355,27 +1357,38 @@
}
}
- public ScoClient getScoClient(IBinder cb) {
+ private ScoClient getScoClient(IBinder cb, boolean create) {
synchronized(mScoClients) {
- ScoClient client;
+ ScoClient client = null;
int size = mScoClients.size();
for (int i = 0; i < size; i++) {
client = mScoClients.get(i);
if (client.getBinder() == cb)
return client;
}
- client = new ScoClient(cb);
- mScoClients.add(client);
+ if (create) {
+ client = new ScoClient(cb);
+ mScoClients.add(client);
+ }
return client;
}
}
public void clearAllScoClients(IBinder exceptBinder, boolean stopSco) {
synchronized(mScoClients) {
+ ScoClient savedClient = null;
int size = mScoClients.size();
for (int i = 0; i < size; i++) {
- if (mScoClients.get(i).getBinder() != exceptBinder)
- mScoClients.get(i).clearCount(stopSco);
+ ScoClient cl = mScoClients.get(i);
+ if (cl.getBinder() != exceptBinder) {
+ cl.clearCount(stopSco);
+ } else {
+ savedClient = cl;
+ }
+ }
+ mScoClients.clear();
+ if (savedClient != null) {
+ mScoClients.add(savedClient);
}
}
}
@@ -2320,6 +2333,7 @@
case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
audioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
mScoAudioState = SCO_STATE_INACTIVE;
+ clearAllScoClients(null, false);
break;
case BluetoothHeadset.STATE_AUDIO_CONNECTING:
if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL) {
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index e0df257..53bbb0f 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -3556,7 +3556,7 @@
case MediaProperties.ASPECT_RATIO_4_3:
if (height == MediaProperties.HEIGHT_480)
retValue = VideoFrameSize.VGA;
- if (height == MediaProperties.HEIGHT_720)
+ else if (height == MediaProperties.HEIGHT_720)
retValue = VideoFrameSize.S720p;
break;
case MediaProperties.ASPECT_RATIO_5_3:
@@ -3566,6 +3566,8 @@
case MediaProperties.ASPECT_RATIO_11_9:
if (height == MediaProperties.HEIGHT_144)
retValue = VideoFrameSize.QCIF;
+ else if (height == MediaProperties.HEIGHT_288)
+ retValue = VideoFrameSize.CIF;
break;
}
if (retValue == VideoFrameSize.SIZE_UNDEFINED) {
diff --git a/media/java/android/media/videoeditor/MediaProperties.java b/media/java/android/media/videoeditor/MediaProperties.java
index 0b7ec08..0225807 100755
--- a/media/java/android/media/videoeditor/MediaProperties.java
+++ b/media/java/android/media/videoeditor/MediaProperties.java
@@ -29,6 +29,7 @@
* Supported heights
*/
public static final int HEIGHT_144 = 144;
+ public static final int HEIGHT_288 = 288;
public static final int HEIGHT_360 = 360;
public static final int HEIGHT_480 = 480;
public static final int HEIGHT_720 = 720;
@@ -82,7 +83,8 @@
@SuppressWarnings({"unchecked"})
private static final Pair<Integer, Integer>[] ASPECT_RATIO_11_9_RESOLUTIONS =
new Pair[] {
- new Pair<Integer, Integer>(176, HEIGHT_144)
+ new Pair<Integer, Integer>(176, HEIGHT_144),
+ new Pair<Integer, Integer>(352, HEIGHT_288)
};
@SuppressWarnings({"unchecked"})
diff --git a/media/java/android/media/videoeditor/VideoEditorImpl.java b/media/java/android/media/videoeditor/VideoEditorImpl.java
index a6b4544..7e1f73a 100755
--- a/media/java/android/media/videoeditor/VideoEditorImpl.java
+++ b/media/java/android/media/videoeditor/VideoEditorImpl.java
@@ -42,6 +42,9 @@
import android.util.Xml;
import android.view.Surface;
import android.view.SurfaceHolder;
+import android.os.Debug;
+import android.os.SystemProperties;
+import android.os.Environment;
/**
* The VideoEditor implementation {@hide}
@@ -134,6 +137,7 @@
*/
private MediaArtistNativeHelper mMANativeHelper;
private boolean mPreviewInProgress = false;
+ private final boolean mMallocDebug;
/**
* Constructor
@@ -142,6 +146,18 @@
* related to the project
*/
public VideoEditorImpl(String projectPath) throws IOException {
+ String s;
+ s = SystemProperties.get("libc.debug.malloc");
+ if (s.equals("1")) {
+ mMallocDebug = true;
+ try {
+ dumpHeap("HeapAtStart");
+ } catch (Exception ex) {
+ Log.e(TAG, "dumpHeap returned error in constructor");
+ }
+ } else {
+ mMallocDebug = false;
+ }
mLock = new Semaphore(1, true);
mMANativeHelper = new MediaArtistNativeHelper(projectPath, mLock, this);
mProjectPath = projectPath;
@@ -373,6 +389,8 @@
switch (height) {
case MediaProperties.HEIGHT_144:
break;
+ case MediaProperties.HEIGHT_288:
+ break;
case MediaProperties.HEIGHT_360:
break;
case MediaProperties.HEIGHT_480:
@@ -709,6 +727,13 @@
unlock();
}
}
+ if (mMallocDebug) {
+ try {
+ dumpHeap("HeapAtEnd");
+ } catch (Exception ex) {
+ Log.e(TAG, "dumpHeap returned error in release");
+ }
+ }
}
/*
@@ -1885,4 +1910,32 @@
}
mLock.release();
}
+
+ /**
+ * Dumps the heap memory usage information to file
+ */
+ private static void dumpHeap (String filename) throws Exception {
+ /* Cleanup as much as possible before dump
+ */
+ System.gc();
+ System.runFinalization();
+ Thread.sleep(1000);
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ String extDir =
+ Environment.getExternalStorageDirectory().toString();
+
+ /* If dump file already exists, then delete it first
+ */
+ if ((new File(extDir + "/" + filename + ".dump")).exists()) {
+ (new File(extDir + "/" + filename + ".dump")).delete();
+ }
+ /* Dump native heap
+ */
+ FileOutputStream ost =
+ new FileOutputStream(extDir + "/" + filename + ".dump");
+ Debug.dumpNativeHeap(ost.getFD());
+ ost.close();
+ }
+ }
}
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index 23081f8..9fe0266 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -1707,12 +1707,19 @@
if (aFramingCtx->FramingYuv != M4OSA_NULL )
{
- if (aFramingCtx->FramingYuv->pac_data != M4OSA_NULL) {
- M4OSA_free((M4OSA_MemAddr32)aFramingCtx->FramingYuv->pac_data);
- aFramingCtx->FramingYuv->pac_data = M4OSA_NULL;
+ if (aFramingCtx->FramingYuv[0].pac_data != M4OSA_NULL) {
+ M4OSA_free((M4OSA_MemAddr32)aFramingCtx->FramingYuv[0].pac_data);
+ aFramingCtx->FramingYuv[0].pac_data = M4OSA_NULL;
}
- }
- if (aFramingCtx->FramingYuv != M4OSA_NULL) {
+ if (aFramingCtx->FramingYuv[1].pac_data != M4OSA_NULL) {
+ M4OSA_free((M4OSA_MemAddr32)aFramingCtx->FramingYuv[1].pac_data);
+ aFramingCtx->FramingYuv[1].pac_data = M4OSA_NULL;
+ }
+ if (aFramingCtx->FramingYuv[2].pac_data != M4OSA_NULL) {
+ M4OSA_free((M4OSA_MemAddr32)aFramingCtx->FramingYuv[2].pac_data);
+ aFramingCtx->FramingYuv[2].pac_data = M4OSA_NULL;
+ }
+
M4OSA_free((M4OSA_MemAddr32)aFramingCtx->FramingYuv);
aFramingCtx->FramingYuv = M4OSA_NULL;
}
diff --git a/media/libstagefright/DRMExtractor.cpp b/media/libstagefright/DRMExtractor.cpp
index 647cf43..2809df5 100644
--- a/media/libstagefright/DRMExtractor.cpp
+++ b/media/libstagefright/DRMExtractor.cpp
@@ -243,6 +243,7 @@
mDrmManagerClient(NULL) {
mOriginalExtractor = MediaExtractor::Create(source, mime);
mOriginalExtractor->setDrmFlag(true);
+ mOriginalExtractor->getMetaData()->setInt32(kKeyIsDRM, 1);
source->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
}
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index d4651c4..23bad5b 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -67,6 +67,7 @@
mime, confidence);
}
+ bool isDrm = false;
// DRM MIME type syntax is "drm+type+original" where
// type is "es_based" or "container_based" and
// original is the content's cleartext MIME type
@@ -78,39 +79,45 @@
}
++originalMime;
if (!strncmp(mime, "drm+es_based+", 13)) {
+ // DRMExtractor sets container metadata kKeyIsDRM to 1
return new DRMExtractor(source, originalMime);
} else if (!strncmp(mime, "drm+container_based+", 20)) {
mime = originalMime;
+ isDrm = true;
} else {
return NULL;
}
}
+ MediaExtractor *ret = NULL;
if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)
|| !strcasecmp(mime, "audio/mp4")) {
- return new MPEG4Extractor(source);
+ ret = new MPEG4Extractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
- return new MP3Extractor(source, meta);
+ ret = new MP3Extractor(source, meta);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)
|| !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
- return new AMRExtractor(source);
+ ret = new AMRExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
- return new FLACExtractor(source);
+ ret = new FLACExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV)) {
- return new WAVExtractor(source);
+ ret = new WAVExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG)) {
- return new OggExtractor(source);
+ ret = new OggExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA)) {
- return new MatroskaExtractor(source);
+ ret = new MatroskaExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
- return new MPEG2TSExtractor(source);
+ ret = new MPEG2TSExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WVM)) {
- return new WVMExtractor(source);
+ ret = new WVMExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS)) {
- return new AACExtractor(source);
+ ret = new AACExtractor(source);
+ }
+ if (ret != NULL && isDrm) {
+ ret->getMetaData()->setInt32(kKeyIsDRM, 1);
}
- return NULL;
+ return ret;
}
} // namespace android
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 600de7c..ea3b801 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -272,6 +272,12 @@
return NULL;
}
+ int32_t drm = 0;
+ if (mExtractor->getMetaData()->findInt32(kKeyIsDRM, &drm) && drm != 0) {
+ LOGE("frame grab not allowed.");
+ return NULL;
+ }
+
size_t n = mExtractor->countTracks();
size_t i;
for (i = 0; i < n; ++i) {
diff --git a/media/libstagefright/colorconversion/ColorConverter.cpp b/media/libstagefright/colorconversion/ColorConverter.cpp
index d518c97..3b92e5d 100644
--- a/media/libstagefright/colorconversion/ColorConverter.cpp
+++ b/media/libstagefright/colorconversion/ColorConverter.cpp
@@ -187,7 +187,7 @@
status_t ColorConverter::convertYUV420Planar(
const BitmapParams &src, const BitmapParams &dst) {
- if (!((dst.mWidth & 3) == 0
+ if (!((dst.mWidth & 1) == 0
&& (src.mCropLeft & 1) == 0
&& src.cropWidth() == dst.cropWidth()
&& src.cropHeight() == dst.cropHeight())) {
diff --git a/native/include/android/input.h b/native/include/android/input.h
index d516037..f19e8be 100644
--- a/native/include/android/input.h
+++ b/native/include/android/input.h
@@ -288,6 +288,15 @@
* the last hover move event.
*/
AMOTION_EVENT_ACTION_HOVER_MOVE = 7,
+
+ /* The motion event contains relative vertical and/or horizontal scroll offsets.
+ * Use getAxisValue to retrieve the information from AMOTION_EVENT_AXIS_VSCROLL
+ * and AMOTION_EVENT_AXIS_HSCROLL.
+ * The pointer may or may not be down when this event is dispatched.
+ * This action is always delivered to the winder under the pointer, which
+ * may not be the window currently touched.
+ */
+ AMOTION_EVENT_ACTION_SCROLL = 8,
};
/*
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 9017ca3..95fd62d 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -748,8 +748,10 @@
}
@Override
- protected synchronized void entryEvicted(String key, Bundle value) {
- mCacheFullyMatchesDisk = false;
+ protected void entryRemoved(boolean evicted, String key, Bundle oldValue, Bundle newValue) {
+ if (evicted) {
+ mCacheFullyMatchesDisk = false;
+ }
}
/**
diff --git a/packages/WAPPushManager/Android.mk b/packages/WAPPushManager/Android.mk
new file mode 100644
index 0000000..c1d8f4b
--- /dev/null
+++ b/packages/WAPPushManager/Android.mk
@@ -0,0 +1,20 @@
+# Copyright 2007-2008 The Android Open Source Project
+
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := WAPPushManager
+
+LOCAL_STATIC_JAVA_LIBRARIES += android-common
+
+LOCAL_PROGUARD_FLAGS := -include $(LOCAL_PATH)/proguard.flags
+
+include $(BUILD_PACKAGE)
+
+# This finds and builds the test apk as well, so a single make does both.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/WAPPushManager/AndroidManifest.xml b/packages/WAPPushManager/AndroidManifest.xml
new file mode 100644
index 0000000..89e9d6a
--- /dev/null
+++ b/packages/WAPPushManager/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2007-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.
+ * 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.smspush">
+
+ <permission android:name="com.android.smspush.WAPPUSH_MANAGER_BIND"
+ android:protectionLevel="signatureOrSystem" />
+
+ <original-package android:name="com.android.smspush" />
+ <application>
+ <service android:name=".WapPushManager"
+ android:permission="com.android.smspush.WAPPUSH_MANAGER_BIND"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="com.android.internal.telephony.IWapPushManager"></action>
+ </intent-filter>
+ </service>
+ </application>
+
+
+</manifest>
diff --git a/packages/WAPPushManager/CleanSpec.mk b/packages/WAPPushManager/CleanSpec.mk
new file mode 100644
index 0000000..b84e1b6
--- /dev/null
+++ b/packages/WAPPushManager/CleanSpec.mk
@@ -0,0 +1,49 @@
+# Copyright (C) 2007 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.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list. These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list. E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/packages/WAPPushManager/MODULE_LICENSE_APACHE2 b/packages/WAPPushManager/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/packages/WAPPushManager/MODULE_LICENSE_APACHE2
diff --git a/packages/WAPPushManager/NOTICE b/packages/WAPPushManager/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/packages/WAPPushManager/NOTICE
@@ -0,0 +1,190 @@
+
+ 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
+
diff --git a/packages/WAPPushManager/proguard.flags b/packages/WAPPushManager/proguard.flags
new file mode 100644
index 0000000..d09887b
--- /dev/null
+++ b/packages/WAPPushManager/proguard.flags
@@ -0,0 +1,18 @@
+
+#apply method is dynamically referenced by the reflection class.
+-keep class android.app.ContextImpl$SharedPreferencesImpl$EditorImpl {
+ void apply();
+}
+-keep class android.content.SharedPreferences$Editor {
+ void apply();
+}
+
+#WapPushManager is referenced only by AndroidManifest.xml
+-keep class com.android.smspush.WapPushManager {
+#CTS module method
+ public boolean isDataExist(java.lang.String, java.lang.String,
+ java.lang.String, java.lang.String);
+ public boolean verifyData(java.lang.String, java.lang.String,
+ java.lang.String, java.lang.String, int, boolean, boolean);
+}
+
diff --git a/packages/WAPPushManager/src/com/android/smspush/WapPushManager.java b/packages/WAPPushManager/src/com/android/smspush/WapPushManager.java
new file mode 100644
index 0000000..96e0377
--- /dev/null
+++ b/packages/WAPPushManager/src/com/android/smspush/WapPushManager.java
@@ -0,0 +1,424 @@
+/*
+ * Copyright (C) 2010 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.smspush;
+
+import android.app.Service;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.telephony.IWapPushManager;
+import com.android.internal.telephony.WapPushManagerParams;
+
+/**
+ * The WapPushManager service is implemented to process incoming
+ * WAP Push messages and to maintain the Receiver Application/Application
+ * ID mapping. The WapPushManager runs as a system service, and only the
+ * WapPushManager can update the WAP Push message and Receiver Application
+ * mapping (Application ID Table). When the device receives an SMS WAP Push
+ * message, the WapPushManager looks up the Receiver Application name in
+ * Application ID Table. If an application is found, the application is
+ * launched using its full component name instead of broadcasting an implicit
+ * Intent. If a Receiver Application is not found in the Application ID
+ * Table or the WapPushManager returns a process-further value, the
+ * telephony stack will process the message using existing message processing
+ * flow, and broadcast an implicit Intent.
+ */
+public class WapPushManager extends Service {
+
+ private static final String LOG_TAG = "WAP PUSH";
+ private static final String DATABASE_NAME = "wappush.db";
+ private static final String APPID_TABLE_NAME = "appid_tbl";
+
+ /**
+ * Version number must be incremented when table structure is changed.
+ */
+ private static final int WAP_PUSH_MANAGER_VERSION = 1;
+ private static final boolean DEBUG_SQL = false;
+ private static final boolean LOCAL_LOGV = false;
+
+ /**
+ * Inner class that deals with application ID table
+ */
+ private class WapPushManDBHelper extends SQLiteOpenHelper {
+ WapPushManDBHelper(Context context) {
+ super(context, DATABASE_NAME, null, WAP_PUSH_MANAGER_VERSION);
+ if (LOCAL_LOGV) Log.v(LOG_TAG, "helper instance created.");
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ if (LOCAL_LOGV) Log.v(LOG_TAG, "db onCreate.");
+ String sql = "CREATE TABLE " + APPID_TABLE_NAME + " ("
+ + "id INTEGER PRIMARY KEY, "
+ + "x_wap_application TEXT, "
+ + "content_type TEXT, "
+ + "package_name TEXT, "
+ + "class_name TEXT, "
+ + "app_type INTEGER, "
+ + "need_signature INTEGER, "
+ + "further_processing INTEGER, "
+ + "install_order INTEGER "
+ + ")";
+
+ if (DEBUG_SQL) Log.v(LOG_TAG, "sql: " + sql);
+ db.execSQL(sql);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db,
+ int oldVersion, int newVersion) {
+ // TODO: when table structure is changed, need to dump and restore data.
+ /*
+ db.execSQL(
+ "drop table if exists "+APPID_TABLE_NAME);
+ onCreate(db);
+ */
+ Log.w(LOG_TAG, "onUpgrade is not implemented yet. do nothing.");
+ }
+
+ protected class queryData {
+ public String packageName;
+ public String className;
+ int appType;
+ int needSignature;
+ int furtherProcessing;
+ int installOrder;
+ }
+
+ /**
+ * Query the latest receiver application info with supplied application ID and
+ * content type.
+ * @param app_id application ID to look up
+ * @param content_type content type to look up
+ */
+ protected queryData queryLastApp(SQLiteDatabase db,
+ String app_id, String content_type) {
+ String sql = "select install_order, package_name, class_name, "
+ + " app_type, need_signature, further_processing"
+ + " from " + APPID_TABLE_NAME
+ + " where x_wap_application=\'" + app_id + "\'"
+ + " and content_type=\'" + content_type + "\'"
+ + " order by install_order desc";
+ if (DEBUG_SQL) Log.v(LOG_TAG, "sql: " + sql);
+ Cursor cur = db.rawQuery(sql, null);
+ queryData ret = null;
+
+ if (cur.moveToNext()) {
+ ret = new queryData();
+ ret.installOrder = cur.getInt(cur.getColumnIndex("install_order"));
+ ret.packageName = cur.getString(cur.getColumnIndex("package_name"));
+ ret.className = cur.getString(cur.getColumnIndex("class_name"));
+ ret.appType = cur.getInt(cur.getColumnIndex("app_type"));
+ ret.needSignature = cur.getInt(cur.getColumnIndex("need_signature"));
+ ret.furtherProcessing = cur.getInt(cur.getColumnIndex("further_processing"));
+ }
+ cur.close();
+ return ret;
+ }
+
+ }
+
+ /**
+ * The exported API implementations class
+ */
+ private class IWapPushManagerStub extends IWapPushManager.Stub {
+ public Context mContext;
+
+ public IWapPushManagerStub() {
+
+ }
+
+ /**
+ * Compare the package signature with WapPushManager package
+ */
+ protected boolean signatureCheck(String package_name) {
+ PackageManager pm = mContext.getPackageManager();
+ int match = pm.checkSignatures(mContext.getPackageName(), package_name);
+
+ if (LOCAL_LOGV) Log.v(LOG_TAG, "compare signature " + mContext.getPackageName()
+ + " and " + package_name + ", match=" + match);
+
+ return match == PackageManager.SIGNATURE_MATCH;
+ }
+
+ /**
+ * Returns the status value of the message processing.
+ * The message will be processed as follows:
+ * 1.Look up Application ID Table with x-wap-application-id + content type
+ * 2.Check the signature of package name that is found in the
+ * Application ID Table by using PackageManager.checkSignature
+ * 3.Trigger the Application
+ * 4.Returns the process status value.
+ */
+ public int processMessage(String app_id, String content_type, Intent intent)
+ throws RemoteException {
+ Log.d(LOG_TAG, "wpman processMsg " + app_id + ":" + content_type);
+
+ WapPushManDBHelper dbh = getDatabase(mContext);
+ SQLiteDatabase db = dbh.getReadableDatabase();
+ WapPushManDBHelper.queryData lastapp = dbh.queryLastApp(db, app_id, content_type);
+ db.close();
+
+ if (lastapp == null) {
+ Log.w(LOG_TAG, "no receiver app found for " + app_id + ":" + content_type);
+ return WapPushManagerParams.APP_QUERY_FAILED;
+ }
+ if (LOCAL_LOGV) Log.v(LOG_TAG, "starting " + lastapp.packageName
+ + "/" + lastapp.className);
+
+ if (lastapp.needSignature != 0) {
+ if (!signatureCheck(lastapp.packageName)) {
+ return WapPushManagerParams.SIGNATURE_NO_MATCH;
+ }
+ }
+
+ if (lastapp.appType == WapPushManagerParams.APP_TYPE_ACTIVITY) {
+ //Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClassName(lastapp.packageName, lastapp.className);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ try {
+ mContext.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.w(LOG_TAG, "invalid name " +
+ lastapp.packageName + "/" + lastapp.className);
+ return WapPushManagerParams.INVALID_RECEIVER_NAME;
+ }
+ } else {
+ intent.setClassName(mContext, lastapp.className);
+ intent.setComponent(new ComponentName(lastapp.packageName,
+ lastapp.className));
+ if (mContext.startService(intent) == null) {
+ Log.w(LOG_TAG, "invalid name " +
+ lastapp.packageName + "/" + lastapp.className);
+ return WapPushManagerParams.INVALID_RECEIVER_NAME;
+ }
+ }
+
+ return WapPushManagerParams.MESSAGE_HANDLED
+ | (lastapp.furtherProcessing == 1 ?
+ WapPushManagerParams.FURTHER_PROCESSING : 0);
+ }
+
+ protected boolean appTypeCheck(int app_type) {
+ if (app_type == WapPushManagerParams.APP_TYPE_ACTIVITY ||
+ app_type == WapPushManagerParams.APP_TYPE_SERVICE) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns true if adding the package succeeded.
+ */
+ public boolean addPackage(String x_app_id, String content_type,
+ String package_name, String class_name,
+ int app_type, boolean need_signature, boolean further_processing) {
+ WapPushManDBHelper dbh = getDatabase(mContext);
+ SQLiteDatabase db = dbh.getWritableDatabase();
+ WapPushManDBHelper.queryData lastapp = dbh.queryLastApp(db, x_app_id, content_type);
+ boolean ret = false;
+ boolean insert = false;
+ int sq = 0;
+
+ if (!appTypeCheck(app_type)) {
+ Log.w(LOG_TAG, "invalid app_type " + app_type + ". app_type must be "
+ + WapPushManagerParams.APP_TYPE_ACTIVITY + " or "
+ + WapPushManagerParams.APP_TYPE_SERVICE);
+ return false;
+ }
+
+ if (lastapp == null) {
+ insert = true;
+ sq = 0;
+ } else if (!lastapp.packageName.equals(package_name) ||
+ !lastapp.className.equals(class_name)) {
+ insert = true;
+ sq = lastapp.installOrder + 1;
+ }
+
+ if (insert) {
+ ContentValues values = new ContentValues();
+
+ values.put("x_wap_application", x_app_id);
+ values.put("content_type", content_type);
+ values.put("package_name", package_name);
+ values.put("class_name", class_name);
+ values.put("app_type", app_type);
+ values.put("need_signature", need_signature ? 1 : 0);
+ values.put("further_processing", further_processing ? 1 : 0);
+ values.put("install_order", sq);
+ db.insert(APPID_TABLE_NAME, null, values);
+ if (LOCAL_LOGV) Log.v(LOG_TAG, "add:" + x_app_id + ":" + content_type
+ + " " + package_name + "." + class_name
+ + ", newsq:" + sq);
+ ret = true;
+ }
+
+ db.close();
+
+ return ret;
+ }
+
+ /**
+ * Returns true if updating the package succeeded.
+ */
+ public boolean updatePackage(String x_app_id, String content_type,
+ String package_name, String class_name,
+ int app_type, boolean need_signature, boolean further_processing) {
+
+ if (!appTypeCheck(app_type)) {
+ Log.w(LOG_TAG, "invalid app_type " + app_type + ". app_type must be "
+ + WapPushManagerParams.APP_TYPE_ACTIVITY + " or "
+ + WapPushManagerParams.APP_TYPE_SERVICE);
+ return false;
+ }
+
+ WapPushManDBHelper dbh = getDatabase(mContext);
+ SQLiteDatabase db = dbh.getWritableDatabase();
+ WapPushManDBHelper.queryData lastapp = dbh.queryLastApp(db, x_app_id, content_type);
+
+ if (lastapp == null) {
+ db.close();
+ return false;
+ }
+
+ ContentValues values = new ContentValues();
+ String where = "x_wap_application=\'" + x_app_id + "\'"
+ + " and content_type=\'" + content_type + "\'"
+ + " and install_order=" + lastapp.installOrder;
+
+ values.put("package_name", package_name);
+ values.put("class_name", class_name);
+ values.put("app_type", app_type);
+ values.put("need_signature", need_signature ? 1 : 0);
+ values.put("further_processing", further_processing ? 1 : 0);
+
+ int num = db.update(APPID_TABLE_NAME, values, where, null);
+ if (LOCAL_LOGV) Log.v(LOG_TAG, "update:" + x_app_id + ":" + content_type + " "
+ + package_name + "." + class_name
+ + ", sq:" + lastapp.installOrder);
+
+ db.close();
+
+ return num > 0;
+ }
+
+ /**
+ * Returns true if deleting the package succeeded.
+ */
+ public boolean deletePackage(String x_app_id, String content_type,
+ String package_name, String class_name) {
+ WapPushManDBHelper dbh = getDatabase(mContext);
+ SQLiteDatabase db = dbh.getWritableDatabase();
+ String where = "x_wap_application=\'" + x_app_id + "\'"
+ + " and content_type=\'" + content_type + "\'"
+ + " and package_name=\'" + package_name + "\'"
+ + " and class_name=\'" + class_name + "\'";
+ int num_removed = db.delete(APPID_TABLE_NAME, where, null);
+
+ db.close();
+ if (LOCAL_LOGV) Log.v(LOG_TAG, "deleted " + num_removed + " rows:"
+ + x_app_id + ":" + content_type + " "
+ + package_name + "." + class_name);
+ return num_removed > 0;
+ }
+ };
+
+
+ /**
+ * Linux IPC Binder
+ */
+ private final IWapPushManagerStub mBinder = new IWapPushManagerStub();
+
+ /**
+ * Default constructor
+ */
+ public WapPushManager() {
+ super();
+ mBinder.mContext = this;
+ }
+
+ @Override
+ public IBinder onBind(Intent arg0) {
+ return mBinder;
+ }
+
+ /**
+ * Application ID database instance
+ */
+ private WapPushManDBHelper mDbHelper = null;
+ protected WapPushManDBHelper getDatabase(Context context) {
+ if (mDbHelper == null) {
+ if (LOCAL_LOGV) Log.v(LOG_TAG, "create new db inst.");
+ mDbHelper = new WapPushManDBHelper(context);
+ }
+ return mDbHelper;
+ }
+
+
+ /**
+ * This method is used for testing
+ */
+ public boolean verifyData(String x_app_id, String content_type,
+ String package_name, String class_name,
+ int app_type, boolean need_signature, boolean further_processing) {
+ WapPushManDBHelper dbh = getDatabase(this);
+ SQLiteDatabase db = dbh.getReadableDatabase();
+ WapPushManDBHelper.queryData lastapp = dbh.queryLastApp(db, x_app_id, content_type);
+
+ db.close();
+
+ if (lastapp == null) return false;
+
+ if (lastapp.packageName.equals(package_name)
+ && lastapp.className.equals(class_name)
+ && lastapp.appType == app_type
+ && lastapp.needSignature == (need_signature ? 1 : 0)
+ && lastapp.furtherProcessing == (further_processing ? 1 : 0)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * This method is used for testing
+ */
+ public boolean isDataExist(String x_app_id, String content_type,
+ String package_name, String class_name) {
+ WapPushManDBHelper dbh = getDatabase(this);
+ SQLiteDatabase db = dbh.getReadableDatabase();
+ boolean ret = dbh.queryLastApp(db, x_app_id, content_type) != null;
+
+ db.close();
+ return ret;
+ }
+
+}
+
diff --git a/packages/WAPPushManager/tests/Android.mk b/packages/WAPPushManager/tests/Android.mk
new file mode 100644
index 0000000..0a95b52
--- /dev/null
+++ b/packages/WAPPushManager/tests/Android.mk
@@ -0,0 +1,38 @@
+# Copyright 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.
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += \
+ src/com/android/smspush/unitTests/IDataVerify.aidl
+
+
+# Notice that we don't have to include the src files of Email because, by
+# running the tests using an instrumentation targeting Eamil, we
+# automatically get all of its classes loaded into our environment.
+
+LOCAL_PACKAGE_NAME := WAPPushManagerTests
+
+LOCAL_INSTRUMENTATION_FOR := WAPPushManager
+
+include $(BUILD_PACKAGE)
+
diff --git a/packages/WAPPushManager/tests/AndroidManifest.xml b/packages/WAPPushManager/tests/AndroidManifest.xml
new file mode 100644
index 0000000..da7634f
--- /dev/null
+++ b/packages/WAPPushManager/tests/AndroidManifest.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+ 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.smspush.unitTests">
+
+
+ <uses-permission android:name="com.android.smspush.WAPPUSH_MANAGER_BIND" />
+ <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />
+ <!--testing.../-->
+ <application android:icon="@drawable/icon" android:label="wappush test">
+ <uses-library android:name="android.test.runner" />
+ <activity android:name=".ClientTest"
+ android:label="wappush test">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <receiver android:name=".DrmReceiver" android:enabled="true">
+ <intent-filter>
+ <action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
+ <data android:mimeType="application/vnd.oma.drm.rights+xml" />
+ <data android:value="application/vnd.oma.drm.rights+wbxml" />
+ </intent-filter>
+ </receiver>
+
+ <service android:enabled="true" android:name=".ReceiverService"
+ android:exported="true"/>
+
+ <activity android:name=".ReceiverActivity"
+ android:exported="true" android:label="test receiver" />
+
+ <service android:name=".DataVerify"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="com.android.smspush.unitTests.IDataVerify" />
+ </intent-filter>
+ </service>
+
+ </application>
+
+ <!--
+ This declares that this application uses the instrumentation test runner targeting
+ the package of com.android.smspush. To run the tests use the command:
+ "adb shell am instrument -w
+ com.android.smspush.unitTests/android.test.InstrumentationTestRunner"
+ -->
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.smspush"
+ android:label="Tests for WAPPushManager"/>
+
+</manifest>
+
diff --git a/packages/WAPPushManager/tests/res/drawable-hdpi/icon.png b/packages/WAPPushManager/tests/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..8074c4c
--- /dev/null
+++ b/packages/WAPPushManager/tests/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/packages/WAPPushManager/tests/res/drawable-ldpi/icon.png b/packages/WAPPushManager/tests/res/drawable-ldpi/icon.png
new file mode 100644
index 0000000..1095584
--- /dev/null
+++ b/packages/WAPPushManager/tests/res/drawable-ldpi/icon.png
Binary files differ
diff --git a/packages/WAPPushManager/tests/res/drawable-mdpi/icon.png b/packages/WAPPushManager/tests/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..a07c69f
--- /dev/null
+++ b/packages/WAPPushManager/tests/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/packages/WAPPushManager/tests/res/layout/main.xml b/packages/WAPPushManager/tests/res/layout/main.xml
new file mode 100644
index 0000000..c7bdbb2
--- /dev/null
+++ b/packages/WAPPushManager/tests/res/layout/main.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+<AbsoluteLayout
+android:id="@+id/widget133"
+android:layout_width="fill_parent"
+android:layout_height="fill_parent"
+xmlns:android="http://schemas.android.com/apk/res/android"
+>
+<EditText
+android:id="@+id/app_id"
+android:layout_width="wrap_content"
+android:layout_height="wrap_content"
+android:text="10"
+android:textSize="18sp"
+android:layout_x="0px"
+android:layout_y="26px"
+>
+</EditText>
+<EditText
+android:id="@+id/cont"
+android:layout_width="wrap_content"
+android:layout_height="wrap_content"
+android:text="20"
+android:textSize="18sp"
+android:layout_x="47px"
+android:layout_y="26px"
+>
+</EditText>
+<EditText
+android:id="@+id/pkg"
+android:layout_width="125px"
+android:layout_height="wrap_content"
+android:text="pkg"
+android:textSize="18sp"
+android:layout_x="0px"
+android:layout_y="81px"
+>
+</EditText>
+<EditText
+android:id="@+id/cls"
+android:layout_width="173px"
+android:layout_height="wrap_content"
+android:text="cls"
+android:textSize="18sp"
+android:layout_x="147px"
+android:layout_y="81px"
+>
+</EditText>
+<Button
+android:id="@+id/addpkg"
+android:layout_width="182px"
+android:layout_height="wrap_content"
+android:text="add/update package"
+android:layout_x="15px"
+android:layout_y="225px"
+>
+</Button>
+<TextView
+android:id="@+id/widget52"
+android:layout_width="wrap_content"
+android:layout_height="wrap_content"
+android:text="input app_id, cont_type, pkg, cls"
+android:textSize="18sp"
+android:layout_x="0px"
+android:layout_y="0px"
+>
+</TextView>
+<Button
+android:id="@+id/procmsg"
+android:layout_width="109px"
+android:layout_height="wrap_content"
+android:text="process msg"
+android:layout_x="197px"
+android:layout_y="361px"
+>
+</Button>
+<RadioGroup
+android:id="@+id/widget137"
+android:layout_width="83px"
+android:layout_height="80px"
+android:orientation="vertical"
+android:layout_x="19px"
+android:layout_y="137px"
+>
+<RadioButton
+android:id="@+id/act"
+android:layout_width="182px"
+android:layout_height="wrap_content"
+android:text="act"
+android:checked="true"
+>
+</RadioButton>
+<RadioButton
+android:id="@+id/svc"
+android:layout_width="wrap_content"
+android:layout_height="wrap_content"
+android:text="svc"
+>
+</RadioButton>
+</RadioGroup>
+<Button
+android:id="@+id/delpkg"
+android:layout_width="174px"
+android:layout_height="wrap_content"
+android:text="delete pkg"
+android:layout_x="14px"
+android:layout_y="283px"
+>
+</Button>
+<EditText
+android:id="@+id/pdu"
+android:layout_width="186px"
+android:layout_height="83px"
+android:text="0006080302030aaf02905c030d6a0085070373616d706c6540646f636f6d6f2e6e652e6a700005c3072009102012345601"
+android:textSize="18sp"
+android:layout_x="10px"
+android:layout_y="341px"
+>
+</EditText>
+<CheckBox
+android:id="@+id/ftr"
+android:layout_width="wrap_content"
+android:layout_height="wrap_content"
+android:text="ftr_proc"
+android:layout_x="143px"
+android:layout_y="181px"
+>
+</CheckBox>
+<CheckBox
+android:id="@+id/sig"
+android:layout_width="wrap_content"
+android:layout_height="wrap_content"
+android:text="nd_sig"
+android:checked="true"
+android:layout_x="142px"
+android:layout_y="140px"
+>
+</CheckBox>
+</AbsoluteLayout>
diff --git a/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/ClientTest.java b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/ClientTest.java
new file mode 100644
index 0000000..78fd174
--- /dev/null
+++ b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/ClientTest.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2010 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.smspush.unitTests;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.RadioButton;
+
+import com.android.internal.telephony.IWapPushManager;
+import com.android.internal.telephony.WapPushManagerParams;
+import com.android.internal.telephony.WapPushOverSms;
+import com.android.internal.util.HexDump;
+import com.android.smspush.WapPushManager;
+
+/**
+ * WapPushManager test application
+ */
+public class ClientTest extends Activity {
+ private static final String LOG_TAG = "WAP PUSH";
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ Button addpbtn = (Button) findViewById(R.id.addpkg);
+ Button procbtn = (Button) findViewById(R.id.procmsg);
+ Button delbtn = (Button) findViewById(R.id.delpkg);
+
+ Log.v(LOG_TAG, "activity created!!");
+
+ addpbtn.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ EditText app_id = (EditText) findViewById(R.id.app_id);
+ EditText cont = (EditText) findViewById(R.id.cont);
+ EditText pkg = (EditText) findViewById(R.id.pkg);
+ EditText cls = (EditText) findViewById(R.id.cls);
+ RadioButton act = (RadioButton) findViewById(R.id.act);
+ CheckBox sig = (CheckBox) findViewById(R.id.sig);
+ CheckBox ftr = (CheckBox) findViewById(R.id.ftr);
+
+ try {
+ if (!mWapPushMan.addPackage(
+ app_id.getText().toString(),
+ cont.getText().toString(),
+ pkg.getText().toString(),
+ cls.getText().toString(),
+ act.isChecked() ? WapPushManagerParams.APP_TYPE_ACTIVITY :
+ WapPushManagerParams.APP_TYPE_SERVICE,
+ sig.isChecked(), ftr.isChecked())) {
+
+ Log.w(LOG_TAG, "remote add pkg failed...");
+ mWapPushMan.updatePackage(
+ app_id.getText().toString(),
+ cont.getText().toString(),
+ pkg.getText().toString(),
+ cls.getText().toString(),
+ act.isChecked() ? WapPushManagerParams.APP_TYPE_ACTIVITY :
+ WapPushManagerParams.APP_TYPE_SERVICE,
+ sig.isChecked(), ftr.isChecked());
+ }
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "remote func failed...");
+ }
+ }
+ });
+
+ delbtn.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ EditText app_id = (EditText) findViewById(R.id.app_id);
+ EditText cont = (EditText) findViewById(R.id.cont);
+ EditText pkg = (EditText) findViewById(R.id.pkg);
+ EditText cls = (EditText) findViewById(R.id.cls);
+ // CheckBox delall = (CheckBox) findViewById(R.id.delall);
+ // Log.d(LOG_TAG, "button clicked");
+
+ try {
+ mWapPushMan.deletePackage(
+ app_id.getText().toString(),
+ cont.getText().toString(),
+ pkg.getText().toString(),
+ cls.getText().toString());
+ // delall.isChecked());
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "remote func failed...");
+ }
+ }
+ });
+
+ procbtn.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ EditText pdu = (EditText) findViewById(R.id.pdu);
+ EditText app_id = (EditText) findViewById(R.id.app_id);
+ EditText cont = (EditText) findViewById(R.id.cont);
+
+ // WapPushOverSms wap = new WapPushOverSms();
+ // wap.dispatchWapPdu(strToHex(pdu.getText().toString()));
+ try {
+ Intent intent = new Intent();
+ intent.putExtra("transactionId", 0);
+ intent.putExtra("pduType", 6);
+ intent.putExtra("header",
+ HexDump.hexStringToByteArray(pdu.getText().toString()));
+ intent.putExtra("data",
+ HexDump.hexStringToByteArray(pdu.getText().toString()));
+
+ mWapPushMan.processMessage(
+ app_id.getText().toString(),
+ cont.getText().toString(),
+ intent);
+ //HexDump.hexStringToByteArray(pdu.getText().toString()), 0, 6, 5, 5);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "remote func failed...");
+ }
+ }
+ });
+ }
+
+ private IWapPushManager mWapPushMan;
+ private ServiceConnection conn = new ServiceConnection() {
+ public void onServiceDisconnected(ComponentName name) {
+ mWapPushMan = null;
+ Log.v(LOG_TAG, "service disconnected.");
+ }
+
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ mWapPushMan = IWapPushManager.Stub.asInterface(service);
+ Log.v(LOG_TAG, "service connected.");
+ }
+ };
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ Log.v(LOG_TAG, "onStart bind WAPPushManager service "
+ + IWapPushManager.class.getName());
+ this.bindService(new Intent(IWapPushManager.class.getName()), conn,
+ Context.BIND_AUTO_CREATE);
+ Log.v(LOG_TAG, "bind service done.");
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ this.unbindService(conn);
+ }
+
+}
diff --git a/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/DataVerify.java b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/DataVerify.java
new file mode 100644
index 0000000..ef491fd
--- /dev/null
+++ b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/DataVerify.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2010 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.smspush.unitTests;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+import android.util.Log;
+
+import com.android.internal.util.HexDump;
+
+/**
+ * To verify that receiver application receives correct body data.
+ */
+public class DataVerify extends Service {
+ private static final String LOG_TAG = "WAP PUSH";
+ private static final int TIME_WAIT = 100;
+ private static final int WAIT_COUNT = 100;
+ private static byte[] mLastReceivedPdu = null;
+ private static boolean sDataSet = false;
+
+ private class IDataVerifyStub extends IDataVerify.Stub {
+ public Context mContext;
+
+ public IDataVerifyStub() {
+ }
+
+ boolean arrayCompare(byte[] arr1, byte[] arr2) {
+ int i;
+
+ if (arr1 == null || arr2 == null) {
+ if (arr1 == null) {
+ Log.w(LOG_TAG, "arr1 is null");
+ } else {
+ Log.w(LOG_TAG, "arr2 is null");
+ }
+ return false;
+ }
+
+ if (arr1.length != arr2.length) {
+ return false;
+ }
+
+ for (i = 0; i < arr1.length; i++) {
+ if (arr1[i] != arr2[i]) return false;
+ }
+ return true;
+ }
+
+ /**
+ * Compare pdu and received pdu
+ */
+ public synchronized boolean verifyData(byte[] pdu) {
+ int cnt = 0;
+
+ while (!sDataSet) {
+ // wait for the activity receive data.
+ try {
+ Thread.sleep(TIME_WAIT);
+ if (cnt++ > WAIT_COUNT) {
+ // don't wait more than 10 sec.
+ return false;
+ }
+ } catch (InterruptedException e) {}
+ }
+
+ Log.v(LOG_TAG, "verify pdu");
+ boolean ret = arrayCompare(pdu, mLastReceivedPdu);
+ return ret;
+ }
+
+ /**
+ * Clear the old data. This method must be called before starting the test
+ */
+ public void resetData() {
+ mLastReceivedPdu = null;
+ sDataSet = false;
+ }
+ }
+
+ private final IDataVerifyStub binder = new IDataVerifyStub();
+
+ /**
+ * Constructor
+ */
+ public DataVerify() {
+ }
+
+ /**
+ * Receiver application must call this method when it receives the wap push message
+ */
+ public static void SetLastReceivedPdu(byte[] pdu) {
+ mLastReceivedPdu = pdu;
+ sDataSet = true;
+ }
+
+ @Override
+ public IBinder onBind(Intent arg0) {
+ return binder;
+ }
+
+}
+
+
diff --git a/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/DrmReceiver.java b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/DrmReceiver.java
new file mode 100644
index 0000000..5f5f121
--- /dev/null
+++ b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/DrmReceiver.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 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.smspush.unitTests;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import com.android.internal.util.HexDump;
+
+/**
+ * A sample wap push receiver application for existing framework
+ * This class is listening for "application/vnd.oma.drm.rights+xml" message
+ */
+public class DrmReceiver extends BroadcastReceiver {
+ private static final String LOG_TAG = "WAP PUSH";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(LOG_TAG, "DrmReceiver received.");
+
+ byte[] body;
+ byte[] header;
+
+ body = intent.getByteArrayExtra("data");
+ header = intent.getByteArrayExtra("header");
+
+ Log.d(LOG_TAG, "header:");
+ Log.d(LOG_TAG, HexDump.dumpHexString(header));
+ Log.d(LOG_TAG, "body:");
+ Log.d(LOG_TAG, HexDump.dumpHexString(body));
+
+ DataVerify.SetLastReceivedPdu(body);
+ }
+
+}
+
+
diff --git a/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/IDataVerify.aidl b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/IDataVerify.aidl
new file mode 100644
index 0000000..f0670fa
--- /dev/null
+++ b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/IDataVerify.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 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.smspush.unitTests;
+
+/**
+ * Interface to receiver application data verifyer class
+ */
+interface IDataVerify {
+ /**
+ * Verify data
+ */
+ boolean verifyData(in byte[] pdu);
+
+ /**
+ * Initialize data
+ */
+ void resetData();
+}
+
diff --git a/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/ReceiverActivity.java b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/ReceiverActivity.java
new file mode 100644
index 0000000..07f55ea
--- /dev/null
+++ b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/ReceiverActivity.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 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.smspush.unitTests;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.internal.util.HexDump;
+
+/**
+ * Activity type receiver application
+ */
+public class ReceiverActivity extends Activity {
+ private static final String LOG_TAG = "WAP PUSH";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.d(LOG_TAG, "activity created!!");
+
+ Intent in = getIntent();
+ byte[] body;
+ byte[] header;
+
+ body = in.getByteArrayExtra("data");
+ header = in.getByteArrayExtra("header");
+
+ Log.d(LOG_TAG, "header:");
+ Log.d(LOG_TAG, HexDump.dumpHexString(header));
+ Log.d(LOG_TAG, "body:");
+ Log.d(LOG_TAG, HexDump.dumpHexString(body));
+
+ DataVerify.SetLastReceivedPdu(body);
+
+ finish();
+
+ }
+}
+
diff --git a/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/ReceiverService.java b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/ReceiverService.java
new file mode 100644
index 0000000..b024bf5
--- /dev/null
+++ b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/ReceiverService.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 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.smspush.unitTests;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+import android.util.Log;
+
+import com.android.internal.util.HexDump;
+
+/**
+ * Service type receiver application
+ */
+public class ReceiverService extends Service {
+ private static final String LOG_TAG = "WAP PUSH";
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ Log.d(LOG_TAG, "Receiver service created");
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ Log.d(LOG_TAG, "Receiver service started");
+
+ byte[] body;
+ byte[] header;
+ body = intent.getByteArrayExtra("data");
+ header = intent.getByteArrayExtra("header");
+
+ Log.d(LOG_TAG, "header:");
+ Log.d(LOG_TAG, HexDump.dumpHexString(header));
+ Log.d(LOG_TAG, "body:");
+ Log.d(LOG_TAG, HexDump.dumpHexString(body));
+
+ DataVerify.SetLastReceivedPdu(body);
+ return START_STICKY;
+ }
+}
+
+
diff --git a/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java
new file mode 100644
index 0000000..9b0a36b
--- /dev/null
+++ b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java
@@ -0,0 +1,2513 @@
+/*
+ * Copyright (C) 2010 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.smspush.unitTests;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.provider.Telephony.Sms.Intents;
+import android.test.ServiceTestCase;
+import android.util.Log;
+import android.util.Config;
+
+import com.android.internal.telephony.IccUtils;
+import com.android.internal.telephony.IWapPushManager;
+import com.android.internal.telephony.WapPushManagerParams;
+import com.android.internal.telephony.WspTypeDecoder;
+import com.android.internal.util.HexDump;
+import com.android.smspush.WapPushManager;
+
+import java.util.Random;
+
+/**
+ * This is a simple framework for a test of a Service. See {@link android.test.ServiceTestCase
+ * ServiceTestCase} for more information on how to write and extend service tests.
+ *
+ * To run this test, you can type:
+ * adb shell am instrument -w \
+ * -e class com.android.smspush.unitTests.WapPushTest \
+ * com.android.smspush.unitTests/android.test.InstrumentationTestRunner
+ */
+public class WapPushTest extends ServiceTestCase<WapPushManager> {
+ private static final String LOG_TAG = "WAP PUSH";
+ private static final boolean LOCAL_LOGV = false;
+ private static final int TIME_WAIT = 100;
+
+ protected int mAppIdValue = 0x8002;
+ protected String mAppIdName = "x-wap-application:*";
+ protected int mContentTypeValue = 0x030a;
+ protected String mContentTypeName = "application/vnd.wap.sic";
+
+ protected String mPackageName;
+ protected String mClassName;
+
+ protected byte[] mGsmHeader = {
+ (byte) 0x00, // sc address
+ (byte) 0x40, // TP-MTI
+ (byte) 0x04, // sender address length?
+ (byte) 0x81, (byte) 0x55, (byte) 0x45, // sender address?
+ (byte) 0x00, // data schema
+ (byte) 0x00, // proto ID
+ (byte) 0x01, (byte) 0x60, (byte) 0x12, (byte) 0x31,
+ (byte) 0x74, (byte) 0x34, (byte) 0x63 // time stamp
+ };
+
+ protected byte[] mUserDataHeader = {
+ (byte) 0x07, // UDH len
+ (byte) 0x06, // header len
+ (byte) 0x05, // port addressing type?
+ (byte) 0x00, // dummy
+ (byte) 0x0B, (byte) 0x84, // dest port
+ (byte) 0x23, (byte) 0xF0 // src port
+ };
+
+ protected byte[] mWspHeader;
+
+ protected byte[] mMessageBody = {
+ (byte) 0x00,
+ (byte) 0x01,
+ (byte) 0x02,
+ (byte) 0x03,
+ (byte) 0x04,
+ (byte) 0x05,
+ (byte) 0x06,
+ (byte) 0x07,
+ (byte) 0x08,
+ (byte) 0x09,
+ (byte) 0x0a,
+ (byte) 0x0b,
+ (byte) 0x0c,
+ (byte) 0x0d,
+ (byte) 0x0e,
+ (byte) 0x0f
+ };
+
+ protected int mWspHeaderStart;
+ protected int mWspHeaderLen;
+ protected int mWspContentTypeStart;
+
+ /**
+ * OMA application ID in binary form
+ * http://www.openmobilealliance.org/tech/omna/omna-push-app-id.aspx
+ */
+ final int[] OMA_APPLICATION_ID_VALUES = new int[] {
+ 0x00,
+ 0x01,
+ 0x02,
+ 0x03,
+ 0x04,
+ 0x05,
+ 0x06,
+ 0x07,
+ 0x08,
+ 0x09,
+ 0x0A,
+ 0x8000,
+ 0x8001,
+ 0x8002,
+ 0x8003,
+ 0x8004,
+ 0x8005,
+ 0x8006,
+ 0x8007,
+ 0x8008,
+ 0x8009,
+ 0x800B,
+ 0x8010
+ };
+
+ /**
+ * OMA application ID in string form
+ * http://www.openmobilealliance.org/tech/omna/omna-push-app-id.aspx
+ */
+ final String[] OMA_APPLICATION_ID_NAMES = new String[] {
+ "x-wap-application:*",
+ "x-wap-application:push.sia",
+ "x-wap-application:wml.ua",
+ "x-wap-application:wta.ua",
+ "x-wap-application:mms.ua",
+ "x-wap-application:push.syncml",
+ "x-wap-application:loc.ua",
+ "x-wap-application:syncml.dm",
+ "x-wap-application:drm.ua",
+ "x-wap-application:emn.ua",
+ "x-wap-application:wv.ua",
+ "x-wap-microsoft:localcontent.ua",
+ "x-wap-microsoft:IMclient.ua",
+ "x-wap-docomo:imode.mail.ua",
+ "x-wap-docomo:imode.mr.ua",
+ "x-wap-docomo:imode.mf.ua",
+ "x-motorola:location.ua",
+ "x-motorola:now.ua",
+ "x-motorola:otaprov.ua",
+ "x-motorola:browser.ua",
+ "x-motorola:splash.ua",
+ "x-wap-nai:mvsw.command",
+ "x-wap-openwave:iota.ua"
+ };
+
+ /**
+ * OMA content type in binary form
+ * http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.aspx
+ */
+ final int[] OMA_CONTENT_TYPE_VALUES = new int[] {
+ 0x00,
+ 0x01,
+ 0x02,
+ 0x03,
+ 0x04,
+ 0x05,
+ 0x06,
+ 0x07,
+ 0x08,
+ 0x09,
+ 0x0A,
+ 0x0B,
+ 0x0C,
+ 0x0D,
+ 0x0E,
+ 0x0F,
+ 0x10,
+ 0x11,
+ 0x12,
+ 0x13,
+ 0x14,
+ 0x15,
+ 0x16,
+ 0x17,
+ 0x18,
+ 0x19,
+ 0x1A,
+ 0x1B,
+ 0x1C,
+ 0x1D,
+ 0x1E,
+ 0x1F,
+ 0x20,
+ 0x21,
+ 0x22,
+ 0x23,
+ 0x24,
+ 0x25,
+ 0x26,
+ 0x27,
+ 0x28,
+ 0x29,
+ 0x2A,
+ 0x2B,
+ 0x2C,
+ 0x2D,
+ 0x2E,
+ 0x2F,
+ 0x30,
+ 0x31,
+ 0x32,
+ 0x33,
+ 0x34,
+ 0x35,
+ 0x36,
+ 0x37,
+ 0x38,
+ 0x39,
+ 0x3A,
+ 0x3B,
+ 0x3C,
+ 0x3D,
+ 0x3E,
+ 0x3F,
+ 0x40,
+ 0x41,
+ 0x42,
+ 0x43,
+ 0x44,
+ 0x45,
+ 0x46,
+ 0x47,
+ 0x48,
+ 0x49,
+ 0x4A,
+ 0x4B,
+ 0x4C,
+ 0x4D,
+ 0x4E,
+ 0x4F,
+ 0x50,
+ 0x51,
+ 0x52,
+ 0x53,
+ 0x54,
+// 0x55,
+// 0x56,
+// 0x57,
+// 0x58,
+ 0x0201,
+ 0x0202,
+ 0x0203,
+ 0x0204,
+ 0x0205,
+ 0x0206,
+ 0x0207,
+ 0x0208,
+ 0x0209,
+ 0x020A,
+ 0x020B,
+ 0x020C,
+ 0x0300,
+ 0x0301,
+ 0x0302,
+ 0x0303,
+ 0x0304,
+ 0x0305,
+ 0x0306,
+ 0x0307,
+ 0x0308,
+ 0x0309,
+ 0x030A,
+ 0x030B,
+ 0x030C,
+ 0x030D,
+ 0x030E,
+ 0x030F,
+ 0x0310,
+ 0x0311,
+ 0x0312,
+ 0x0313,
+ 0x0314,
+ 0x0315,
+ 0x0316,
+ 0x0317,
+ 0x0318,
+ 0x0319,
+ 0x031A,
+ 0x031B
+ /*0x031C,
+ 0x031D*/
+ };
+
+ /**
+ * OMA content type in string form
+ * http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.aspx
+ */
+ final String[] OMA_CONTENT_TYPE_NAMES = new String[] {
+ "*/*",
+ "text/*",
+ "text/html",
+ "text/plain",
+ "text/x-hdml",
+ "text/x-ttml",
+ "text/x-vCalendar",
+ "text/x-vCard",
+ "text/vnd.wap.wml",
+ "text/vnd.wap.wmlscript",
+ "text/vnd.wap.wta-event",
+ "multipart/*",
+ "multipart/mixed",
+ "multipart/form-data",
+ "multipart/byterantes",
+ "multipart/alternative",
+ "application/*",
+ "application/java-vm",
+ "application/x-www-form-urlencoded",
+ "application/x-hdmlc",
+ "application/vnd.wap.wmlc",
+ "application/vnd.wap.wmlscriptc",
+ "application/vnd.wap.wta-eventc",
+ "application/vnd.wap.uaprof",
+ "application/vnd.wap.wtls-ca-certificate",
+ "application/vnd.wap.wtls-user-certificate",
+ "application/x-x509-ca-cert",
+ "application/x-x509-user-cert",
+ "image/*",
+ "image/gif",
+ "image/jpeg",
+ "image/tiff",
+ "image/png",
+ "image/vnd.wap.wbmp",
+ "application/vnd.wap.multipart.*",
+ "application/vnd.wap.multipart.mixed",
+ "application/vnd.wap.multipart.form-data",
+ "application/vnd.wap.multipart.byteranges",
+ "application/vnd.wap.multipart.alternative",
+ "application/xml",
+ "text/xml",
+ "application/vnd.wap.wbxml",
+ "application/x-x968-cross-cert",
+ "application/x-x968-ca-cert",
+ "application/x-x968-user-cert",
+ "text/vnd.wap.si",
+ "application/vnd.wap.sic",
+ "text/vnd.wap.sl",
+ "application/vnd.wap.slc",
+ "text/vnd.wap.co",
+ "application/vnd.wap.coc",
+ "application/vnd.wap.multipart.related",
+ "application/vnd.wap.sia",
+ "text/vnd.wap.connectivity-xml",
+ "application/vnd.wap.connectivity-wbxml",
+ "application/pkcs7-mime",
+ "application/vnd.wap.hashed-certificate",
+ "application/vnd.wap.signed-certificate",
+ "application/vnd.wap.cert-response",
+ "application/xhtml+xml",
+ "application/wml+xml",
+ "text/css",
+ "application/vnd.wap.mms-message",
+ "application/vnd.wap.rollover-certificate",
+ "application/vnd.wap.locc+wbxml",
+ "application/vnd.wap.loc+xml",
+ "application/vnd.syncml.dm+wbxml",
+ "application/vnd.syncml.dm+xml",
+ "application/vnd.syncml.notification",
+ "application/vnd.wap.xhtml+xml",
+ "application/vnd.wv.csp.cir",
+ "application/vnd.oma.dd+xml",
+ "application/vnd.oma.drm.message",
+ "application/vnd.oma.drm.content",
+ "application/vnd.oma.drm.rights+xml",
+ "application/vnd.oma.drm.rights+wbxml",
+ "application/vnd.wv.csp+xml",
+ "application/vnd.wv.csp+wbxml",
+ "application/vnd.syncml.ds.notification",
+ "audio/*",
+ "video/*",
+ "application/vnd.oma.dd2+xml",
+ "application/mikey",
+ "application/vnd.oma.dcd",
+ "application/vnd.oma.dcdc",
+// "text/x-vMessage",
+// "application/vnd.omads-email+wbxml",
+// "text/x-vBookmark",
+// "application/vnd.syncml.dm.notification",
+ "application/vnd.uplanet.cacheop-wbxml",
+ "application/vnd.uplanet.signal",
+ "application/vnd.uplanet.alert-wbxml",
+ "application/vnd.uplanet.list-wbxml",
+ "application/vnd.uplanet.listcmd-wbxml",
+ "application/vnd.uplanet.channel-wbxml",
+ "application/vnd.uplanet.provisioning-status-uri",
+ "x-wap.multipart/vnd.uplanet.header-set",
+ "application/vnd.uplanet.bearer-choice-wbxml",
+ "application/vnd.phonecom.mmc-wbxml",
+ "application/vnd.nokia.syncset+wbxml",
+ "image/x-up-wpng",
+ "application/iota.mmc-wbxml",
+ "application/iota.mmc-xml",
+ "application/vnd.syncml+xml",
+ "application/vnd.syncml+wbxml",
+ "text/vnd.wap.emn+xml",
+ "text/calendar",
+ "application/vnd.omads-email+xml",
+ "application/vnd.omads-file+xml",
+ "application/vnd.omads-folder+xml",
+ "text/directory;profile=vCard",
+ "application/vnd.wap.emn+wbxml",
+ "application/vnd.nokia.ipdc-purchase-response",
+ "application/vnd.motorola.screen3+xml",
+ "application/vnd.motorola.screen3+gzip",
+ "application/vnd.cmcc.setting+wbxml",
+ "application/vnd.cmcc.bombing+wbxml",
+ "application/vnd.docomo.pf",
+ "application/vnd.docomo.ub",
+ "application/vnd.omaloc-supl-init",
+ "application/vnd.oma.group-usage-list+xml",
+ "application/oma-directory+xml",
+ "application/vnd.docomo.pf2",
+ "application/vnd.oma.drm.roap-trigger+wbxml",
+ "application/vnd.sbm.mid2",
+ "application/vnd.wmf.bootstrap",
+ "application/vnc.cmcc.dcd+xml",
+ "application/vnd.sbm.cid",
+ "application/vnd.oma.bcast.provisioningtrigger",
+ /*"application/vnd.docomo.dm",
+ "application/vnd.oma.scidm.messages+xml"*/
+ };
+
+ private IDataVerify mIVerify = null;
+
+ ServiceConnection mConn = new ServiceConnection() {
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ Log.v(LOG_TAG, "data verify interface connected.");
+ mIVerify = IDataVerify.Stub.asInterface(service);
+ }
+ public void onServiceDisconnected(ComponentName name) {
+ }
+ };
+
+ /**
+ * Main WapPushManager test module constructor
+ */
+ public WapPushTest() {
+ super(WapPushManager.class);
+ mClassName = this.getClass().getName();
+ mPackageName = this.getClass().getPackage().getName();
+ }
+
+ /**
+ * Initialize the verifier
+ */
+ @Override
+ public void setUp() {
+ try {
+ super.setUp();
+ // get verifier
+ getContext().bindService(new Intent(IDataVerify.class.getName()),
+ mConn, Context.BIND_AUTO_CREATE);
+ } catch (Exception e) {
+ Log.w(LOG_TAG, "super exception");
+ }
+ // Log.d(LOG_TAG, "test setup");
+ }
+
+ private IWapPushManager mWapPush = null;
+ IWapPushManager getInterface() {
+ if (mWapPush != null) return mWapPush;
+ Intent startIntent = new Intent();
+ startIntent.setClass(getContext(), WapPushManager.class);
+ IBinder service = bindService(startIntent);
+
+ mWapPush = IWapPushManager.Stub.asInterface(service);
+ return mWapPush;
+ }
+
+ /*
+ * All methods need to start with 'test'.
+ * Use various assert methods to pass/fail the test case.
+ */
+ protected void utAddPackage(boolean need_sig, boolean more_proc) {
+ IWapPushManager iwapman = getInterface();
+
+ // insert new data
+ try {
+ assertTrue(iwapman.addPackage(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_SERVICE, need_sig, more_proc));
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ // verify the data
+ WapPushManager wpman = getService();
+ assertTrue(wpman.verifyData(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_SERVICE, need_sig, more_proc));
+ }
+
+ /**
+ * Add package test
+ */
+ public void testAddPackage1() {
+ int originalAppIdValue = mAppIdValue;
+ int originalContentTypeValue = mContentTypeValue;
+
+ utAddPackage(true, true);
+ mAppIdValue += 10;
+ utAddPackage(true, false);
+ mContentTypeValue += 20;
+ utAddPackage(false, true);
+ mContentTypeValue += 20;
+ utAddPackage(false, false);
+
+ mAppIdValue = originalAppIdValue;
+ mContentTypeValue = originalContentTypeValue;
+
+ // clean up data
+ try {
+ IWapPushManager iwapman = getInterface();
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+ mAppIdValue += 10;
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+ mContentTypeValue += 20;
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+ mContentTypeValue += 20;
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+ mAppIdValue = originalAppIdValue;
+ mContentTypeValue = originalContentTypeValue;
+ }
+
+ /**
+ * Add duprecated package test.
+ */
+ public void testAddPackage2() {
+ try {
+ IWapPushManager iwapman = getInterface();
+
+ // set up data
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
+ false, false);
+ iwapman.addPackage(Integer.toString(mAppIdValue + 10),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
+ false, false);
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue + 10), mPackageName, mClassName, 0,
+ false, false);
+
+ assertFalse(iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
+ false, false));
+ assertFalse(iwapman.addPackage(Integer.toString(mAppIdValue + 10),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
+ false, false));
+ assertFalse(iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue + 10), mPackageName, mClassName, 0,
+ false, false));
+
+ // clean up data
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+ iwapman.deletePackage(Integer.toString(mAppIdValue + 10),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue + 10), mPackageName, mClassName);
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+ }
+
+ protected void utUpdatePackage(boolean need_sig, boolean more_proc) {
+ IWapPushManager iwapman = getInterface();
+
+ // insert new data
+ try {
+ assertTrue(iwapman.updatePackage(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_SERVICE, need_sig, more_proc));
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ // verify the data
+ WapPushManager wpman = getService();
+ assertTrue(wpman.verifyData(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_SERVICE, need_sig, more_proc));
+ }
+
+ /**
+ * Updating package test
+ */
+ public void testUpdatePackage1() {
+ int originalAppIdValue = mAppIdValue;
+ int originalContentTypeValue = mContentTypeValue;
+
+ // set up data
+ try {
+ IWapPushManager iwapman = getInterface();
+
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ 0, false, false);
+ mAppIdValue += 10;
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ 0, false, false);
+ mContentTypeValue += 20;
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ 0, false, false);
+ mContentTypeValue += 20;
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ 0, false, false);
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ mAppIdValue = originalAppIdValue;
+ mContentTypeValue = originalContentTypeValue;
+ utUpdatePackage(false, false);
+ mAppIdValue += 10;
+ utUpdatePackage(false, true);
+ mContentTypeValue += 20;
+ utUpdatePackage(true, false);
+ mContentTypeValue += 20;
+ utUpdatePackage(true, true);
+
+ mAppIdValue = originalAppIdValue;
+ mContentTypeValue = originalContentTypeValue;
+
+ // clean up data
+ try {
+ IWapPushManager iwapman = getInterface();
+
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+ mAppIdValue += 10;
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+ mContentTypeValue += 20;
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+ mContentTypeValue += 20;
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+ mAppIdValue = originalAppIdValue;
+ mContentTypeValue = originalContentTypeValue;
+ }
+
+ /**
+ * Updating invalid package test
+ */
+ public void testUpdatePackage2() {
+ int originalAppIdValue = mAppIdValue;
+ int originalContentTypeValue = mContentTypeValue;
+
+ try {
+ // set up data
+ IWapPushManager iwapman = getInterface();
+
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ 0, false, false);
+ assertFalse(iwapman.updatePackage(
+ Integer.toString(mAppIdValue + 10),
+ Integer.toString(mContentTypeValue),
+ mPackageName, mClassName, 0, false, false));
+ assertFalse(iwapman.updatePackage(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue + 10),
+ mPackageName, mClassName, 0, false, false));
+ assertTrue(iwapman.updatePackage(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ mPackageName + "dummy_data", mClassName, 0, false, false));
+ assertTrue(iwapman.updatePackage(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ mPackageName, mClassName + "dummy_data", 0, false, false));
+ // clean up data
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName,
+ mClassName + "dummy_data");
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+ }
+
+ protected void utDeletePackage() {
+ IWapPushManager iwapman = getInterface();
+
+ try {
+ assertTrue(iwapman.deletePackage(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ mPackageName, mClassName));
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ // verify the data
+ WapPushManager wpman = getService();
+ assertTrue(!wpman.isDataExist(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ mPackageName, mClassName));
+ }
+
+ /**
+ * Deleting package test
+ */
+ public void testDeletePackage1() {
+ int originalAppIdValue = mAppIdValue;
+ int originalContentTypeValue = mContentTypeValue;
+
+ // set up data
+ try {
+ IWapPushManager iwapman = getInterface();
+
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ 0, false, false);
+ mAppIdValue += 10;
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ 0, false, false);
+ mContentTypeValue += 20;
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ 0, false, false);
+ mContentTypeValue += 20;
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ 0, false, false);
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ mAppIdValue = originalAppIdValue;
+ mContentTypeValue = originalContentTypeValue;
+ utDeletePackage();
+ mAppIdValue += 10;
+ utDeletePackage();
+ mContentTypeValue += 20;
+ utDeletePackage();
+ mContentTypeValue += 20;
+ utDeletePackage();
+
+ mAppIdValue = originalAppIdValue;
+ mContentTypeValue = originalContentTypeValue;
+ }
+
+ /**
+ * Deleting invalid package test
+ */
+ public void testDeletePackage2() {
+ int originalAppIdValue = mAppIdValue;
+ int originalContentTypeValue = mContentTypeValue;
+
+ try {
+ // set up data
+ IWapPushManager iwapman = getInterface();
+
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ 0, false, false);
+
+ assertFalse(iwapman.deletePackage(Integer.toString(mAppIdValue + 10),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName));
+ assertFalse(iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue + 20), mPackageName, mClassName));
+ assertFalse(iwapman.deletePackage(Integer.toString(mAppIdValue + 10),
+ Integer.toString(mContentTypeValue + 20), mPackageName, mClassName));
+
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+ }
+
+
+ protected int encodeUint32(int uint32Val, byte[] arr, int start) {
+ int bit = 1;
+ int topbit = 0;
+ int encodeLen;
+ int tmpVal;
+
+ assertTrue(uint32Val >= 0);
+ for (int i = 0; i < 31; i++) {
+ if ((bit & uint32Val) > 0) topbit = i;
+ bit = (bit << 1);
+ }
+ encodeLen = topbit/7 + 1;
+ if (arr == null) return encodeLen;
+
+ //Log.d(LOG_TAG, "uint32Val = " + Integer.toHexString(uint32Val) + ", topbit = "
+ // + topbit + ", encodeLen = " + encodeLen);
+
+ tmpVal = uint32Val;
+ for (int i = encodeLen - 1; i >= 0; i--) {
+ long val = 0;
+ if (i < encodeLen - 1) val = 0x80;
+ val |= tmpVal & 0x7f;
+ arr[start + i] = (byte) (val & 0xFF);
+ tmpVal = (tmpVal >> 7);
+ }
+ return encodeLen;
+ }
+
+ protected int encodeShortInt(int sintVal, byte[] arr, int start) {
+ int encodeLen = 0;
+
+ if (sintVal >= 0x80) return encodeLen;
+ encodeLen = 1;
+ arr[start] = (byte) (sintVal | 0x80);
+ return encodeLen;
+ }
+
+
+ /**
+ * Generate Random WSP header with integer application ID
+ */
+ protected void createRandomWspHeader(byte[] arr, Random rd, int headerStart,
+ boolean noAppId) {
+
+ boolean appIdAdded = false;
+
+ Log.d(LOG_TAG, "headerStart = " + headerStart + ", appId = " + mAppIdValue
+ + "(" + Integer.toHexString(mAppIdValue) + ")");
+ Log.d(LOG_TAG, "random arr length:" + arr.length);
+ String typename[] = new String[] { "short int", "long int", "string", "uint32"};
+
+ while (!appIdAdded) {
+ int type;
+ int index = headerStart;
+ int len = arr.length;
+ int i;
+ boolean addAppid = false;
+ int tmpVal = 0;
+ int tmpVal2 = 0;
+
+ while (true) {
+ int add;
+
+ /*
+ * field name
+ * 0: short int
+ * 1: long int
+ * 2: text
+ * (no uint for param value)
+ */
+ type = rd.nextInt(3);
+ switch (type) {
+ case 0: // header short integer
+ if (index > 100 && !appIdAdded) addAppid = true;
+ add = 1;
+ break;
+ case 1: // header long int
+ add = 1 + rd.nextInt(29);
+ break;
+ default: // header string
+ add = 2 + rd.nextInt(10);
+ break;
+ }
+ if (index + add >= len) break;
+
+ // fill header name
+ switch (type) {
+ case 0: // header short integer
+ if (!addAppid) {
+ do {
+ arr[index] = (byte) (0x80 | rd.nextInt(128));
+ } while (arr[index] == (byte) 0xaf);
+ } else {
+ Log.d(LOG_TAG, "appId added.");
+ arr[index] = (byte) 0xaf;
+ // if noAppId case, appId fld must be decieved.
+ if (noAppId) arr[index]++;
+ }
+ break;
+ case 1: // header long int
+ arr[index] = (byte) (add - 1);
+ tmpVal2 = 0;
+ for (i = 1; i < add; i++) {
+ tmpVal = rd.nextInt(255);
+ tmpVal2 = (tmpVal2 << 8) | tmpVal;
+ arr[index + i] = (byte) tmpVal;
+ }
+ // don't set application id
+ if (tmpVal2 == 0x2f) arr[index + 1]++;
+ break;
+ default: // header string
+ for (i = 0; i < add - 1; i++) {
+ tmpVal = rd.nextInt(127);
+ if (tmpVal < 32) tmpVal= (32 + tmpVal);
+ arr[index + i] = (byte) tmpVal;
+ }
+ arr[index + i] = (byte) 0x0;
+ break;
+ }
+
+ if (LOCAL_LOGV) {
+ Log.d(LOG_TAG, "field name index:" + index);
+ Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
+ if (type != 2) {
+ for (i = index; i< index + add; i++) {
+ System.out.print(Integer.toHexString(0xff & arr[i]));
+ System.out.print(' ');
+ }
+ } else {
+ System.out.print(Integer.toHexString(0xff & arr[index]));
+ System.out.print(' ');
+ String str = new String(arr, index + 1, add - 2);
+ for (i = 0; i < str.length(); i++) {
+ System.out.print(str.charAt(i));
+ System.out.print(' ');
+ }
+ }
+ System.out.print('\n');
+ }
+ index += add;
+
+
+ /*
+ * field value
+ * 0: short int
+ * 1: long int
+ * 2: text
+ * 3: uint
+ */
+ if (addAppid) {
+ type = 1;
+ } else {
+ type = rd.nextInt(4);
+ }
+ switch (type) {
+ case 0: // header short integer
+ add = 1;
+ break;
+ case 1: // header long int
+ if (addAppid) {
+ int bit = 1;
+ int topBit = 0;
+
+ for (i = 0; i < 31; i++) {
+ if ((mAppIdValue & bit) > 0) topBit = i;
+ bit = (bit << 1);
+ }
+ add = 2 + topBit/8;
+ } else {
+ add = 1 + rd.nextInt(29);
+ }
+ break;
+ case 2: // header string
+ add = 2 + rd.nextInt(10);
+ break;
+ default: // uint32
+ add = 6;
+ }
+ if (index + add >= len) break;
+
+ // fill field value
+ switch (type) {
+ case 0: // header short int
+ arr[index] = (byte) (0x80 | rd.nextInt(128));
+ break;
+ case 1: // header long int
+ if (addAppid) {
+ addAppid = false;
+ appIdAdded = true;
+
+ arr[index] = (byte) (add - 1);
+ tmpVal = mAppIdValue;
+ for (i = add; i > 1; i--) {
+ arr[index + i - 1] = (byte) (tmpVal & 0xff);
+ tmpVal = (tmpVal >> 8);
+ }
+ } else {
+ arr[index] = (byte) (add - 1);
+ for (i = 1; i < add; i++) {
+ arr[index + i] = (byte) rd.nextInt(255);
+ }
+ }
+ break;
+ case 2:// header string
+ for (i = 0; i < add - 1; i++) {
+ tmpVal = rd.nextInt(127);
+ if (tmpVal < 32) tmpVal= (32 + tmpVal);
+ arr[index + i] = (byte) tmpVal;
+ }
+ arr[index + i] = (byte) 0x0;
+ break;
+ default: // header uvarint
+ arr[index] = (byte) 31;
+ tmpVal = rd.nextInt(0x0FFFFFFF);
+ add = 1 + encodeUint32(tmpVal, null, index + 1);
+ encodeUint32(tmpVal, arr, index + 1);
+ break;
+
+ }
+
+ if (LOCAL_LOGV) {
+ Log.d(LOG_TAG, "field value index:" + index);
+ Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
+ if (type != 2) {
+ for (i = index; i< index + add; i++) {
+ System.out.print(Integer.toHexString(0xff & arr[i]));
+ System.out.print(' ');
+ }
+ } else {
+ System.out.print(Integer.toHexString(0xff & arr[index]));
+ System.out.print(' ');
+ String str = new String(arr, index + 1, add - 2);
+ for (i = 0; i < str.length(); i++) {
+ System.out.print(str.charAt(i));
+ System.out.print(' ');
+ }
+ }
+ System.out.print('\n');
+ }
+ index += add;
+ }
+ if (noAppId) break;
+ }
+
+ Log.d(LOG_TAG, HexDump.dumpHexString(arr));
+ }
+
+ /**
+ * Generate Random WSP header with string application ID
+ */
+ protected void createRandomWspHeaderStrAppId(byte[] arr, Random rd, int headerStart,
+ boolean randomStr) {
+
+ boolean appIdAdded = false;
+
+ Log.d(LOG_TAG, "random arr length:" + arr.length);
+ String typename[] = new String[] { "short int", "long int", "string", "uint32"};
+
+ while (!appIdAdded) {
+ int type;
+ int index = headerStart;
+ int len = arr.length;
+ int i;
+ boolean addAppid = false;
+ int tmpVal = 0;
+ int tmpVal2 = 0;
+
+ while (true) {
+ int add;
+
+ /*
+ * field name
+ * 0: short int
+ * 1: long int
+ * 2: text
+ * (no uint for param value)
+ */
+ type = rd.nextInt(3);
+ switch (type) {
+ case 0: // header short integer
+ if (index > 100 && !appIdAdded) addAppid = true;
+ add = 1;
+ break;
+ case 1: // header long int
+ add = 1 + rd.nextInt(29);
+ break;
+ default: // header string
+ add = 2 + rd.nextInt(10);
+ break;
+ }
+ if (index + add >= len) break;
+
+ // fill header name
+ switch (type) {
+ case 0: // header short integer
+ if (!addAppid) {
+ do {
+ arr[index] = (byte) (0x80 | rd.nextInt(128));
+ } while (arr[index] == (byte) 0xaf);
+ } else {
+ Log.d(LOG_TAG, "appId added.");
+ arr[index] = (byte) 0xaf;
+ }
+ break;
+ case 1: // header long int
+ arr[index] = (byte) (add - 1);
+ tmpVal2 = 0;
+ for (i = 1; i < add; i++) {
+ tmpVal = rd.nextInt(255);
+ tmpVal2 = (tmpVal2 << 8) | tmpVal;
+ arr[index + i] = (byte) tmpVal;
+ }
+ // don't set application id
+ if (tmpVal2 == 0x2f) arr[index + 1]++;
+ break;
+ default: // header string
+ for (i = 0; i < add - 1; i++) {
+ tmpVal = rd.nextInt(127);
+ if (tmpVal < 32) tmpVal= (32 + tmpVal);
+ arr[index + i] = (byte) tmpVal;
+ }
+ arr[index + i] = (byte) 0x0;
+ break;
+ }
+
+ if (LOCAL_LOGV) {
+ Log.d(LOG_TAG, "field name index:" + index);
+ Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
+ if (type != 2) {
+ for (i = index; i < index + add; i++) {
+ System.out.print(Integer.toHexString(0xff & arr[i]));
+ System.out.print(' ');
+ }
+ } else {
+ System.out.print(Integer.toHexString(0xff & arr[index]));
+ System.out.print(' ');
+ String str = new String(arr, index + 1, add - 2);
+ for (i = 0; i < str.length(); i++) {
+ System.out.print(str.charAt(i));
+ System.out.print(' ');
+ }
+ }
+ System.out.print('\n');
+ }
+ index += add;
+
+
+ /*
+ * field value
+ * 0: short int
+ * 1: long int
+ * 2: text
+ * 3: uint
+ */
+ if (addAppid) {
+ type = 2;
+ } else {
+ type = rd.nextInt(4);
+ }
+ switch (type) {
+ case 0: // header short integer
+ add = 1;
+ break;
+ case 1: // header long int
+ add = 1 + rd.nextInt(29);
+ break;
+ case 2: // header string
+ if (addAppid) {
+ if (randomStr) {
+ add = 1 + rd.nextInt(10);
+ byte[] randStr= new byte[add];
+ for (i = 0; i < add; i++) {
+ tmpVal = rd.nextInt(127);
+ if (tmpVal < 32) tmpVal= (32 + tmpVal);
+ randStr[i] = (byte) tmpVal;
+ }
+ mAppIdName = new String(randStr);
+ }
+ add = mAppIdName.length() + 1;
+ } else {
+ add = 2 + rd.nextInt(10);
+ }
+ break;
+ default: // uint32
+ add = 6;
+ }
+ if (index + add >= len) break;
+
+ // fill field value
+ switch (type) {
+ case 0: // header short int
+ arr[index] = (byte) (0x80 | rd.nextInt(128));
+ break;
+ case 1: // header long int
+ arr[index] = (byte) (add - 1);
+ for (i = 1; i < add; i++)
+ arr[index + i] = (byte) rd.nextInt(255);
+ break;
+ case 2:// header string
+ if (addAppid) {
+ addAppid = false;
+ appIdAdded = true;
+ for (i = 0; i < add - 1; i++) {
+ arr[index + i] = (byte) (mAppIdName.charAt(i));
+ }
+ Log.d(LOG_TAG, "mAppIdName added [" + mAppIdName + "]");
+ } else {
+ for (i = 0; i < add - 1; i++) {
+ tmpVal = rd.nextInt(127);
+ if (tmpVal < 32) tmpVal= (32 + tmpVal);
+ arr[index + i] = (byte) tmpVal;
+ }
+ }
+ arr[index + i] = (byte) 0x0;
+ break;
+ default: // header uvarint
+ arr[index] = (byte) 31;
+ tmpVal = rd.nextInt(0x0FFFFFFF);
+ add = 1 + encodeUint32(tmpVal, null, index + 1);
+ encodeUint32(tmpVal, arr, index + 1);
+ break;
+
+ }
+
+ if (LOCAL_LOGV) {
+ Log.d(LOG_TAG, "field value index:" + index);
+ Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
+ if (type != 2) {
+ for (i = index; i < index + add; i++) {
+ System.out.print(Integer.toHexString(0xff & arr[i]));
+ System.out.print(' ');
+ }
+ } else {
+ System.out.print(Integer.toHexString(0xff & arr[index]));
+ System.out.print(' ');
+ String str = new String(arr, index + 1, add - 2);
+ for (i = 0; i < str.length(); i++) {
+ System.out.print(str.charAt(i));
+ System.out.print(' ');
+ }
+ }
+ System.out.print('\n');
+ }
+ index += add;
+ }
+ }
+
+ Log.d(LOG_TAG, "headerStart = " + headerStart + ", mAppIdName = " + mAppIdName);
+ Log.d(LOG_TAG, HexDump.dumpHexString(arr));
+ }
+
+ protected byte[] createPDU(int testNum) {
+ byte[] array = null;
+ // byte[] wsp = null;
+
+ switch (testNum) {
+ // sample pdu
+ case 1:
+ byte[] array1 = {
+ (byte) 0x00, // TID
+ (byte) 0x06, // Type = wap push
+ (byte) 0x00, // Length to be set later.
+
+ // Content-Type
+ (byte) 0x03, (byte) 0x02,
+ (byte) ((mContentTypeValue >> 8) & 0xff),
+ (byte) (mContentTypeValue & 0xff),
+
+ // Application-id
+ (byte) 0xaf, (byte) 0x02,
+ (byte) ((mAppIdValue >> 8) & 0xff),
+ (byte) (mAppIdValue& 0xff)
+ };
+ array1[2] = (byte) (array1.length - 3);
+ mWspHeader = array1;
+ mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + 7;
+ mWspHeaderLen = array1.length;
+ break;
+
+ // invalid wsp header
+ case 2:
+ byte[] array2 = {
+ (byte) 0x00, // invalid data
+ };
+ mWspHeader = array2;
+ mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length;
+ mWspHeaderLen = array2.length;
+ break;
+
+ // random wsp header
+ case 3:
+ Random rd = new Random();
+ int arrSize = 150 + rd.nextInt(100);
+ byte[] array3 = new byte[arrSize];
+ int hdrEncodeLen;
+
+ array3[0] = (byte) 0x0;
+ array3[1] = (byte) 0x6;
+ hdrEncodeLen = encodeUint32(array3.length, null, 2);
+ hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
+ array3[hdrEncodeLen + 2] = (byte) 0x3;
+ array3[hdrEncodeLen + 3] = (byte) 0x2;
+ array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
+ array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
+ createRandomWspHeader(array3, rd, hdrEncodeLen + 6, false);
+ mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
+ mWspHeaderLen = array3.length;
+
+ Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
+ + "(" + Integer.toHexString(mContentTypeValue) + ")");
+
+ mWspHeader = array3;
+ break;
+
+ // random wsp header w/o appid
+ case 4:
+ rd = new Random();
+ arrSize = 150 + rd.nextInt(100);
+ array3 = new byte[arrSize];
+
+ array3[0] = (byte) 0x0;
+ array3[1] = (byte) 0x6;
+ hdrEncodeLen = encodeUint32(array3.length, null, 2);
+ hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
+ array3[hdrEncodeLen + 2] = (byte) 0x3;
+ array3[hdrEncodeLen + 3] = (byte) 0x2;
+ array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
+ array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
+ createRandomWspHeader(array3, rd, hdrEncodeLen + 6, true);
+ mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
+ mWspHeaderLen = array3.length;
+
+ Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
+ + "(" + Integer.toHexString(mContentTypeValue) + ")");
+
+ mWspHeader = array3;
+ break;
+
+ // random wsp header w/ random appid string
+ case 5:
+ rd = new Random();
+ arrSize = 150 + rd.nextInt(100);
+ array3 = new byte[arrSize];
+
+ array3[0] = (byte) 0x0;
+ array3[1] = (byte) 0x6;
+ hdrEncodeLen = encodeUint32(array3.length, null, 2);
+ hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
+ array3[hdrEncodeLen + 2] = (byte) 0x3;
+ array3[hdrEncodeLen + 3] = (byte) 0x2;
+ array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
+ array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
+ createRandomWspHeaderStrAppId(array3, rd, hdrEncodeLen + 6, true);
+ mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
+ mWspHeaderLen = array3.length;
+
+ Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
+ + "(" + Integer.toHexString(mContentTypeValue) + ")");
+
+ mWspHeader = array3;
+ break;
+
+ // random wsp header w/ OMA appid string
+ case 6:
+ rd = new Random();
+ arrSize = 150 + rd.nextInt(100);
+ array3 = new byte[arrSize];
+
+ array3[0] = (byte) 0x0;
+ array3[1] = (byte) 0x6;
+ hdrEncodeLen = encodeUint32(array3.length, null, 2);
+ hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
+ array3[hdrEncodeLen + 2] = (byte) 0x3;
+ array3[hdrEncodeLen + 3] = (byte) 0x2;
+ array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
+ array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
+ createRandomWspHeaderStrAppId(array3, rd, hdrEncodeLen + 6, false);
+ mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
+ mWspHeaderLen = array3.length;
+
+ Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
+ + "(" + Integer.toHexString(mContentTypeValue) + ")");
+
+ mWspHeader = array3;
+ break;
+
+ // random wsp header w/ OMA content type
+ case 7:
+ rd = new Random();
+ arrSize = 150 + rd.nextInt(100);
+ array3 = new byte[arrSize];
+
+ array3[0] = (byte) 0x0;
+ array3[1] = (byte) 0x6;
+ hdrEncodeLen = encodeUint32(array3.length, null, 2);
+ hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
+
+ // encode content type
+ int contentLen = mContentTypeName.length();
+ int next = 2 + hdrEncodeLen;
+ mWspContentTypeStart = mGsmHeader.length + mUserDataHeader.length + next;
+ // next += encodeUint32(contentLen, array3, next);
+ int i;
+ Log.d(LOG_TAG, "mContentTypeName = " + mContentTypeName
+ + ", contentLen = " + contentLen);
+
+ for (i = 0; i < contentLen; i++) {
+ array3[next + i] = (byte) mContentTypeName.charAt(i);
+ }
+ array3[next + i] = (byte) 0x0;
+
+ createRandomWspHeader(array3, rd, next + contentLen + 1, false);
+ mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length
+ + next + contentLen + 1;
+ mWspHeaderLen = array3.length;
+
+ mWspHeader = array3;
+ break;
+
+ // random wsp header w/ OMA content type, OMA app ID
+ case 8:
+ rd = new Random();
+ arrSize = 150 + rd.nextInt(100);
+ array3 = new byte[arrSize];
+
+ array3[0] = (byte) 0x0;
+ array3[1] = (byte) 0x6;
+ hdrEncodeLen = encodeUint32(array3.length, null, 2);
+ hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
+
+ // encode content type
+ contentLen = mContentTypeName.length();
+ next = 2 + hdrEncodeLen;
+ mWspContentTypeStart = mGsmHeader.length + mUserDataHeader.length + next;
+ // next += encodeUint32(contentLen, array3, next);
+ Log.d(LOG_TAG, "mContentTypeName = " + mContentTypeName
+ + ", contentLen = " + contentLen);
+
+ for (i = 0; i < contentLen; i++) {
+ array3[next + i] = (byte) mContentTypeName.charAt(i);
+ }
+ array3[next + i] = (byte) 0x0;
+
+ createRandomWspHeaderStrAppId(array3, rd, next + contentLen + 1, false);
+ mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length
+ + next + contentLen + 1;
+ mWspHeaderLen = array3.length;
+
+ mWspHeader = array3;
+ break;
+
+ default:
+ return null;
+ }
+ array = new byte[mGsmHeader.length + mUserDataHeader.length + mWspHeader.length
+ + mMessageBody.length];
+ System.arraycopy(mGsmHeader, 0, array, 0, mGsmHeader.length);
+ System.arraycopy(mUserDataHeader, 0, array,
+ mGsmHeader.length, mUserDataHeader.length);
+ System.arraycopy(mWspHeader, 0, array,
+ mGsmHeader.length + mUserDataHeader.length, mWspHeader.length);
+ System.arraycopy(mMessageBody, 0, array,
+ mGsmHeader.length + mUserDataHeader.length + mWspHeader.length,
+ mMessageBody.length);
+ return array;
+
+ }
+
+ Intent createIntent(int pduType, int tranId) {
+ Intent intent = new Intent();
+ intent.putExtra("transactionId", tranId);
+ intent.putExtra("pduType", pduType);
+ intent.putExtra("header", mGsmHeader);
+ intent.putExtra("data", mMessageBody);
+ // intent.putExtra("contentTypeParameters", null);
+ return intent;
+ }
+
+ /**
+ * Message processing test, start activity
+ */
+ public void testProcessMsg1() {
+ byte[] pdu = createPDU(1);
+ int headerLen = pdu.length -
+ (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
+ int pduType = 6;
+ int tranId = 0;
+ String originalPackageName = mPackageName;
+ String originalClassName = mClassName;
+
+ try {
+
+ mClassName = "com.android.smspush.unitTests.ReceiverActivity";
+
+ // set up data
+ IWapPushManager iwapman = getInterface();
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
+
+ assertTrue((iwapman.processMessage(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ createIntent(pduType, tranId))
+ & WapPushManagerParams.MESSAGE_HANDLED) ==
+ WapPushManagerParams.MESSAGE_HANDLED);
+
+ // clean up data
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ mPackageName = originalPackageName;
+ mClassName = originalClassName;
+ }
+
+ /**
+ * Message processing test, start service
+ */
+ public void testProcessMsg2() {
+ byte[] pdu = createPDU(1);
+ int headerLen = pdu.length - (mGsmHeader.length +
+ mUserDataHeader.length + mMessageBody.length);
+ int pduType = 6;
+ int tranId = 0;
+ String originalPackageName = mPackageName;
+ String originalClassName = mClassName;
+
+ try {
+
+ mClassName = "com.android.smspush.unitTests.ReceiverService";
+
+ // set up data
+ IWapPushManager iwapman = getInterface();
+
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_SERVICE, false, false);
+
+ assertTrue((iwapman.processMessage(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ createIntent(pduType, tranId))
+ & WapPushManagerParams.MESSAGE_HANDLED) ==
+ WapPushManagerParams.MESSAGE_HANDLED);
+
+ // clean up data
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ mPackageName = originalPackageName;
+ mClassName = originalClassName;
+ }
+
+ /**
+ * Message processing test, no signature
+ */
+ public void testProcessMsg3() {
+ byte[] pdu = createPDU(1);
+ int headerLen = pdu.length -
+ (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
+ int pduType = 6;
+ int tranId = 0;
+ String originalPackageName = mPackageName;
+ String originalClassName = mClassName;
+
+ try {
+
+ mPackageName = "com.android.development";
+ mClassName = "com.android.development.Development";
+
+ // set up data
+ IWapPushManager iwapman = getInterface();
+
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_SERVICE, true, false);
+
+ assertFalse((iwapman.processMessage(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ createIntent(pduType, tranId))
+ & WapPushManagerParams.MESSAGE_HANDLED) ==
+ WapPushManagerParams.MESSAGE_HANDLED);
+
+ // clean up data
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ mPackageName = originalPackageName;
+ mClassName = originalClassName;
+ }
+
+ IDataVerify getVerifyInterface() {
+ while (mIVerify == null) {
+ // wait for the activity receive data.
+ try {
+ Thread.sleep(TIME_WAIT);
+ } catch (InterruptedException e) {}
+ }
+ return mIVerify;
+ }
+
+
+ /**
+ * Message processing test, received body data verification test
+ */
+ public void testProcessMsg4() {
+ byte[] originalMessageBody = mMessageBody;
+ mMessageBody = new byte[] {
+ (byte) 0xee,
+ (byte) 0xff,
+ (byte) 0xee,
+ (byte) 0xff,
+ (byte) 0xee,
+ (byte) 0xff,
+ (byte) 0xee,
+ (byte) 0xff,
+ (byte) 0xee,
+ (byte) 0xff,
+ (byte) 0xee,
+ (byte) 0xff,
+ };
+
+ byte[] pdu = createPDU(1);
+ int headerLen = pdu.length -
+ (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
+ int pduType = 6;
+ int tranId = 0;
+ String originalPackageName = mPackageName;
+ String originalClassName = mClassName;
+
+ try {
+ IWapPushManager iwapman = getInterface();
+ IDataVerify dataverify = getVerifyInterface();
+
+ dataverify.resetData();
+
+ // set up data
+ mClassName = "com.android.smspush.unitTests.ReceiverActivity";
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
+
+ iwapman.processMessage(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ createIntent(pduType, tranId));
+
+ // clean up data
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+
+ assertTrue(dataverify.verifyData(mMessageBody));
+
+ // set up data
+ dataverify.resetData();
+ mClassName = "com.android.smspush.unitTests.ReceiverService";
+ mMessageBody = new byte[] {
+ (byte) 0xaa,
+ (byte) 0xbb,
+ (byte) 0x11,
+ (byte) 0x22,
+ (byte) 0xaa,
+ (byte) 0xbb,
+ (byte) 0x11,
+ (byte) 0x22,
+ (byte) 0xaa,
+ (byte) 0xbb,
+ (byte) 0x11,
+ (byte) 0x22,
+ (byte) 0xaa,
+ (byte) 0xbb,
+ (byte) 0x11,
+ (byte) 0x22,
+ (byte) 0xaa,
+ (byte) 0xbb,
+ (byte) 0x11,
+ (byte) 0x22,
+ (byte) 0xaa,
+ (byte) 0xbb,
+ (byte) 0x11,
+ (byte) 0x22,
+ };
+ pdu = createPDU(1);
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_SERVICE, false, false);
+
+ iwapman.processMessage(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ createIntent(pduType, tranId));
+
+ // clean up data
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+
+ // Log.d(LOG_TAG, HexDump.dumpHexString(mMessageBody));
+ assertTrue(dataverify.verifyData(mMessageBody));
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ mPackageName = originalPackageName;
+ mClassName = originalClassName;
+ mMessageBody = originalMessageBody;
+ }
+
+ /**
+ * Message processing test, send invalid sms data
+ */
+ public void testProcessMsg5() {
+ byte[] pdu = createPDU(2);
+ int headerLen = pdu.length -
+ (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
+ int pduType = 6;
+ int tranId = 0;
+ String originalPackageName = mPackageName;
+ String originalClassName = mClassName;
+
+ try {
+
+ mClassName = "com.android.smspush.unitTests.ReceiverActivity";
+
+ // set up data
+ IWapPushManager iwapman = getInterface();
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
+
+ assertTrue((iwapman.processMessage(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ createIntent(pduType, tranId))
+ & WapPushManagerParams.MESSAGE_HANDLED) ==
+ WapPushManagerParams.MESSAGE_HANDLED);
+
+ // clean up data
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ mPackageName = originalPackageName;
+ mClassName = originalClassName;
+ }
+
+ /**
+ * Message processing test, no receiver application
+ */
+ public void testProcessMsg6() {
+ byte[] pdu = createPDU(1);
+ int headerLen = pdu.length -
+ (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
+ int pduType = 6;
+ int tranId = 0;
+ String originalPackageName = mPackageName;
+ String originalClassName = mClassName;
+
+ try {
+
+ mClassName = "com.android.smspush.unitTests.NoReceiver";
+
+ // set up data
+ IWapPushManager iwapman = getInterface();
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
+
+ assertFalse((iwapman.processMessage(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ createIntent(pduType, tranId))
+ & WapPushManagerParams.MESSAGE_HANDLED) ==
+ WapPushManagerParams.MESSAGE_HANDLED);
+
+ // clean up data
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+
+ // set up data
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_SERVICE, false, false);
+
+ assertFalse((iwapman.processMessage(
+ Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue),
+ createIntent(pduType, tranId))
+ & WapPushManagerParams.MESSAGE_HANDLED) ==
+ WapPushManagerParams.MESSAGE_HANDLED);
+
+ // clean up data
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ Integer.toString(mContentTypeValue), mPackageName, mClassName);
+
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ mPackageName = originalPackageName;
+ mClassName = originalClassName;
+ }
+
+ /**
+ * WspTypeDecoder test, normal pdu
+ */
+ public void testDecoder1() {
+ boolean res;
+ int originalAppIdValue = mAppIdValue;
+ Random rd = new Random();
+
+ for (int i = 0; i < 10; i++) {
+ mAppIdValue = rd.nextInt(0xFFFF);
+ byte[] pdu = createPDU(1);
+ WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
+
+ res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
+ mWspHeaderStart + mWspHeaderLen - 1);
+ assertTrue(res);
+
+ int index = (int) pduDecoder.getValue32();
+ res = pduDecoder.decodeXWapApplicationId(index);
+ assertTrue(res);
+
+ Log.d(LOG_TAG, "mAppIdValue: " + mAppIdValue
+ + ", val: " + pduDecoder.getValue32());
+ assertTrue(mAppIdValue == (int) pduDecoder.getValue32());
+ }
+
+ mAppIdValue = originalAppIdValue;
+ }
+
+ /**
+ * WspTypeDecoder test, no header
+ */
+ public void testDecoder2() {
+ boolean res;
+ int originalAppIdValue = mAppIdValue;
+ Random rd = new Random();
+
+ mAppIdValue = rd.nextInt(0xFFFF);
+ byte[] pdu = createPDU(2);
+ WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
+
+ res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
+ mWspHeaderStart + mWspHeaderLen - 1);
+ assertFalse(res);
+
+ mAppIdValue = originalAppIdValue;
+ }
+
+ /**
+ * WspTypeDecoder test, decode appid test
+ */
+ public void testDecoder3() {
+ boolean res;
+ int originalAppIdValue = mAppIdValue;
+ int originalContentTypeValue = mContentTypeValue;
+ Random rd = new Random();
+
+ for (int i = 0; i < 100; i++) {
+ mAppIdValue = rd.nextInt(0x0FFFFFFF);
+ mContentTypeValue = rd.nextInt(0x0FFF);
+ byte[] pdu = createPDU(3);
+ WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
+
+ res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
+ mWspHeaderStart + mWspHeaderLen - 1);
+ assertTrue(res);
+
+ int index = (int) pduDecoder.getValue32();
+ res = pduDecoder.decodeXWapApplicationId(index);
+ assertTrue(res);
+
+ Log.d(LOG_TAG, "mAppIdValue: " + mAppIdValue
+ + ", val: " + pduDecoder.getValue32());
+ assertTrue(mAppIdValue == (int) pduDecoder.getValue32());
+ }
+
+ mAppIdValue = originalAppIdValue;
+ mContentTypeValue = originalContentTypeValue;
+ }
+
+ /*
+ public void testEnc() {
+ byte[] arr = new byte[20];
+ int index = 0;
+ index += encodeUint32(0x87a5, arr, index);
+ index += encodeUint32(0x1, arr, index);
+ index += encodeUint32(0x9b, arr, index);
+ index += encodeUint32(0x10, arr, index);
+ index += encodeUint32(0xe0887, arr, index);
+ index += encodeUint32(0x791a23d0, arr, index);
+
+ Log.d(LOG_TAG, HexDump.dumpHexString(arr));
+ }
+ */
+
+ /**
+ * WspTypeDecoder test, no appid test
+ */
+ public void testDecoder4() {
+ boolean res;
+ int originalAppIdValue = mAppIdValue;
+ int originalContentTypeValue = mContentTypeValue;
+ Random rd = new Random();
+
+ for (int i = 0; i < 100; i++) {
+ mAppIdValue = rd.nextInt(0x0FFFFFFF);
+ mContentTypeValue = rd.nextInt(0x0FFF);
+ byte[] pdu = createPDU(4);
+ WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
+
+ res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
+ mWspHeaderStart + mWspHeaderLen - 1);
+ assertFalse(res);
+
+ }
+
+ mAppIdValue = originalAppIdValue;
+ mContentTypeValue = originalContentTypeValue;
+ }
+
+ /**
+ * WspTypeDecoder test, decode string appid test
+ */
+ public void testDecoder5() {
+ boolean res;
+ String originalAppIdName = mAppIdName;
+ int originalContentTypeValue = mContentTypeValue;
+ Random rd = new Random();
+
+ for (int i = 0; i < 10; i++) {
+ mAppIdValue = rd.nextInt(0x0FFFFFFF);
+ mContentTypeValue = rd.nextInt(0x0FFF);
+ byte[] pdu = createPDU(5);
+ WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
+
+ res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
+ mWspHeaderStart + mWspHeaderLen - 1);
+ assertTrue(res);
+
+ int index = (int) pduDecoder.getValue32();
+ res = pduDecoder.decodeXWapApplicationId(index);
+ assertTrue(res);
+
+ Log.d(LOG_TAG, "mAppIdValue: [" + mAppIdName + "], val: ["
+ + pduDecoder.getValueString() + "]");
+ assertTrue(mAppIdName.equals(pduDecoder.getValueString()));
+ }
+
+ mAppIdName = originalAppIdName;
+ mContentTypeValue = originalContentTypeValue;
+ }
+
+ /**
+ * WspTypeDecoder test, decode string appid test
+ */
+ public void testDecoder6() {
+ boolean res;
+ String originalAppIdName = mAppIdName;
+ int originalContentTypeValue = mContentTypeValue;
+ Random rd = new Random();
+
+ for (int i = 0; i < OMA_APPLICATION_ID_NAMES.length; i++) {
+ mAppIdName = OMA_APPLICATION_ID_NAMES[i];
+ mContentTypeValue = rd.nextInt(0x0FFF);
+ byte[] pdu = createPDU(6);
+ WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
+
+ res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
+ mWspHeaderStart + mWspHeaderLen - 1);
+ assertTrue(res);
+
+ int index = (int) pduDecoder.getValue32();
+ res = pduDecoder.decodeXWapApplicationId(index);
+ assertTrue(res);
+
+ Log.d(LOG_TAG, "mAppIdValue: [" + mAppIdName + "], val: ["
+ + pduDecoder.getValueString() + "]");
+ assertTrue(mAppIdName.equals(pduDecoder.getValueString()));
+ }
+
+ mAppIdName = originalAppIdName;
+ mContentTypeValue = originalContentTypeValue;
+ }
+
+ /**
+ * WspTypeDecoder test, decode OMA content type
+ */
+ public void testDecoder7() {
+ boolean res;
+ String originalAppIdName = mAppIdName;
+ int originalContentTypeValue = mContentTypeValue;
+ Random rd = new Random();
+
+ for (int i = 0; i < OMA_CONTENT_TYPE_NAMES.length; i++) {
+ mContentTypeName = OMA_CONTENT_TYPE_NAMES[i];
+ byte[] pdu = createPDU(7);
+ WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
+
+ res = pduDecoder.decodeContentType(mWspContentTypeStart);
+ assertTrue(res);
+
+ Log.d(LOG_TAG, "mContentTypeName: [" + mContentTypeName + "], val: ["
+ + pduDecoder.getValueString() + "]");
+ assertTrue(mContentTypeName.equals(pduDecoder.getValueString()));
+ }
+
+ mAppIdName = originalAppIdName;
+ mContentTypeValue = originalContentTypeValue;
+ }
+
+
+ /**
+ * Copied from WapPushOverSms.
+ * The code flow is not changed from the original.
+ */
+ public int dispatchWapPdu(byte[] pdu, IWapPushManager wapPushMan) {
+
+ if (Config.DEBUG) Log.d(LOG_TAG, "Rx: " + IccUtils.bytesToHexString(pdu));
+
+ int index = 0;
+ int transactionId = pdu[index++] & 0xFF;
+ int pduType = pdu[index++] & 0xFF;
+ int headerLength = 0;
+
+ if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) &&
+ (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
+ if (Config.DEBUG) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
+ return Intents.RESULT_SMS_HANDLED;
+ }
+
+ WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
+
+ /**
+ * Parse HeaderLen(unsigned integer).
+ * From wap-230-wsp-20010705-a section 8.1.2
+ * The maximum size of a uintvar is 32 bits.
+ * So it will be encoded in no more than 5 octets.
+ */
+ if (pduDecoder.decodeUintvarInteger(index) == false) {
+ if (Config.DEBUG) Log.w(LOG_TAG, "Received PDU. Header Length error.");
+ return Intents.RESULT_SMS_GENERIC_ERROR;
+ }
+ headerLength = (int) pduDecoder.getValue32();
+ index += pduDecoder.getDecodedDataLength();
+
+ int headerStartIndex = index;
+
+ /**
+ * Parse Content-Type.
+ * From wap-230-wsp-20010705-a section 8.4.2.24
+ *
+ * Content-type-value = Constrained-media | Content-general-form
+ * Content-general-form = Value-length Media-type
+ * Media-type = (Well-known-media | Extension-Media) *(Parameter)
+ * Value-length = Short-length | (Length-quote Length)
+ * Short-length = <Any octet 0-30> (octet <= WAP_PDU_SHORT_LENGTH_MAX)
+ * Length-quote = <Octet 31> (WAP_PDU_LENGTH_QUOTE)
+ * Length = Uintvar-integer
+ */
+ if (pduDecoder.decodeContentType(index) == false) {
+ if (Config.DEBUG) Log.w(LOG_TAG, "Received PDU. Header Content-Type error.");
+ return Intents.RESULT_SMS_GENERIC_ERROR;
+ }
+
+ String mimeType = pduDecoder.getValueString();
+ long binaryContentType = pduDecoder.getValue32();
+ index += pduDecoder.getDecodedDataLength();
+
+ byte[] header = new byte[headerLength];
+ System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
+
+ byte[] intentData;
+
+ if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
+ intentData = pdu;
+ } else {
+ int dataIndex = headerStartIndex + headerLength;
+ intentData = new byte[pdu.length - dataIndex];
+ System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length);
+ }
+
+ /**
+ * Seek for application ID field in WSP header.
+ * If application ID is found, WapPushManager substitute the message
+ * processing. Since WapPushManager is optional module, if WapPushManager
+ * is not found, legacy message processing will be continued.
+ */
+ if (pduDecoder.seekXWapApplicationId(index, index + headerLength - 1)) {
+ index = (int) pduDecoder.getValue32();
+ pduDecoder.decodeXWapApplicationId(index);
+ String wapAppId = pduDecoder.getValueString();
+ if (wapAppId == null) {
+ wapAppId = Integer.toString((int) pduDecoder.getValue32());
+ }
+
+ String contentType = ((mimeType == null) ?
+ Long.toString(binaryContentType) : mimeType);
+ if (Config.DEBUG) Log.v(LOG_TAG, "appid found: " + wapAppId + ":" + contentType);
+
+ try {
+ boolean processFurther = true;
+ // IWapPushManager wapPushMan = mWapConn.getWapPushManager();
+ if (wapPushMan == null) {
+ if (Config.DEBUG) Log.w(LOG_TAG, "wap push manager not found!");
+ } else {
+ Intent intent = new Intent();
+ intent.putExtra("transactionId", transactionId);
+ intent.putExtra("pduType", pduType);
+ intent.putExtra("header", header);
+ intent.putExtra("data", intentData);
+ intent.putExtra("contentTypeParameters",
+ pduDecoder.getContentParameters());
+
+ int procRet = wapPushMan.processMessage(wapAppId, contentType, intent);
+ if (Config.DEBUG) Log.v(LOG_TAG, "procRet:" + procRet);
+ if ((procRet & WapPushManagerParams.MESSAGE_HANDLED) > 0
+ && (procRet & WapPushManagerParams.FURTHER_PROCESSING) == 0) {
+ processFurther = false;
+ }
+ }
+ if (!processFurther) {
+ return Intents.RESULT_SMS_HANDLED;
+ }
+ } catch (RemoteException e) {
+ if (Config.DEBUG) Log.w(LOG_TAG, "remote func failed...");
+ }
+ }
+ if (Config.DEBUG) Log.v(LOG_TAG, "fall back to existing handler");
+
+ return Activity.RESULT_OK;
+ }
+
+ protected byte[] retrieveWspBody() {
+ byte[] array = new byte[mWspHeader.length + mMessageBody.length];
+
+ System.arraycopy(mWspHeader, 0, array, 0, mWspHeader.length);
+ System.arraycopy(mMessageBody, 0, array, mWspHeader.length, mMessageBody.length);
+ return array;
+ }
+
+ protected String getContentTypeName(int ctypeVal) {
+ int i;
+
+ for (i = 0; i < OMA_CONTENT_TYPE_VALUES.length; i++) {
+ if (ctypeVal == OMA_CONTENT_TYPE_VALUES[i]) {
+ return OMA_CONTENT_TYPE_NAMES[i];
+ }
+ }
+ return null;
+ }
+
+ protected boolean isContentTypeMapped(int ctypeVal) {
+ int i;
+
+ for (i = 0; i < OMA_CONTENT_TYPE_VALUES.length; i++) {
+ if (ctypeVal == OMA_CONTENT_TYPE_VALUES[i]) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Integration test 1, simple case
+ */
+ public void testIntegration1() {
+ boolean res;
+ int originalAppIdValue = mAppIdValue;
+ int originalContentTypeValue = mContentTypeValue;
+ String originalAppIdName = mAppIdName;
+ String originalContentTypeName = mContentTypeName;
+ String originalClassName = mClassName;
+ byte[] originalMessageBody = mMessageBody;
+ Random rd = new Random();
+
+ mMessageBody = new byte[100 + rd.nextInt(100)];
+ rd.nextBytes(mMessageBody);
+
+ byte[] pdu = createPDU(1);
+ byte[] wappushPdu = retrieveWspBody();
+
+
+ mClassName = "com.android.smspush.unitTests.ReceiverActivity";
+ // Phone dummy = new DummyPhone(getContext());
+ // Phone gsm = PhoneFactory.getGsmPhone();
+ // GSMPhone gsm = new GSMPhone(getContext(), new SimulatedCommands(), null, true);
+ // WapPushOverSms dispatcher = new WapPushOverSms(dummy, null);
+
+ try {
+ // set up data
+ IWapPushManager iwapman = getInterface();
+ IDataVerify dataverify = getVerifyInterface();
+
+ dataverify.resetData();
+
+ if (isContentTypeMapped(mContentTypeValue)) {
+ // content type is mapped
+ mContentTypeName = getContentTypeName(mContentTypeValue);
+ Log.d(LOG_TAG, "mContentTypeValue mapping "
+ + mContentTypeName + ":" + mContentTypeValue);
+ } else {
+ mContentTypeName = Integer.toString(mContentTypeValue);
+ }
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ mContentTypeName, mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
+
+ dispatchWapPdu(wappushPdu, iwapman);
+
+ // clean up data
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ mContentTypeName, mPackageName, mClassName);
+
+ assertTrue(dataverify.verifyData(mMessageBody));
+ } catch (RemoteException e) {
+ }
+
+
+ mClassName = originalClassName;
+ mAppIdName = originalAppIdName;
+ mContentTypeName = originalContentTypeName;
+ mAppIdValue = originalAppIdValue;
+ mContentTypeValue = originalContentTypeValue;
+ mMessageBody = originalMessageBody;
+ }
+
+ /**
+ * Integration test 2, random mAppIdValue(int), all OMA content type
+ */
+ public void testIntegration2() {
+ boolean res;
+ int originalAppIdValue = mAppIdValue;
+ int originalContentTypeValue = mContentTypeValue;
+ String originalAppIdName = mAppIdName;
+ String originalContentTypeName = mContentTypeName;
+ String originalClassName = mClassName;
+ byte[] originalMessageBody = mMessageBody;
+ Random rd = new Random();
+
+ IWapPushManager iwapman = getInterface();
+ IDataVerify dataverify = getVerifyInterface();
+ mClassName = "com.android.smspush.unitTests.ReceiverActivity";
+
+ for (int i = 0; i < OMA_CONTENT_TYPE_NAMES.length; i++) {
+ mContentTypeName = OMA_CONTENT_TYPE_NAMES[i];
+ mAppIdValue = rd.nextInt(0x0FFFFFFF);
+
+ mMessageBody = new byte[100 + rd.nextInt(100)];
+ rd.nextBytes(mMessageBody);
+
+ byte[] pdu = createPDU(7);
+ byte[] wappushPdu = retrieveWspBody();
+
+ try {
+ dataverify.resetData();
+ // set up data
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ mContentTypeName, mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
+
+ dispatchWapPdu(wappushPdu, iwapman);
+
+ // clean up data
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ mContentTypeName, mPackageName, mClassName);
+
+ if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
+ assertTrue(dataverify.verifyData(wappushPdu));
+ } else {
+ assertTrue(dataverify.verifyData(mMessageBody));
+ }
+ } catch (RemoteException e) {
+ }
+ }
+
+
+ mClassName = originalClassName;
+ mAppIdName = originalAppIdName;
+ mContentTypeName = originalContentTypeName;
+ mAppIdValue = originalAppIdValue;
+ mContentTypeValue = originalContentTypeValue;
+ mMessageBody = originalMessageBody;
+ }
+
+ /**
+ * Integration test 3, iterate OmaApplication ID, random binary content type
+ */
+ public void testIntegration3() {
+ boolean res;
+ int originalAppIdValue = mAppIdValue;
+ int originalContentTypeValue = mContentTypeValue;
+ String originalAppIdName = mAppIdName;
+ String originalContentTypeName = mContentTypeName;
+ String originalClassName = mClassName;
+ byte[] originalMessageBody = mMessageBody;
+ Random rd = new Random();
+
+ IWapPushManager iwapman = getInterface();
+ IDataVerify dataverify = getVerifyInterface();
+ mClassName = "com.android.smspush.unitTests.ReceiverService";
+
+ for (int i = 0; i < OMA_APPLICATION_ID_NAMES.length; i++) {
+ mAppIdName = OMA_APPLICATION_ID_NAMES[i];
+ mContentTypeValue = rd.nextInt(0x0FFF);
+
+ mMessageBody = new byte[100 + rd.nextInt(100)];
+ rd.nextBytes(mMessageBody);
+
+ byte[] pdu = createPDU(6);
+ byte[] wappushPdu = retrieveWspBody();
+
+ try {
+ dataverify.resetData();
+ // set up data
+ if (isContentTypeMapped(mContentTypeValue)) {
+ // content type is mapped to integer value
+ mContentTypeName = getContentTypeName(mContentTypeValue);
+ Log.d(LOG_TAG, "mContentTypeValue mapping "
+ + mContentTypeValue + ":" + mContentTypeName);
+ } else {
+ mContentTypeName = Integer.toString(mContentTypeValue);
+ }
+
+ iwapman.addPackage(mAppIdName,
+ mContentTypeName, mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_SERVICE, false, false);
+
+ dispatchWapPdu(wappushPdu, iwapman);
+
+ // clean up data
+ iwapman.deletePackage(mAppIdName,
+ mContentTypeName, mPackageName, mClassName);
+
+ if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
+ assertTrue(dataverify.verifyData(wappushPdu));
+ } else {
+ assertTrue(dataverify.verifyData(mMessageBody));
+ }
+ } catch (RemoteException e) {
+ }
+ }
+
+ mClassName = originalClassName;
+ mAppIdName = originalAppIdName;
+ mContentTypeName = originalContentTypeName;
+ mAppIdValue = originalAppIdValue;
+ mContentTypeValue = originalContentTypeValue;
+ mMessageBody = originalMessageBody;
+ }
+
+ /**
+ * Integration test 4, iterate OmaApplication ID, Oma content type
+ */
+ public void testIntegration4() {
+ boolean res;
+ int originalAppIdValue = mAppIdValue;
+ int originalContentTypeValue = mContentTypeValue;
+ String originalAppIdName = mAppIdName;
+ String originalContentTypeName = mContentTypeName;
+ String originalClassName = mClassName;
+ byte[] originalMessageBody = mMessageBody;
+ Random rd = new Random();
+
+ IWapPushManager iwapman = getInterface();
+ IDataVerify dataverify = getVerifyInterface();
+ mClassName = "com.android.smspush.unitTests.ReceiverService";
+
+ for (int i = 0; i < OMA_APPLICATION_ID_NAMES.length
+ + OMA_CONTENT_TYPE_NAMES.length; i++) {
+ mAppIdName = OMA_APPLICATION_ID_NAMES[rd.nextInt(OMA_APPLICATION_ID_NAMES.length)];
+ int contIndex = rd.nextInt(OMA_CONTENT_TYPE_NAMES.length);
+ mContentTypeName = OMA_CONTENT_TYPE_NAMES[contIndex];
+
+ mMessageBody = new byte[100 + rd.nextInt(100)];
+ rd.nextBytes(mMessageBody);
+
+ byte[] pdu = createPDU(8);
+ byte[] wappushPdu = retrieveWspBody();
+
+ try {
+ dataverify.resetData();
+ // set up data
+ iwapman.addPackage(mAppIdName,
+ mContentTypeName, mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_SERVICE, false, false);
+
+ dispatchWapPdu(wappushPdu, iwapman);
+
+ // clean up data
+ iwapman.deletePackage(mAppIdName,
+ mContentTypeName, mPackageName, mClassName);
+
+ if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
+ assertTrue(dataverify.verifyData(wappushPdu));
+ } else {
+ assertTrue(dataverify.verifyData(mMessageBody));
+ }
+ } catch (RemoteException e) {
+ }
+ }
+
+ mClassName = originalClassName;
+ mAppIdName = originalAppIdName;
+ mContentTypeName = originalContentTypeName;
+ mAppIdValue = originalAppIdValue;
+ mContentTypeValue = originalContentTypeValue;
+ mMessageBody = originalMessageBody;
+ }
+
+ /**
+ * Integration test 5, iterate binary OmaApplication ID, Oma binary content type
+ */
+ public void testIntegration5() {
+ boolean res;
+ int originalAppIdValue = mAppIdValue;
+ int originalContentTypeValue = mContentTypeValue;
+ String originalAppIdName = mAppIdName;
+ String originalContentTypeName = mContentTypeName;
+ String originalClassName = mClassName;
+ byte[] originalMessageBody = mMessageBody;
+ Random rd = new Random();
+
+ IWapPushManager iwapman = getInterface();
+ IDataVerify dataverify = getVerifyInterface();
+ mClassName = "com.android.smspush.unitTests.ReceiverService";
+
+ for (int i = 0; i < OMA_APPLICATION_ID_VALUES.length +
+ OMA_CONTENT_TYPE_VALUES.length; i++) {
+ mAppIdValue = OMA_APPLICATION_ID_VALUES[rd.nextInt(
+ OMA_APPLICATION_ID_VALUES.length)];
+ mContentTypeValue =
+ OMA_CONTENT_TYPE_VALUES[rd.nextInt(OMA_CONTENT_TYPE_VALUES.length)];
+
+ mMessageBody = new byte[100 + rd.nextInt(100)];
+ rd.nextBytes(mMessageBody);
+
+ byte[] pdu = createPDU(3);
+ byte[] wappushPdu = retrieveWspBody();
+
+ try {
+ dataverify.resetData();
+ // set up data
+ if (isContentTypeMapped(mContentTypeValue)) {
+ // content type is mapped to integer value
+ mContentTypeName = getContentTypeName(mContentTypeValue);
+ Log.d(LOG_TAG, "mContentTypeValue mapping "
+ + mContentTypeValue + ":" + mContentTypeName);
+ } else {
+ mContentTypeName = Integer.toString(mContentTypeValue);
+ }
+
+ iwapman.addPackage(Integer.toString(mAppIdValue),
+ mContentTypeName, mPackageName, mClassName,
+ WapPushManagerParams.APP_TYPE_SERVICE, false, false);
+
+ dispatchWapPdu(wappushPdu, iwapman);
+
+ // clean up data
+ iwapman.deletePackage(Integer.toString(mAppIdValue),
+ mContentTypeName, mPackageName, mClassName);
+
+ if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
+ assertTrue(dataverify.verifyData(wappushPdu));
+ } else {
+ assertTrue(dataverify.verifyData(mMessageBody));
+ }
+ } catch (RemoteException e) {
+ }
+ }
+
+ mClassName = originalClassName;
+ mAppIdName = originalAppIdName;
+ mContentTypeName = originalContentTypeName;
+ mAppIdValue = originalAppIdValue;
+ mContentTypeValue = originalContentTypeValue;
+ mMessageBody = originalMessageBody;
+ }
+
+}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index f5f4c6e..75ef762 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -284,7 +284,7 @@
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
synchronized (mLock) {
if (mPointerLocationView != null) {
- mPointerLocationView.addTouchEvent(event);
+ mPointerLocationView.addPointerEvent(event);
handled = true;
}
}
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp
index 3082d45..bfc80db 100644
--- a/services/audioflinger/AudioPolicyManagerBase.cpp
+++ b/services/audioflinger/AudioPolicyManagerBase.cpp
@@ -1889,7 +1889,15 @@
mStreams[i].mVolDbAtt[StreamDescriptor::VOLMAX] = 0.0f;
}
- // TODO add modifications for music to have finer steps below knee1 and above knee2
+ // Modification for music: more attenuation for lower volumes, finer steps at high volumes
+ mStreams[AudioSystem::MUSIC].mVolIndex[StreamDescriptor::VOLMIN] = 1;
+ mStreams[AudioSystem::MUSIC].mVolDbAtt[StreamDescriptor::VOLMIN] = -58.0f;
+ mStreams[AudioSystem::MUSIC].mVolIndex[StreamDescriptor::VOLKNEE1] = 20;
+ mStreams[AudioSystem::MUSIC].mVolDbAtt[StreamDescriptor::VOLKNEE1] = -40.0f;
+ mStreams[AudioSystem::MUSIC].mVolIndex[StreamDescriptor::VOLKNEE2] = 60;
+ mStreams[AudioSystem::MUSIC].mVolDbAtt[StreamDescriptor::VOLKNEE2] = -17.0f;
+ mStreams[AudioSystem::MUSIC].mVolIndex[StreamDescriptor::VOLMAX] = 100;
+ mStreams[AudioSystem::MUSIC].mVolDbAtt[StreamDescriptor::VOLMAX] = 0.0f;
}
float AudioPolicyManagerBase::computeVolume(int stream, int index, audio_io_handle_t output, uint32_t device)
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index b31381a..25db25e 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -508,6 +508,7 @@
}
// Grab the next input event.
+ bool deviceWasRemoved = false;
for (;;) {
// Consume buffered input events, if any.
if (mInputBufferIndex < mInputBufferCount) {
@@ -558,6 +559,10 @@
int32_t readSize = read(pfd.fd, mInputBufferData,
sizeof(struct input_event) * INPUT_BUFFER_SIZE);
if (readSize < 0) {
+ if (errno == ENODEV) {
+ deviceWasRemoved = true;
+ break;
+ }
if (errno != EAGAIN && errno != EINTR) {
LOGW("could not get event (errno=%d)", errno);
}
@@ -570,6 +575,13 @@
}
}
+ // Handle the case where a device has been removed but INotify has not yet noticed.
+ if (deviceWasRemoved) {
+ AutoMutex _l(mLock);
+ closeDeviceAtIndexLocked(mInputFdIndex);
+ continue; // report added or removed devices immediately
+ }
+
#if HAVE_INOTIFY
// readNotify() will modify mFDs and mFDCount, so this must be done after
// processing all other events.
@@ -580,8 +592,6 @@
}
#endif
- mInputFdIndex = 0;
-
// Poll for events. Mind the wake lock dance!
// We hold a wake lock at all times except during poll(). This works due to some
// subtle choreography. When a device driver has pending (unread) events, it acquires
@@ -602,6 +612,9 @@
usleep(100000);
}
}
+
+ // Prepare to process all of the FDs we just polled.
+ mInputFdIndex = 0;
}
}
@@ -1008,37 +1021,42 @@
for (size_t i = FIRST_ACTUAL_DEVICE_INDEX; i < mDevices.size(); i++) {
Device* device = mDevices[i];
if (device->path == devicePath) {
- LOGI("Removed device: path=%s name=%s id=%d fd=%d classes=0x%x\n",
- device->path.string(), device->identifier.name.string(), device->id,
- device->fd, device->classes);
-
- for (int j=0; j<EV_SW; j++) {
- if (mSwitches[j] == device->id) {
- mSwitches[j] = 0;
- }
- }
-
- if (device->id == mBuiltInKeyboardId) {
- LOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
- device->path.string(), mBuiltInKeyboardId);
- mBuiltInKeyboardId = -1;
- clearKeyboardProperties(device, true);
- }
- clearKeyboardProperties(device, false);
-
- mFds.removeAt(i);
- mDevices.removeAt(i);
- device->close();
-
- device->next = mClosingDevices;
- mClosingDevices = device;
- return 0;
+ return closeDeviceAtIndexLocked(i);
}
}
- LOGE("remove device: %s not found\n", devicePath);
+ LOGV("Remove device: %s not found, device may already have been removed.", devicePath);
return -1;
}
+int EventHub::closeDeviceAtIndexLocked(int index) {
+ Device* device = mDevices[index];
+ LOGI("Removed device: path=%s name=%s id=%d fd=%d classes=0x%x\n",
+ device->path.string(), device->identifier.name.string(), device->id,
+ device->fd, device->classes);
+
+ for (int j=0; j<EV_SW; j++) {
+ if (mSwitches[j] == device->id) {
+ mSwitches[j] = 0;
+ }
+ }
+
+ if (device->id == mBuiltInKeyboardId) {
+ LOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
+ device->path.string(), mBuiltInKeyboardId);
+ mBuiltInKeyboardId = -1;
+ clearKeyboardProperties(device, true);
+ }
+ clearKeyboardProperties(device, false);
+
+ mFds.removeAt(index);
+ mDevices.removeAt(index);
+ device->close();
+
+ device->next = mClosingDevices;
+ mClosingDevices = device;
+ return 0;
+}
+
int EventHub::readNotify(int nfd) {
#ifdef HAVE_INOTIFY
int res;
diff --git a/services/input/EventHub.h b/services/input/EventHub.h
index 23bb344..f7936d2 100644
--- a/services/input/EventHub.h
+++ b/services/input/EventHub.h
@@ -261,6 +261,7 @@
int openDevice(const char *devicePath);
int closeDevice(const char *devicePath);
+ int closeDeviceAtIndexLocked(int index);
int scanDir(const char *dirname);
int readNotify(int nfd);
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 2e3f0bd..c064a9c 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -116,6 +116,7 @@
case AMOTION_EVENT_ACTION_MOVE:
case AMOTION_EVENT_ACTION_OUTSIDE:
case AMOTION_EVENT_ACTION_HOVER_MOVE:
+ case AMOTION_EVENT_ACTION_SCROLL:
return true;
case AMOTION_EVENT_ACTION_POINTER_DOWN:
case AMOTION_EVENT_ACTION_POINTER_UP: {
@@ -480,8 +481,7 @@
// If the application takes too long to catch up then we drop all events preceding
// the touch into the other window.
MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
- if ((motionEntry->action == AMOTION_EVENT_ACTION_DOWN
- || motionEntry->action == AMOTION_EVENT_ACTION_HOVER_MOVE)
+ if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
&& (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
&& mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
&& mInputTargetWaitApplication != NULL) {
@@ -1180,7 +1180,8 @@
&& (mTouchState.deviceId != entry->deviceId
|| mTouchState.source != entry->source);
if (maskedAction == AMOTION_EVENT_ACTION_DOWN
- || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
+ || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
+ || maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
if (wrongDevice && !down) {
mTempTouchState.copyFrom(mTouchState);
@@ -1205,8 +1206,9 @@
if (maskedAction == AMOTION_EVENT_ACTION_DOWN
|| (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)
- || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
- /* Case 1: New splittable pointer going down. */
+ || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
+ || maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
+ /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
int32_t pointerIndex = getMotionEventActionPointerIndex(action);
int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].
@@ -1380,8 +1382,10 @@
// If this is the first pointer going down and the touched window has a wallpaper
// then also add the touched wallpaper windows so they are locked in for the duration
// of the touch gesture.
- if (maskedAction == AMOTION_EVENT_ACTION_DOWN
- || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
+ // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
+ // engine only supports touch events. We would need to add a mechanism similar
+ // to View.onGenericMotionEvent to enable wallpapers to handle these events.
+ if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
if (foregroundWindow->hasWallpaper) {
for (size_t i = 0; i < mWindows.size(); i++) {
@@ -1423,7 +1427,7 @@
|| maskedAction == AMOTION_EVENT_ACTION_CANCEL
|| maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
// All pointers up or canceled.
- mTempTouchState.reset();
+ mTouchState.reset();
} else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
// First pointer went down.
if (mTouchState.down) {
@@ -1432,6 +1436,7 @@
LOGD("Pointer down received while already down.");
#endif
}
+ mTouchState.copyFrom(mTempTouchState);
} else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
// One pointer went up.
if (isSplit) {
@@ -1450,10 +1455,13 @@
i += 1;
}
}
+ mTouchState.copyFrom(mTempTouchState);
+ } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
+ // Discard temporary touch state since it was only valid for this action.
+ } else {
+ // Save changes to touch state as-is for all other actions.
+ mTouchState.copyFrom(mTempTouchState);
}
-
- // Save changes to touch state.
- mTouchState.copyFrom(mTempTouchState);
}
} else {
#if DEBUG_FOCUS
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index a963c72..a865d9f 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -1197,7 +1197,14 @@
switch (rawEvent->type) {
case EV_KEY:
switch (rawEvent->scanCode) {
- case BTN_MOUSE:
+ case BTN_LEFT:
+ case BTN_RIGHT:
+ case BTN_MIDDLE:
+ case BTN_SIDE:
+ case BTN_EXTRA:
+ case BTN_FORWARD:
+ case BTN_BACK:
+ case BTN_TASK:
mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE;
mAccumulator.btnMouse = rawEvent->value != 0;
// Sync now since BTN_MOUSE is not necessarily followed by SYN_REPORT and
@@ -1247,6 +1254,7 @@
int motionEventAction;
PointerCoords pointerCoords;
nsecs_t downTime;
+ float vscroll, hscroll;
{ // acquire lock
AutoMutex _l(mLock);
@@ -1331,10 +1339,14 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, mLocked.down ? 1.0f : 0.0f);
if (mHaveVWheel && (fields & Accumulator::FIELD_REL_WHEEL)) {
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, mAccumulator.relWheel);
+ vscroll = mAccumulator.relWheel;
+ } else {
+ vscroll = 0;
}
if (mHaveHWheel && (fields & Accumulator::FIELD_REL_HWHEEL)) {
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, mAccumulator.relHWheel);
+ hscroll = mAccumulator.relHWheel;
+ } else {
+ hscroll = 0;
}
} // release lock
@@ -1345,6 +1357,15 @@
1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);
mAccumulator.clear();
+
+ if (vscroll != 0 || hscroll != 0) {
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
+
+ getDispatcher()->notifyMotion(when, getDeviceId(), mSources, 0,
+ AMOTION_EVENT_ACTION_SCROLL, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
+ 1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);
+ }
}
int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index b7cc324..e3218c8 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -5812,8 +5812,7 @@
mDisplay = wm.getDefaultDisplay();
mInitialDisplayWidth = mDisplay.getWidth();
mInitialDisplayHeight = mDisplay.getHeight();
- mInputManager.setDisplaySize(0, Display.unmapDisplaySize(mInitialDisplayWidth),
- Display.unmapDisplaySize(mInitialDisplayHeight));
+ mInputManager.setDisplaySize(0, mDisplay.getRealWidth(), mDisplay.getRealHeight());
}
try {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fd3f0c2..40882d8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2470,7 +2470,7 @@
}
break;
}
- if (++name > 31)
+ if (++name >= SharedBufferStack::NUM_LAYERS_MAX)
name = NO_MEMORY;
} while(name >= 0);
diff --git a/telephony/java/com/android/internal/telephony/IWapPushManager.aidl b/telephony/java/com/android/internal/telephony/IWapPushManager.aidl
new file mode 100644
index 0000000..d5ecb94
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IWapPushManager.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 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.internal.telephony;
+
+import android.content.Intent;
+
+interface IWapPushManager {
+ /**
+ * Processes WAP push message and triggers the receiver application registered
+ * in the application ID table.
+ */
+ int processMessage(String app_id, String content_type, in Intent intent);
+
+ /**
+ * Add receiver application into the application ID table.
+ * Returns true if inserting the information is successfull. Inserting the duplicated
+ * record in the application ID table is not allowed. Use update/delete method.
+ */
+ boolean addPackage(String x_app_id, String content_type,
+ String package_name, String class_name,
+ int app_type, boolean need_signature, boolean further_processing);
+
+ /**
+ * Updates receiver application that is last added.
+ * Returns true if updating the information is successfull.
+ */
+ boolean updatePackage(String x_app_id, String content_type,
+ String package_name, String class_name,
+ int app_type, boolean need_signature, boolean further_processing);
+
+ /**
+ * Delites receiver application information.
+ * Returns true if deleting is successfull.
+ */
+ boolean deletePackage(String x_app_id, String content_type,
+ String package_name, String class_name);
+}
+
diff --git a/telephony/java/com/android/internal/telephony/WapPushManagerParams.java b/telephony/java/com/android/internal/telephony/WapPushManagerParams.java
new file mode 100644
index 0000000..11e5ff9
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/WapPushManagerParams.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010 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.internal.telephony;
+
+/**
+ * WapPushManager constant value definitions
+ */
+public class WapPushManagerParams {
+ /**
+ * Application type activity
+ */
+ public static final int APP_TYPE_ACTIVITY = 0;
+
+ /**
+ * Application type service
+ */
+ public static final int APP_TYPE_SERVICE = 1;
+
+ /**
+ * Process Message return value
+ * Message is handled
+ */
+ public static final int MESSAGE_HANDLED = 0x1;
+
+ /**
+ * Process Message return value
+ * Application ID or content type was not found in the application ID table
+ */
+ public static final int APP_QUERY_FAILED = 0x2;
+
+ /**
+ * Process Message return value
+ * Receiver application signature check failed
+ */
+ public static final int SIGNATURE_NO_MATCH = 0x4;
+
+ /**
+ * Process Message return value
+ * Receiver application was not found
+ */
+ public static final int INVALID_RECEIVER_NAME = 0x8;
+
+ /**
+ * Process Message return value
+ * Unknown exception
+ */
+ public static final int EXCEPTION_CAUGHT = 0x10;
+
+ /**
+ * Process Message return value
+ * Need further processing after WapPushManager message processing
+ */
+ public static final int FURTHER_PROCESSING = 0x8000;
+
+}
+
diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
index 2f5d3ec..7704667 100644
--- a/telephony/java/com/android/internal/telephony/WapPushOverSms.java
+++ b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
@@ -14,15 +14,20 @@
* limitations under the License.
*/
+
package com.android.internal.telephony;
import android.app.Activity;
import android.content.Context;
+import android.content.ComponentName;
import android.content.Intent;
+import android.content.ServiceConnection;
import android.provider.Telephony;
import android.provider.Telephony.Sms.Intents;
import android.util.Config;
import android.util.Log;
+import android.os.IBinder;
+import android.os.RemoteException;
/**
* WAP push handler class.
@@ -42,11 +47,83 @@
*/
private final int WAKE_LOCK_TIMEOUT = 5000;
+ private final int BIND_RETRY_INTERVAL = 1000;
+ /**
+ * A handle to WapPushManager interface
+ */
+ private WapPushConnection mWapConn = null;
+ private class WapPushConnection implements ServiceConnection {
+ private IWapPushManager mWapPushMan;
+ private Context mOwner;
+
+ public WapPushConnection(Context ownerContext) {
+ mOwner = ownerContext;
+ }
+
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ mWapPushMan = IWapPushManager.Stub.asInterface(service);
+ if (Config.DEBUG) Log.v(LOG_TAG, "wappush manager connected to " +
+ mOwner.hashCode());
+ }
+
+ public void onServiceDisconnected(ComponentName name) {
+ mWapPushMan = null;
+ if (Config.DEBUG) Log.v(LOG_TAG, "wappush manager disconnected.");
+ // WapPushManager must be always attached.
+ rebindWapPushManager();
+ }
+
+ /**
+ * bind WapPushManager
+ */
+ public void bindWapPushManager() {
+ if (mWapPushMan != null) return;
+
+ final ServiceConnection wapPushConnection = this;
+
+ mOwner.bindService(new Intent(IWapPushManager.class.getName()),
+ wapPushConnection, Context.BIND_AUTO_CREATE);
+ }
+
+ /**
+ * rebind WapPushManager
+ * This method is called when WapPushManager is disconnected unexpectedly.
+ */
+ private void rebindWapPushManager() {
+ if (mWapPushMan != null) return;
+
+ final ServiceConnection wapPushConnection = this;
+ new Thread() {
+ public void run() {
+ while (mWapPushMan == null) {
+ mOwner.bindService(new Intent(IWapPushManager.class.getName()),
+ wapPushConnection, Context.BIND_AUTO_CREATE);
+ try {
+ Thread.sleep(BIND_RETRY_INTERVAL);
+ } catch (InterruptedException e) {
+ if (Config.DEBUG) Log.v(LOG_TAG, "sleep interrupted.");
+ }
+ }
+ }
+ }.start();
+ }
+
+ /**
+ * Returns interface to WapPushManager
+ */
+ public IWapPushManager getWapPushManager() {
+ return mWapPushMan;
+ }
+ }
+
public WapPushOverSms(Phone phone, SMSDispatcher smsDispatcher) {
mSmsDispatcher = smsDispatcher;
mContext = phone.getContext();
+ mWapConn = new WapPushConnection(mContext);
+ mWapConn.bindWapPushManager();
}
+
/**
* Dispatches inbound messages that are in the WAP PDU format. See
* wap-230-wsp-20010705-a section 8 for details on the WAP PDU format.
@@ -106,16 +183,15 @@
}
String mimeType = pduDecoder.getValueString();
-
+ long binaryContentType = pduDecoder.getValue32();
index += pduDecoder.getDecodedDataLength();
byte[] header = new byte[headerLength];
System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
byte[] intentData;
- String permission;
- if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
+ if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
intentData = pdu;
} else {
int dataIndex = headerStartIndex + headerLength;
@@ -123,6 +199,62 @@
System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length);
}
+ /**
+ * Seek for application ID field in WSP header.
+ * If application ID is found, WapPushManager substitute the message
+ * processing. Since WapPushManager is optional module, if WapPushManager
+ * is not found, legacy message processing will be continued.
+ */
+ if (pduDecoder.seekXWapApplicationId(index, index + headerLength - 1)) {
+ index = (int) pduDecoder.getValue32();
+ pduDecoder.decodeXWapApplicationId(index);
+ String wapAppId = pduDecoder.getValueString();
+ if (wapAppId == null) {
+ wapAppId = Integer.toString((int) pduDecoder.getValue32());
+ }
+
+ String contentType = ((mimeType == null) ?
+ Long.toString(binaryContentType) : mimeType);
+ if (Config.DEBUG) Log.v(LOG_TAG, "appid found: " + wapAppId + ":" + contentType);
+
+ try {
+ boolean processFurther = true;
+ IWapPushManager wapPushMan = mWapConn.getWapPushManager();
+
+ if (wapPushMan == null) {
+ if (Config.DEBUG) Log.w(LOG_TAG, "wap push manager not found!");
+ } else {
+ Intent intent = new Intent();
+ intent.putExtra("transactionId", transactionId);
+ intent.putExtra("pduType", pduType);
+ intent.putExtra("header", header);
+ intent.putExtra("data", intentData);
+ intent.putExtra("contentTypeParameters",
+ pduDecoder.getContentParameters());
+
+ int procRet = wapPushMan.processMessage(wapAppId, contentType, intent);
+ if (Config.DEBUG) Log.v(LOG_TAG, "procRet:" + procRet);
+ if ((procRet & WapPushManagerParams.MESSAGE_HANDLED) > 0
+ && (procRet & WapPushManagerParams.FURTHER_PROCESSING) == 0) {
+ processFurther = false;
+ }
+ }
+ if (!processFurther) {
+ return Intents.RESULT_SMS_HANDLED;
+ }
+ } catch (RemoteException e) {
+ if (Config.DEBUG) Log.w(LOG_TAG, "remote func failed...");
+ }
+ }
+ if (Config.DEBUG) Log.v(LOG_TAG, "fall back to existing handler");
+
+ if (mimeType == null) {
+ if (Config.DEBUG) Log.w(LOG_TAG, "Header Content-Type error.");
+ return Intents.RESULT_SMS_GENERIC_ERROR;
+ }
+
+ String permission;
+
if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_MMS)) {
permission = "android.permission.RECEIVE_MMS";
} else {
@@ -141,4 +273,4 @@
return Activity.RESULT_OK;
}
-}
\ No newline at end of file
+}
diff --git a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
index 6bf6b13..c8dd718 100644
--- a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
+++ b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
@@ -37,6 +37,7 @@
private final static HashMap<Integer, String> WELL_KNOWN_PARAMETERS =
new HashMap<Integer, String>();
+ public static final int PARAMETER_ID_X_WAP_APPLICATION_ID = 0x2f;
private static final int Q_VALUE = 0x00;
static {
@@ -603,6 +604,70 @@
}
/**
+ * Seek for the "X-Wap-Application-Id" field for WSP pdu
+ *
+ * @param startIndex The starting position of seek pointer
+ * @param endIndex Valid seek area end point
+ *
+ * @return false when error(not a X-Wap-Application-Id) occur
+ * return value can be retrieved by getValue32()
+ */
+ public boolean seekXWapApplicationId(int startIndex, int endIndex) {
+ int index = startIndex;
+
+ try {
+ for (index = startIndex; index <= endIndex; ) {
+ /**
+ * 8.4.1.1 Field name
+ * Field name is integer or text.
+ */
+ if (decodeIntegerValue(index)) {
+ int fieldValue = (int) getValue32();
+
+ if (fieldValue == PARAMETER_ID_X_WAP_APPLICATION_ID) {
+ unsigned32bit = index + 1;
+ return true;
+ }
+ } else {
+ if (!decodeTextString(index)) return false;
+ }
+ index += getDecodedDataLength();
+ if (index > endIndex) return false;
+
+ /**
+ * 8.4.1.2 Field values
+ * Value Interpretation of First Octet
+ * 0 - 30 This octet is followed by the indicated number (0 - 30)
+ of data octets
+ * 31 This octet is followed by a uintvar, which indicates the number
+ * of data octets after it
+ * 32 - 127 The value is a text string, terminated by a zero octet
+ (NUL character)
+ * 128 - 255 It is an encoded 7-bit value; this header has no more data
+ */
+ byte val = wspData[index];
+ if (0 <= val && val <= WAP_PDU_SHORT_LENGTH_MAX) {
+ index += wspData[index] + 1;
+ } else if (val == WAP_PDU_LENGTH_QUOTE) {
+ if (index + 1 >= endIndex) return false;
+ index++;
+ if (!decodeUintvarInteger(index)) return false;
+ index += getDecodedDataLength();
+ } else if (WAP_PDU_LENGTH_QUOTE < val && val <= 127) {
+ if (!decodeTextString(index)) return false;
+ index += getDecodedDataLength();
+ } else {
+ index++;
+ }
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //seek application ID failed. WSP header might be corrupted
+ return false;
+ }
+ return false;
+ }
+
+ /**
* Decode the "X-Wap-Content-URI" type for WSP pdu
*
* @param startIndex The starting position of the "X-Wap-Content-URI" in this pdu
diff --git a/test-runner/src/android/test/SingleLaunchActivityTestCase.java b/test-runner/src/android/test/SingleLaunchActivityTestCase.java
index b63b3ce..79c554a 100644
--- a/test-runner/src/android/test/SingleLaunchActivityTestCase.java
+++ b/test-runner/src/android/test/SingleLaunchActivityTestCase.java
@@ -75,7 +75,7 @@
protected void tearDown() throws Exception {
// If it is the last test case, call finish on the activity.
sTestCaseCounter --;
- if (sTestCaseCounter == 1) {
+ if (sTestCaseCounter == 0) {
sActivity.finish();
}
super.tearDown();
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index c5aa573..15570e4 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -45,7 +45,7 @@
mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL),
- mMaxResVersion(NULL), mDebugMode(false), mProduct(NULL),
+ mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), mProduct(NULL),
mArgc(0), mArgv(NULL)
{}
~Bundle(void) {}
@@ -139,6 +139,8 @@
void setMaxResVersion(const char * val) { mMaxResVersion = val; }
bool getDebugMode() { return mDebugMode; }
void setDebugMode(bool val) { mDebugMode = val; }
+ bool getNonConstantId() { return mNonConstantId; }
+ void setNonConstantId(bool val) { mNonConstantId = val; }
const char* getProduct() const { return mProduct; }
void setProduct(const char * val) { mProduct = val; }
@@ -239,6 +241,7 @@
const char* mCustomPackage;
const char* mMaxResVersion;
bool mDebugMode;
+ bool mNonConstantId;
const char* mProduct;
/* file specification */
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 739b01f..266a02f 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -160,7 +160,11 @@
" product variants\n"
" --utf16\n"
" changes default encoding for resources to UTF-16. Only useful when API\n"
- " level is set to 7 or higher where the default encoding is UTF-8.\n");
+ " level is set to 7 or higher where the default encoding is UTF-8.\n"
+ " --non-constant-id\n"
+ " Make the resources ID non constant. This is required to make an R java class\n"
+ " that does not contain the final value but is used to make reusable compiled\n"
+ " libraries that need to access resources.\n");
}
/*
@@ -497,6 +501,8 @@
goto bail;
}
bundle.setProduct(argv[0]);
+ } else if (strcmp(cp, "-non-constant-id") == 0) {
+ bundle.setNonConstantId(true);
} else {
fprintf(stderr, "ERROR: Unknown option '-%s'\n", cp);
wantUsage = true;
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 7f84df6..730bd71 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -1723,7 +1723,8 @@
static status_t writeSymbolClass(
FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,
- const sp<AaptSymbols>& symbols, const String8& className, int indent)
+ const sp<AaptSymbols>& symbols, const String8& className, int indent,
+ bool nonConstantId)
{
fprintf(fp, "%spublic %sfinal class %s {\n",
getIndentSpace(indent),
@@ -1733,6 +1734,10 @@
size_t i;
status_t err = NO_ERROR;
+ const char * id_format = nonConstantId ?
+ "%spublic static int %s=0x%08x;\n" :
+ "%spublic static final int %s=0x%08x;\n";
+
size_t N = symbols->getSymbols().size();
for (i=0; i<N; i++) {
const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);
@@ -1785,7 +1790,7 @@
if (deprecated) {
fprintf(fp, "%s@Deprecated\n", getIndentSpace(indent));
}
- fprintf(fp, "%spublic static final int %s=0x%08x;\n",
+ fprintf(fp, id_format,
getIndentSpace(indent),
String8(name).string(), (int)sym.int32Val);
}
@@ -1836,7 +1841,7 @@
if (nclassName == "styleable") {
styleableSymbols = nsymbols;
} else {
- err = writeSymbolClass(fp, assets, includePrivate, nsymbols, nclassName, indent);
+ err = writeSymbolClass(fp, assets, includePrivate, nsymbols, nclassName, indent, nonConstantId);
}
if (err != NO_ERROR) {
return err;
@@ -1907,7 +1912,7 @@
"\n"
"package %s;\n\n", package.string());
- status_t err = writeSymbolClass(fp, assets, includePrivate, symbols, className, 0);
+ status_t err = writeSymbolClass(fp, assets, includePrivate, symbols, className, 0, bundle->getNonConstantId());
if (err != NO_ERROR) {
return err;
}