diff options
153 files changed, 5360 insertions, 4084 deletions
@@ -188,6 +188,7 @@ LOCAL_SRC_FILES += \ 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 \ @@ -416,8 +417,8 @@ web_docs_sample_code_flags := \ resources/samples/NotePad "Note Pad" \ -samplecode $(sample_dir)/SampleSyncAdapter \ resources/samples/SampleSyncAdapter "Sample Sync Adapter" \ - -samplecode frameworks/base/libs/rs/java \ - resources/samples/Renderscript "Renderscript" \ + -samplecode $(sample_dir)/RenderScript \ + resources/samples/RenderScript "RenderScript" \ -samplecode $(sample_dir)/SearchableDictionary \ resources/samples/SearchableDictionary "Searchable Dictionary v2" \ -samplecode $(sample_dir)/SipDemo \ diff --git a/api/current.xml b/api/current.xml index 007b0b1..83055bf 100644 --- a/api/current.xml +++ b/api/current.xml @@ -39936,7 +39936,7 @@ visibility="public" > </field> -<field name="resizableMode" +<field name="resizeMode" type="int" transient="false" volatile="false" 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_SRC_FILES:= \ 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 gWriteMP4; 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 @@ static void playSource(OMXClient *client, sp<MediaSource> &source) { 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 @@ static void usage(const char *me) { 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 @@ int main(int argc, char **argv) { bool dumpProfiles = false; bool extractThumbnail = false; bool seekTest = false; + bool useSurfaceAlloc = false; gNumRepetitions = 1; gMaxNumFrames = 0; gReproduceBug = -1; @@ -563,7 +575,7 @@ int main(int argc, char **argv) { 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 @@ int main(int argc, char **argv) { break; } + case 'S': + { + useSurfaceAlloc = true; + break; + } + case '?': case 'h': default: @@ -780,6 +798,39 @@ int main(int argc, char **argv) { } } + 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 @@ int main(int argc, char **argv) { } } + if (useSurfaceAlloc && !audioOnly) { + gSurface.clear(); + +#if USE_SURFACE_COMPOSER + composerClient->dispose(); +#endif + } + client.disconnect(); return 0; diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index 2e70a56..c91cdca 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -101,7 +101,6 @@ public class AccountManagerService private final IAccountAuthenticatorCache mAuthenticatorCache; private final DatabaseHelper mOpenHelper; - private final SimWatcher mSimWatcher; private static final String TABLE_ACCOUNTS = "accounts"; private static final String ACCOUNTS_ID = "_id"; @@ -208,7 +207,6 @@ public class AccountManagerService mAuthenticatorCache = authenticatorCache; mAuthenticatorCache.setListener(this, null /* Handler */); - mSimWatcher = new SimWatcher(mContext); sThis.set(this); validateAccountsAndPopulateCache(); @@ -1739,100 +1737,6 @@ public class AccountManagerService } } - private class SimWatcher extends BroadcastReceiver { - public SimWatcher(Context context) { - // Re-scan the SIM card when the SIM state changes, and also if - // the disk recovers from a full state (we may have failed to handle - // things properly while the disk was full). - final IntentFilter filter = new IntentFilter(); - filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); - filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK); - context.registerReceiver(this, filter); - } - - /** - * Compare the IMSI to the one stored in the login service's - * database. If they differ, erase all passwords and - * authtokens (and store the new IMSI). - */ - @Override - public void onReceive(Context context, Intent intent) { - // Check IMSI on every update; nothing happens if the IMSI - // is missing or unchanged. - TelephonyManager telephonyManager = - (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - if (telephonyManager == null) { - Log.w(TAG, "failed to get TelephonyManager"); - return; - } - String imsi = telephonyManager.getSubscriberId(); - - // If the subscriber ID is an empty string, don't do anything. - if (TextUtils.isEmpty(imsi)) return; - - // If the current IMSI matches what's stored, don't do anything. - String storedImsi = getMetaValue("imsi"); - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "current IMSI=" + imsi + "; stored IMSI=" + storedImsi); - } - if (imsi.equals(storedImsi)) return; - - // If a CDMA phone is unprovisioned, getSubscriberId() - // will return a different value, but we *don't* erase the - // passwords. We only erase them if it has a different - // subscriber ID once it's provisioned. - if (telephonyManager.getCurrentPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) { - IBinder service = ServiceManager.checkService(Context.TELEPHONY_SERVICE); - if (service == null) { - Log.w(TAG, "call to checkService(TELEPHONY_SERVICE) failed"); - return; - } - ITelephony telephony = ITelephony.Stub.asInterface(service); - if (telephony == null) { - Log.w(TAG, "failed to get ITelephony interface"); - return; - } - boolean needsProvisioning; - try { - needsProvisioning = telephony.needsOtaServiceProvisioning(); - } catch (RemoteException e) { - Log.w(TAG, "exception while checking provisioning", e); - // default to NOT wiping out the passwords - needsProvisioning = true; - } - if (needsProvisioning) { - // if the phone needs re-provisioning, don't do anything. - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "current IMSI=" + imsi + " (needs provisioning); stored IMSI=" + - storedImsi); - } - return; - } - } - - if (!imsi.equals(storedImsi) && !TextUtils.isEmpty(storedImsi)) { - Log.w(TAG, "wiping all passwords and authtokens because IMSI changed (" - + "stored=" + storedImsi + ", current=" + imsi + ")"); - SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - db.beginTransaction(); - try { - db.execSQL("DELETE from " + TABLE_AUTHTOKENS); - db.execSQL("UPDATE " + TABLE_ACCOUNTS + " SET " + ACCOUNTS_PASSWORD + " = ''"); - - synchronized (mCacheLock) { - mAuthTokenCache = new HashMap<Account, HashMap<String, String>>(); - } - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - sendAccountsChangedBroadcast(); - } - setMetaValue("imsi", imsi); - } - } - public IBinder onBind(Intent intent) { return asBinder(); } 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 @@ public class DownloadManager { /** * 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/FragmentManager.java b/core/java/android/app/FragmentManager.java index 52b3108..d8d0a5b 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -167,10 +167,9 @@ public abstract class FragmentManager { public static final int POP_BACK_STACK_INCLUSIVE = 1<<0; /** - * Pop the top state off the back stack. Returns true if there was one - * to pop, else false. This function is asynchronous -- it enqueues the - * request to pop, but the action will not be performed until the application - * returns to its event loop. + * Pop the top state off the back stack. This function is asynchronous -- it + * enqueues the request to pop, but the action will not be performed until the + * application returns to its event loop. */ public abstract void popBackStack(); diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java index 32c2397..b46802e 100644 --- a/core/java/android/appwidget/AppWidgetProviderInfo.java +++ b/core/java/android/appwidget/AppWidgetProviderInfo.java @@ -130,6 +130,9 @@ public class AppWidgetProviderInfo implements Parcelable { /** * The view id of the AppWidget subview which should be auto-advanced by the widget's host. + * + * <p>This field corresponds to the <code>android:autoAdvanceViewId</code> attribute in + * the AppWidget meta-data file. */ public int autoAdvanceViewId; @@ -146,8 +149,11 @@ public class AppWidgetProviderInfo implements Parcelable { * The rules by which a widget can be resized. See {@link #RESIZE_NONE}, * {@link #RESIZE_NONE}, {@link #RESIZE_HORIZONTAL}, * {@link #RESIZE_VERTICAL}, {@link #RESIZE_BOTH}. + * + * <p>This field corresponds to the <code>android:resizeMode</code> attribute in + * the AppWidget meta-data file. */ - public int resizableMode; + public int resizeMode; public AppWidgetProviderInfo() { } @@ -170,7 +176,7 @@ public class AppWidgetProviderInfo implements Parcelable { this.icon = in.readInt(); this.previewImage = in.readInt(); this.autoAdvanceViewId = in.readInt(); - this.resizableMode = in.readInt(); + this.resizeMode = in.readInt(); } public void writeToParcel(android.os.Parcel out, int flags) { @@ -194,7 +200,7 @@ public class AppWidgetProviderInfo implements Parcelable { out.writeInt(this.icon); out.writeInt(this.previewImage); out.writeInt(this.autoAdvanceViewId); - out.writeInt(this.resizableMode); + out.writeInt(this.resizeMode); } public int describeContents() { diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 31f8719..8944f12 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -31,6 +31,7 @@ import java.io.ObjectOutputStream; import java.io.Serializable; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -356,7 +357,7 @@ public final class Parcel { public final native void enforceInterface(String interfaceName); /** - * Write a byte array into the parcel at the current {#link #dataPosition}, + * Write a byte array into the parcel at the current {@link #dataPosition}, * growing {@link #dataCapacity} if needed. * @param b Bytes to place into the parcel. */ @@ -365,7 +366,7 @@ public final class Parcel { } /** - * Write an byte array into the parcel at the current {#link #dataPosition}, + * Write an byte array into the parcel at the current {@link #dataPosition}, * growing {@link #dataCapacity} if needed. * @param b Bytes to place into the parcel. * @param offset Index of first byte to be written. @@ -376,9 +377,7 @@ public final class Parcel { writeInt(-1); return; } - if (b.length < offset + len || len < 0 || offset < 0) { - throw new ArrayIndexOutOfBoundsException(); - } + Arrays.checkOffsetAndCount(b.length, offset, len); writeNative(b, offset, len); } 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 @@ public class DateUtils 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 @@ public class DateUtils * @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/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 @@ public class TimeUtils { 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 b748064..126f409 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -79,6 +79,11 @@ public class Display */ 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 @@ public class Display 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/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java index 218ee4f..0124151 100644 --- a/core/java/android/view/ScaleGestureDetector.java +++ b/core/java/android/view/ScaleGestureDetector.java @@ -245,6 +245,7 @@ public class ScaleGestureDetector { final float bottomSlop = mBottomSlopEdge; int index0 = event.findPointerIndex(mActiveId0); int index1 = event.findPointerIndex(mActiveId1); + float x0 = getRawX(event, index0); float y0 = getRawY(event, index0); float x1 = getRawX(event, index1); @@ -353,14 +354,24 @@ public class ScaleGestureDetector { if (actionId == mActiveId0) { final int newIndex = findNewActiveIndex(event, mActiveId1, actionIndex); if (newIndex >= 0) { + mListener.onScaleEnd(this); mActiveId0 = event.getPointerId(newIndex); + mActive0MostRecent = true; + mPrevEvent = MotionEvent.obtain(event); + setContext(event); + mGestureInProgress = mListener.onScaleBegin(this); } else { gestureEnded = true; } } else if (actionId == mActiveId1) { final int newIndex = findNewActiveIndex(event, mActiveId0, actionIndex); if (newIndex >= 0) { + mListener.onScaleEnd(this); mActiveId1 = event.getPointerId(newIndex); + mActive0MostRecent = false; + mPrevEvent = MotionEvent.obtain(event); + setContext(event); + mGestureInProgress = mListener.onScaleBegin(this); } else { gestureEnded = true; } @@ -449,6 +460,7 @@ public class ScaleGestureDetector { * MotionEvent has no getRawX(int) method; simulate it pending future API approval. */ private static float getRawX(MotionEvent event, int pointerIndex) { + if (pointerIndex < 0) return Float.MIN_VALUE; if (pointerIndex == 0) return event.getRawX(); float offset = event.getRawX() - event.getX(); return event.getX(pointerIndex) + offset; @@ -458,6 +470,7 @@ public class ScaleGestureDetector { * MotionEvent has no getRawY(int) method; simulate it pending future API approval. */ private static float getRawY(MotionEvent event, int pointerIndex) { + if (pointerIndex < 0) return Float.MIN_VALUE; if (pointerIndex == 0) return event.getRawY(); float offset = event.getRawY() - event.getY(); return event.getY(pointerIndex) + offset; 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 @@ class HTML5Audio extends Handler 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 @@ package android.webkit; 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 @@ public class L10nUtils { 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(); + } - mStrings = new Vector<String>(mIdsArray.length); - for (int i = 0; i < mIdsArray.length; i++) { - mStrings.add(context.getResources().getString(mIdsArray[i])); + private static String loadString(int id) { + if (mStrings == null) { + mStrings = new HashMap<Integer, SoftReference<String> >(mIdsArray.length); } + + 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 98fc290..f877fc8 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -987,7 +987,7 @@ public class WebView extends AbsoluteLayout 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 @@ -7768,11 +7768,11 @@ public class WebView extends AbsoluteLayout * 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 @@ -7798,13 +7798,12 @@ public class WebView extends AbsoluteLayout } 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. @@ -7911,6 +7910,7 @@ public class WebView extends AbsoluteLayout mAdapter = a; } + @Override public void onChanged() { // The filter may have changed which item is checked. Find the // item that the ListView thinks is checked. @@ -7931,15 +7931,12 @@ public class WebView extends AbsoluteLayout } } } - - 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); @@ -7977,7 +7974,7 @@ public class WebView extends AbsoluteLayout } } 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/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java index 5e0de27..6303850 100644 --- a/core/java/android/webkit/ZoomManager.java +++ b/core/java/android/webkit/ZoomManager.java @@ -227,10 +227,13 @@ class ZoomManager { assert density > 0; if (Math.abs(density - mDefaultScale) > MINIMUM_SCALE_INCREMENT) { + // Remember the current zoom density before it gets changed. + final float originalDefault = mDefaultScale; // set the new default density setDefaultZoomScale(density); + float scaleChange = (originalDefault > 0.0) ? density / originalDefault: 1.0f; // adjust the scale if it falls outside the new zoom bounds - setZoomScale(mActualScale, true); + setZoomScale(mActualScale * scaleChange, true); } } @@ -721,10 +724,7 @@ class ZoomManager { } public boolean onScale(ScaleGestureDetector detector) { - // Prevent scaling beyond overview scale. - float scale = Math.max( - computeScaleWithLimits(detector.getScaleFactor() * mActualScale), - getZoomOverviewScale()); + float scale = computeScaleWithLimits(detector.getScaleFactor() * mActualScale); if (mPinchToZoomAnimating || willScaleTriggerZoom(scale)) { mPinchToZoomAnimating = true; // limit the scale change per step @@ -780,13 +780,6 @@ class ZoomManager { // update mMinZoomScale if the minimum zoom scale is not fixed if (!mMinZoomScaleFixed) { - // when change from narrow screen to wide screen, the new viewWidth - // can be wider than the old content width. We limit the minimum - // scale to 1.0f. The proper minimum scale will be calculated when - // the new picture shows up. - mMinZoomScale = Math.min(1.0f, (float) mWebView.getViewWidth() - / (mWebView.drawHistory() ? mWebView.getHistoryPictureWidth() - : mZoomOverviewWidth)); // limit the minZoomScale to the initialScale if it is set if (mInitialScale > 0 && mInitialScale < mMinZoomScale) { mMinZoomScale = mInitialScale; @@ -823,7 +816,7 @@ class ZoomManager { // Keep overview mode unchanged when rotating. final float zoomOverviewScale = getZoomOverviewScale(); final float newScale = (mInZoomOverviewBeforeSizeChange) ? - zoomOverviewScale : Math.max(mActualScale, zoomOverviewScale); + zoomOverviewScale : mActualScale; setZoomScale(newScale, mUpdateTextWrap, true); // update the zoom buttons as the scale can be changed updateZoomPicker(); @@ -879,21 +872,15 @@ class ZoomManager { } } - if (!mMinZoomScaleFixed) { - mMinZoomScale = newZoomOverviewScale; - } // fit the content width to the current view for the first new picture // after first layout. boolean scaleHasDiff = exceedsMinScaleIncrement(newZoomOverviewScale, mActualScale); - // Make sure the actual scale is no less than zoom overview scale. - boolean scaleLessThanOverview = - (newZoomOverviewScale - mActualScale) >= MINIMUM_SCALE_INCREMENT; // Make sure mobile sites are correctly handled since mobile site will // change content width after rotating. boolean mobileSiteInOverview = mInZoomOverview && !exceedsMinScaleIncrement(newZoomOverviewScale, 1.0f); if (!mWebView.drawHistory() && - (mInitialZoomOverview || scaleLessThanOverview || mobileSiteInOverview) && + (mInitialZoomOverview || mobileSiteInOverview) && scaleHasDiff && zoomOverviewWidthChanged) { mInitialZoomOverview = false; setZoomScale(newZoomOverviewScale, !willScaleTriggerZoom(mTextWrapScale) && @@ -967,10 +954,11 @@ class ZoomManager { mTextWrapScale = viewState.mTextWrapScale; scale = viewState.mViewScale; } else { - scale = overviewScale; - if (!settings.getUseWideViewPort() - || !settings.getLoadWithOverviewMode()) { - scale = Math.max(viewState.mTextWrapScale, scale); + scale = mDefaultScale; + mTextWrapScale = mDefaultScale; + if (settings.getUseWideViewPort() + && settings.getLoadWithOverviewMode()) { + scale = Math.max(overviewScale, scale); } if (settings.isNarrowColumnLayout() && settings.getUseFixedViewport()) { @@ -981,7 +969,7 @@ class ZoomManager { } boolean reflowText = false; if (!viewState.mIsRestored) { - if (settings.getUseFixedViewport()) { + if (settings.getUseFixedViewport() && settings.getLoadWithOverviewMode()) { // Override the scale only in case of fixed viewport. scale = Math.max(scale, overviewScale); mTextWrapScale = Math.max(mTextWrapScale, overviewScale); diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index c2c8d16..1d05d0b 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -3529,6 +3529,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te post(this); } else { mTouchMode = TOUCH_MODE_REST; + reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } } 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 @@ public class EdgeGlow { mEdgeScaleY = mEdgeScaleYStart + (mEdgeScaleYFinish - mEdgeScaleYStart) * interp * factor; + mState = STATE_RECEDE; break; case STATE_RECEDE: mState = STATE_IDLE; 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 @@ public class NumberPicker extends LinearLayout { case MotionEvent.ACTION_DOWN: mLastMotionEventY = mLastDownEventY = event.getY(); removeAllCallbacks(); - hideInputControls(); + mShowInputControlsAnimator.cancel(); mBeginEditOnUpEvent = false; mAdjustScrollerOnUpEvent = true; if (mDrawSelectorWheel) { @@ -621,6 +621,7 @@ public class NumberPicker extends LinearLayout { } mBeginEditOnUpEvent = scrollersFinished; mAdjustScrollerOnUpEvent = true; + hideInputControls(); return true; } if (isEventInViewHitRect(event, mInputText) @@ -630,6 +631,7 @@ public class NumberPicker extends LinearLayout { && isEventInViewHitRect(event, mDecrementButton))) { mAdjustScrollerOnUpEvent = false; setDrawSelectorWheel(true); + hideInputControls(); return true; } break; @@ -640,6 +642,7 @@ public class NumberPicker extends LinearLayout { mBeginEditOnUpEvent = false; onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL); setDrawSelectorWheel(true); + hideInputControls(); return true; } break; diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java index 22f6f4e..d74ef24 100644 --- a/core/java/android/widget/TabWidget.java +++ b/core/java/android/widget/TabWidget.java @@ -174,8 +174,8 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener { void measureHorizontal(int widthMeasureSpec, int heightMeasureSpec) { // First, measure with no constraint final int unspecifiedWidth = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - super.measureHorizontal(unspecifiedWidth, heightMeasureSpec); mImposedTabsHeight = -1; + super.measureHorizontal(unspecifiedWidth, heightMeasureSpec); int extraWidth = getMeasuredWidth() - MeasureSpec.getSize(widthMeasureSpec); if (extraWidth > 0) { diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 33d1225..09c1ac5 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -7091,6 +7091,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // Only track when onStartTemporaryDetach() is called directly, // usually because this instance is an editable field in a list if (!mDispatchTemporaryDetach) mTemporaryDetach = true; + + // Because of View recycling in ListView, there is no easy way to know when a TextView with + // selection becomes visible again. Until a better solution is found, stop text selection + // mode (if any) as soon as this TextView is recycled. + stopSelectionActionMode(); } @Override diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 7a53874..7226e31 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -31,6 +31,8 @@ #include <binder/IPCThreadState.h> #include <utils/Log.h> #include <utils/SystemClock.h> +#include <utils/List.h> +#include <utils/KeyedVector.h> #include <cutils/logger.h> #include <binder/Parcel.h> #include <binder/ProcessState.h> @@ -322,25 +324,15 @@ private: class JavaBBinderHolder : public RefBase { public: - JavaBBinderHolder(JNIEnv* env, jobject object) - : mObject(object) - { - LOGV("Creating JavaBBinderHolder for Object %p\n", object); - } - ~JavaBBinderHolder() - { - LOGV("Destroying JavaBBinderHolder for Object %p\n", mObject); - } - - sp<JavaBBinder> get(JNIEnv* env) + sp<JavaBBinder> get(JNIEnv* env, jobject obj) { AutoMutex _l(mLock); sp<JavaBBinder> b = mBinder.promote(); if (b == NULL) { - b = new JavaBBinder(env, mObject); + b = new JavaBBinder(env, obj); mBinder = b; LOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%d\n", - b.get(), b->getWeakRefs(), mObject, b->getWeakRefs()->getWeakCount()); + b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount()); } return b; @@ -354,20 +346,41 @@ public: private: Mutex mLock; - jobject mObject; wp<JavaBBinder> mBinder; }; // ---------------------------------------------------------------------------- +// Per-IBinder death recipient bookkeeping. This is how we reconcile local jobject +// death recipient references passed in through JNI with the permanent corresponding +// JavaDeathRecipient objects. + +class JavaDeathRecipient; + +class DeathRecipientList : public RefBase { + List< sp<JavaDeathRecipient> > mList; + Mutex mLock; + +public: + ~DeathRecipientList(); + + void add(const sp<JavaDeathRecipient>& recipient); + void remove(const sp<JavaDeathRecipient>& recipient); + sp<JavaDeathRecipient> find(jobject recipient); +}; + +// ---------------------------------------------------------------------------- + class JavaDeathRecipient : public IBinder::DeathRecipient { public: - JavaDeathRecipient(JNIEnv* env, jobject object) - : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)), - mHoldsRef(true) + JavaDeathRecipient(JNIEnv* env, jobject object, sp<DeathRecipientList>& list) + : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)), mList(list) { - incStrong(this); + // These objects manage their own lifetimes so are responsible for final bookkeeping. + // The list holds a strong reference to this object. + mList->add(this); + android_atomic_inc(&gNumDeathRefs); incRefsCreated(env); } @@ -391,16 +404,12 @@ public: void clearReference() { - bool release = false; - mLock.lock(); - if (mHoldsRef) { - mHoldsRef = false; - release = true; - } - mLock.unlock(); - if (release) { - decStrong(this); - } + mList->remove(this); + } + + bool matches(jobject obj) { + JNIEnv* env = javavm_to_jnienv(mVM); + return env->IsSameObject(obj, mObject); } protected: @@ -415,12 +424,57 @@ protected: private: JavaVM* const mVM; jobject const mObject; - Mutex mLock; - bool mHoldsRef; + sp<DeathRecipientList> mList; }; // ---------------------------------------------------------------------------- +DeathRecipientList::~DeathRecipientList() { + AutoMutex _l(mLock); + + // Should never happen -- the JavaDeathRecipient objects that have added themselves + // to the list are holding references on the list object. Only when they are torn + // down can the list header be destroyed. + if (mList.size() > 0) { + LOGE("Retiring binder %p with extant death recipients\n", this); + } +} + +void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) { + AutoMutex _l(mLock); + + mList.push_back(recipient); +} + +void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) { + AutoMutex _l(mLock); + + List< sp<JavaDeathRecipient> >::iterator iter; + for (iter = mList.begin(); iter != mList.end(); iter++) { + if (*iter == recipient) { + mList.erase(iter); + return; + } + } +} + +sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) { + AutoMutex _l(mLock); + + List< sp<JavaDeathRecipient> >::iterator iter; + for (iter = mList.begin(); iter != mList.end(); iter++) { + if ((*iter)->matches(recipient)) { + return *iter; + } + } + return NULL; +} + +static KeyedVector<IBinder*, sp<DeathRecipientList> > gDeathRecipientsByIBinder; +static Mutex gDeathRecipientMapLock; + +// ---------------------------------------------------------------------------- + namespace android { static void proxy_cleanup(const void* id, void* obj, void* cleanupCookie) @@ -490,7 +544,7 @@ sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) { JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetIntField(obj, gBinderOffsets.mObject); - return jbh != NULL ? jbh->get(env) : NULL; + return jbh != NULL ? jbh->get(env, obj) : NULL; } if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { @@ -621,26 +675,26 @@ static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz) IPCThreadState::self()->flushCommands(); } -static void android_os_Binder_init(JNIEnv* env, jobject clazz) +static void android_os_Binder_init(JNIEnv* env, jobject obj) { - JavaBBinderHolder* jbh = new JavaBBinderHolder(env, clazz); + JavaBBinderHolder* jbh = new JavaBBinderHolder(); if (jbh == NULL) { jniThrowException(env, "java/lang/OutOfMemoryError", NULL); return; } - LOGV("Java Binder %p: acquiring first ref on holder %p", clazz, jbh); - jbh->incStrong(clazz); - env->SetIntField(clazz, gBinderOffsets.mObject, (int)jbh); + LOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh); + jbh->incStrong((void*)android_os_Binder_init); + env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh); } -static void android_os_Binder_destroy(JNIEnv* env, jobject clazz) +static void android_os_Binder_destroy(JNIEnv* env, jobject obj) { JavaBBinderHolder* jbh = (JavaBBinderHolder*) - env->GetIntField(clazz, gBinderOffsets.mObject); + env->GetIntField(obj, gBinderOffsets.mObject); if (jbh != NULL) { - env->SetIntField(clazz, gBinderOffsets.mObject, 0); - LOGV("Java Binder %p: removing ref on holder %p", clazz, jbh); - jbh->decStrong(clazz); + env->SetIntField(obj, gBinderOffsets.mObject, 0); + LOGV("Java Binder %p: removing ref on holder %p", obj, jbh); + jbh->decStrong((void*)android_os_Binder_init); } else { // Encountering an uninitialized binder is harmless. All it means is that // the Binder was only partially initialized when its finalizer ran and called @@ -648,7 +702,7 @@ static void android_os_Binder_destroy(JNIEnv* env, jobject clazz) // For example, a Binder subclass constructor might have thrown an exception before // it could delegate to its superclass's constructor. Consequently init() would // not have been called and the holder pointer would remain NULL. - LOGV("Java Binder %p: ignoring uninitialized binder", clazz); + LOGV("Java Binder %p: ignoring uninitialized binder", obj); } } @@ -973,8 +1027,25 @@ static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj, LOGV("linkToDeath: binder=%p recipient=%p\n", target, recipient); if (!target->localBinder()) { - sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient); - status_t err = target->linkToDeath(jdr, recipient, flags); + sp<JavaDeathRecipient> jdr; + + { + sp<DeathRecipientList> list; + AutoMutex _maplocker(gDeathRecipientMapLock); + + ssize_t listIndex = gDeathRecipientsByIBinder.indexOfKey(target); + if (listIndex < 0) { + // Set up the death notice bookkeeping for this binder lazily + list = new DeathRecipientList; + gDeathRecipientsByIBinder.add(target, list); + } else { + list = gDeathRecipientsByIBinder.valueAt(listIndex); + } + + jdr = new JavaDeathRecipient(env, recipient, list); + } + + status_t err = target->linkToDeath(jdr, NULL, flags); if (err != NO_ERROR) { // Failure adding the death recipient, so clear its reference // now. @@ -1003,15 +1074,33 @@ static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj, LOGV("unlinkToDeath: binder=%p recipient=%p\n", target, recipient); if (!target->localBinder()) { - wp<IBinder::DeathRecipient> dr; - status_t err = target->unlinkToDeath(NULL, recipient, flags, &dr); - if (err == NO_ERROR && dr != NULL) { - sp<IBinder::DeathRecipient> sdr = dr.promote(); - JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get()); - if (jdr != NULL) { - jdr->clearReference(); + status_t err = NAME_NOT_FOUND; + sp<JavaDeathRecipient> origJDR; + { + AutoMutex _maplocker(gDeathRecipientMapLock); + ssize_t listIndex = gDeathRecipientsByIBinder.indexOfKey(target); + if (listIndex >= 0) { + sp<DeathRecipientList> list = gDeathRecipientsByIBinder.valueAt(listIndex); + origJDR = list->find(recipient); + } else { + // If there is no DeathRecipientList for this binder, it means the binder + // is dead and in the process of being cleaned up. + err = DEAD_OBJECT; + } + } + // If we found the matching recipient, proceed to unlink using that + if (origJDR != NULL) { + wp<IBinder::DeathRecipient> dr; + err = target->unlinkToDeath(origJDR, NULL, flags, &dr); + if (err == NO_ERROR && dr != NULL) { + sp<IBinder::DeathRecipient> sdr = dr.promote(); + JavaDeathRecipient* jdr = static_cast<JavaDeathRecipient*>(sdr.get()); + if (jdr != NULL) { + jdr->clearReference(); + } } } + if (err == NO_ERROR || err == DEAD_OBJECT) { res = JNI_TRUE; } else { @@ -1031,6 +1120,15 @@ static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj) env->SetIntField(obj, gBinderProxyOffsets.mObject, 0); b->decStrong(obj); IPCThreadState::self()->flushCommands(); + + // tear down the death recipient bookkeeping + { + AutoMutex _maplocker(gDeathRecipientMapLock); + ssize_t listIndex = gDeathRecipientsByIBinder.indexOfKey(b); + if (listIndex >= 0) { + gDeathRecipientsByIBinder.removeItemsAt((size_t)listIndex); + } + } } // ---------------------------------------------------------------------------- @@ -1152,15 +1250,13 @@ static void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz, if (parcel == NULL) { return; } - void *dest; const status_t err = parcel->writeInt32(length); if (err != NO_ERROR) { jniThrowException(env, "java/lang/OutOfMemoryError", NULL); } - dest = parcel->writeInplace(length); - + void* dest = parcel->writeInplace(length); if (dest == NULL) { jniThrowException(env, "java/lang/OutOfMemoryError", NULL); return; @@ -1168,7 +1264,7 @@ static void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz, jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0); if (ar) { - memcpy(dest, ar, length); + memcpy(dest, ar + offset, length); env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0); } } 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 @@ struct offsets_t { }; static offsets_t offsets; +static int gShortSize = -1; +static int gLongSize = -1; static int gOldSize = -1; static int gNewSize = -1; @@ -76,6 +78,10 @@ static jint android_view_Display_getWidth( { 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 @@ static jint android_view_Display_getHeight( { 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 @@ static jint android_view_Display_getDisplayCount( 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 @@ static JNINativeMethod gMethods[] = { (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 register_android_view_Display(JNIEnv* env) 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 @@ int register_android_view_Display(JNIEnv* env) } }; - diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index be66e9c..bd2e669 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -177,7 +177,7 @@ static sp<Surface> getSurface(JNIEnv* env, jobject clazz) sp<ANativeWindow> android_Surface_getNativeWindow( JNIEnv* env, jobject clazz) { - return getSurface(env, clazz).get(); + return getSurface(env, clazz); } static void setSurface(JNIEnv* env, jobject clazz, const sp<Surface>& surface) diff --git a/libs/rs/java/HelloCompute/AndroidManifest.xml b/core/res/res/layout/webview_select_singlechoice.xml index 8c7ac2f..c0753a8 100644 --- a/libs/rs/java/HelloCompute/AndroidManifest.xml +++ b/core/res/res/layout/webview_select_singlechoice.xml @@ -4,9 +4,9 @@ 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. @@ -14,17 +14,17 @@ 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> +<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 c02a3f1..8ef9a3b 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/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 @@ home=true </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/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js index e919de9..14118bb 100644 --- a/docs/html/resources/resources-data.js +++ b/docs/html/resources/resources-data.js @@ -497,12 +497,12 @@ var ANDROID_RESOURCES = [ }, { tags: ['sample', 'new', 'newfeature', 'performance', 'gamedev', 'gl'], - path: 'samples/Renderscript/index.html', + path: 'samples/RenderScript/index.html', title: { - en: 'Renderscript' + en: 'RenderScript' }, description: { - en: 'A set of samples that demonstrate how to use various features of the Renderscript APIs.' + en: 'A set of samples that demonstrate how to use various features of the RenderScript APIs.' } }, { diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java index 4fc419c..fae22f0 100644 --- a/graphics/java/android/renderscript/Element.java +++ b/graphics/java/android/renderscript/Element.java @@ -21,7 +21,7 @@ import android.util.Log; /** * <p>The most basic data type. An element represents one cell of a memory allocation. - * Element is the basic data type of Renderscript. An element can be of two forms: Basic elements or Complex forms. + * Element is the basic data type of Renderscript. An element can be of two forms: Basic elements or Complex forms. * Examples of basic elements are:</p> * <ul> * <li>Single float value</li> @@ -29,7 +29,7 @@ import android.util.Log; * <li>single RGB-565 color</li> * <li>single unsigned int 16</li> * </ul> - * <p>Complex elements contain a list of sub-elements and names that + * <p>Complex elements contain a list of sub-elements and names that * represents a structure of data. The fields can be accessed by name * from a script or shader. The memory layout is defined and ordered. Data * alignment is determinied by the most basic primitive type. i.e. a float4 @@ -403,7 +403,7 @@ public class Element extends BaseObj { if(rs.mElement_MATRIX_3X3 == null) { rs.mElement_MATRIX_3X3 = createUser(rs, DataType.MATRIX_3X3); } - return rs.mElement_MATRIX_4X4; + return rs.mElement_MATRIX_3X3; } public static Element MATRIX_2X2(RenderScript rs) { diff --git a/include/binder/IBinder.h b/include/binder/IBinder.h index 749a977..81b56c2 100644 --- a/include/binder/IBinder.h +++ b/include/binder/IBinder.h @@ -98,7 +98,7 @@ public: * Register the @a recipient for a notification if this binder * goes away. If this binder object unexpectedly goes away * (typically because its hosting process has been killed), - * then DeathRecipient::binderDied() will be called with a referene + * then DeathRecipient::binderDied() will be called with a reference * to this. * * The @a cookie is optional -- if non-NULL, it should be a diff --git a/include/utils/StrongPointer.h b/include/utils/StrongPointer.h index a8c9897..49fa3a8 100644 --- a/include/utils/StrongPointer.h +++ b/include/utils/StrongPointer.h @@ -133,7 +133,7 @@ sp<T>::sp(const sp<T>& other) template<typename T> template<typename U> sp<T>::sp(U* other) : m_ptr(other) { - if (other) other->incStrong(this); + if (other) ((T*)other)->incStrong(this); } template<typename T> template<typename U> @@ -170,7 +170,7 @@ sp<T>& sp<T>::operator = (T* other) template<typename T> template<typename U> sp<T>& sp<T>::operator = (const sp<U>& other) { - U* otherPtr(other.m_ptr); + T* otherPtr(other.m_ptr); if (otherPtr) otherPtr->incStrong(this); if (m_ptr) m_ptr->decStrong(this); m_ptr = otherPtr; @@ -180,7 +180,7 @@ sp<T>& sp<T>::operator = (const sp<U>& other) template<typename T> template<typename U> sp<T>& sp<T>::operator = (U* other) { - if (other) other->incStrong(this); + if (other) ((T*)other)->incStrong(this); if (m_ptr) m_ptr->decStrong(this); m_ptr = other; return *this; 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 @@ LOCAL_MODULE_TAGS := optional 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 Binary files differdeleted file mode 100644 index 3a5c970..0000000 --- a/libs/rs/java/Balls/res/drawable/flares.png +++ /dev/null diff --git a/libs/rs/java/Balls/res/drawable/test_pattern.png b/libs/rs/java/Balls/res/drawable/test_pattern.png Binary files differdeleted file mode 100644 index e7d1455..0000000 --- a/libs/rs/java/Balls/res/drawable/test_pattern.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index e7d1455..0000000 --- a/libs/rs/java/Fountain/res/drawable/test_pattern.png +++ /dev/null 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/_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 Binary files differdeleted file mode 100644 index 81a87b1..0000000 --- a/libs/rs/java/HelloCompute/res/drawable/data.jpg +++ /dev/null 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/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 Binary files differdeleted file mode 100644 index e7d1455..0000000 --- a/libs/rs/java/HelloWorld/res/drawable/test_pattern.png +++ /dev/null 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 f63015e..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 Binary files differdeleted file mode 100644 index b631e1e..0000000 --- a/libs/rs/java/Samples/res/drawable/checker.png +++ /dev/null diff --git a/libs/rs/java/Samples/res/drawable/cubemap_test.png b/libs/rs/java/Samples/res/drawable/cubemap_test.png Binary files differdeleted file mode 100644 index baf35d0..0000000 --- a/libs/rs/java/Samples/res/drawable/cubemap_test.png +++ /dev/null diff --git a/libs/rs/java/Samples/res/drawable/data.png b/libs/rs/java/Samples/res/drawable/data.png Binary files differdeleted file mode 100644 index 8e34714..0000000 --- a/libs/rs/java/Samples/res/drawable/data.png +++ /dev/null diff --git a/libs/rs/java/Samples/res/drawable/leaf.png b/libs/rs/java/Samples/res/drawable/leaf.png Binary files differdeleted file mode 100644 index 3cd3775..0000000 --- a/libs/rs/java/Samples/res/drawable/leaf.png +++ /dev/null diff --git a/libs/rs/java/Samples/res/drawable/test_pattern.png b/libs/rs/java/Samples/res/drawable/test_pattern.png Binary files differdeleted file mode 100644 index e7d1455..0000000 --- a/libs/rs/java/Samples/res/drawable/test_pattern.png +++ /dev/null diff --git a/libs/rs/java/Samples/res/drawable/torusmap.png b/libs/rs/java/Samples/res/drawable/torusmap.png Binary files differdeleted file mode 100644 index 1e08f3b..0000000 --- a/libs/rs/java/Samples/res/drawable/torusmap.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index 0322b01..0000000 --- a/libs/rs/java/Samples/res/raw/torus.a3d +++ /dev/null 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/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp index 1e9bd74..68611d6 100644 --- a/libs/surfaceflinger_client/Surface.cpp +++ b/libs/surfaceflinger_client/Surface.cpp @@ -1040,7 +1040,7 @@ int Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const // e.g. if GraphicBuffer is used to wrap an android_native_buffer_t that // was dequeued from an ANativeWindow. for (size_t i = 0; i < mBuffers.size(); i++) { - if (buffer->handle == mBuffers[i]->handle) { + if (mBuffers[i] != 0 && buffer->handle == mBuffers[i]->handle) { idx = mBuffers[i]->getIndex(); break; } diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp index 0fd404d..bb6c125 100644 --- a/libs/utils/RefBase.cpp +++ b/libs/utils/RefBase.cpp @@ -99,20 +99,38 @@ public: #if DEBUG_REFS_FATAL_SANITY_CHECKS LOG_ALWAYS_FATAL("Strong references remain!"); #else - LOGE("Strong references remain!"); + LOGE("Strong references remain:"); #endif + ref_entry* refs = mStrongRefs; + while (refs) { + char inc = refs->ref >= 0 ? '+' : '-'; + LOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref); +#if DEBUG_REFS_CALLSTACK_ENABLED + refs->stack.dump(); +#endif; + refs = refs->next; + } } if (!mRetain && mWeakRefs != NULL) { dumpStack = true; #if DEBUG_REFS_FATAL_SANITY_CHECKS - LOG_ALWAYS_FATAL("Weak references remain!"); + LOG_ALWAYS_FATAL("Weak references remain:"); #else LOGE("Weak references remain!"); #endif + ref_entry* refs = mWeakRefs; + while (refs) { + char inc = refs->ref >= 0 ? '+' : '-'; + LOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref); +#if DEBUG_REFS_CALLSTACK_ENABLED + refs->stack.dump(); +#endif; + refs = refs->next; + } } - if (dumpStack) { + LOGE("above errors at:"); CallStack stack; stack.update(); stack.dump(); @@ -228,7 +246,8 @@ private: if (mTrackEnabled) { AutoMutex _l(mMutex); - ref_entry* ref = *refs; + ref_entry* const head = *refs; + ref_entry* ref = head; while (ref != NULL) { if (ref->id == id) { *refs = ref->next; @@ -249,6 +268,13 @@ private: "(weakref_type %p) that doesn't exist!", id, mBase, this); + ref = head; + while (ref) { + char inc = ref->ref >= 0 ? '+' : '-'; + LOGD("\t%c ID %p (ref %d):", inc, ref->id, ref->ref); + ref = ref->next; + } + CallStack stack; stack.update(); stack.dump(); 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.os.RemoteException; 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 @@ public class GpsNetInitiatedHandler { */ 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 = ""; - - 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; + final char PADDING_CHAR = 0x00; + int lengthBytes = input.length; + int lengthSeptets = (lengthBytes * 8) / 7; + String decoded; + + /* 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 @@ public class AudioService extends IAudioService.Stub { if (!checkAudioSettingsPermission("startBluetoothSco()")) { return; } - ScoClient client = getScoClient(cb); + ScoClient client = getScoClient(cb, true); client.incCount(); } @@ -1227,8 +1227,10 @@ public class AudioService extends IAudioService.Stub { 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 class AudioService extends IAudioService.Stub { } } - 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 @@ public class AudioService extends IAudioService.Stub { 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 @@ class MediaArtistNativeHelper { 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 @@ class MediaArtistNativeHelper { 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 @@ public class MediaProperties { * 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 @@ public class MediaProperties { @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.Log; 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 @@ public class VideoEditorImpl implements VideoEditor { */ private MediaArtistNativeHelper mMANativeHelper; private boolean mPreviewInProgress = false; + private final boolean mMallocDebug; /** * Constructor @@ -142,6 +146,18 @@ public class VideoEditorImpl implements VideoEditor { * 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 @@ public class VideoEditorImpl implements VideoEditor { 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 @@ public class VideoEditorImpl implements VideoEditor { unlock(); } } + if (mMallocDebug) { + try { + dumpHeap("HeapAtEnd"); + } catch (Exception ex) { + Log.e(TAG, "dumpHeap returned error in release"); + } + } } /* @@ -1885,4 +1910,32 @@ public class VideoEditorImpl implements VideoEditor { } 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 @@ videoEditor_populateSettings( 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 @@ DRMExtractor::DRMExtractor(const sp<DataSource> &source, const char* mime) 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 @@ sp<MediaExtractor> MediaExtractor::Create( 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 @@ sp<MediaExtractor> MediaExtractor::Create( } ++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 @@ VideoFrame *StagefrightMetadataRetriever::getFrameAtTime( 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::convertCbYCrY( 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/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java index 988b229..a6cf355 100755 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java @@ -21,9 +21,10 @@ import com.android.mediaframeworktest.performance.MediaPlayerPerformance; import com.android.mediaframeworktest.performance.VideoEditorPerformance; import junit.framework.TestSuite; +import android.os.Bundle; import android.test.InstrumentationTestRunner; import android.test.InstrumentationTestSuite; - +import android.util.Log; /** * Instrumentation Test Runner for all MediaPlayer tests. @@ -36,19 +37,30 @@ import android.test.InstrumentationTestSuite; public class MediaFrameworkPerfTestRunner extends InstrumentationTestRunner { + public static boolean mGetNativeHeapDump = false; + + + @Override + public TestSuite getAllTests() { + TestSuite suite = new InstrumentationTestSuite(this); + suite.addTestSuite(MediaPlayerPerformance.class); + /* Video Editor performance Test cases */ + suite.addTestSuite(VideoEditorPerformance.class); + return suite; + } - @Override - public TestSuite getAllTests() { - TestSuite suite = new InstrumentationTestSuite(this); - suite.addTestSuite(MediaPlayerPerformance.class); - /*Video Editor performance Test cases*/ - suite.addTestSuite(VideoEditorPerformance.class); - return suite; - } + @Override + public ClassLoader getLoader() { + return MediaFrameworkTestRunner.class.getClassLoader(); + } - @Override - public ClassLoader getLoader() { - return MediaFrameworkTestRunner.class.getClassLoader(); - } + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + String get_heap_dump = (String) icicle.get("get_heap_dump"); + if (get_heap_dump != null) { + mGetNativeHeapDump = true; + } + } } diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaTestUtil.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaTestUtil.java new file mode 100755 index 0000000..0183b5d --- /dev/null +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaTestUtil.java @@ -0,0 +1,45 @@ +/* + * 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.mediaframeworktest; + +import java.io.FileOutputStream; + +import android.os.Debug; +import android.os.Environment; + +/** + * + * Utilities for media framework test. + * + */ +public class MediaTestUtil { + private MediaTestUtil(){ + } + + private static final String STORAGE_PATH = + Environment.getExternalStorageDirectory().toString(); + + //Catpure the heapdump for memory leaksage analysis\ + public static void getNativeHeapDump (String name) throws Exception { + System.gc(); + System.runFinalization(); + Thread.sleep(1000); + FileOutputStream o = new FileOutputStream(STORAGE_PATH + '/' +name + ".dump"); + Debug.dumpNativeHeap(o.getFD()); + o.close(); + } +}
\ No newline at end of file diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java index ce6db68..82df669 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java @@ -28,7 +28,7 @@ import android.media.MediaRecorder; import android.media.EncoderCapabilities; import android.media.EncoderCapabilities.VideoEncoderCap; import android.media.EncoderCapabilities.AudioEncoderCap; -import android.test.ActivityInstrumentationTestCase; +import android.test.ActivityInstrumentationTestCase2; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; @@ -42,7 +42,7 @@ import java.util.List; /** * Junit / Instrumentation test case for the media recorder api */ -public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFrameworkTest> { +public class MediaRecorderTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> { private String TAG = "MediaRecorderTest"; private int mOutputDuration =0; private int mOutputVideoWidth = 0; @@ -62,9 +62,9 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram } protected void setUp() throws Exception { - super.setUp(); - Log.v(TAG,"create the media recorder"); + getActivity(); mRecorder = new MediaRecorder(); + super.setUp(); } private void recordVideo(int frameRate, int width, int height, @@ -199,8 +199,6 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram return false; } - - private void getOutputVideoProperty(String outputFilePath) { MediaPlayer mediaPlayer = new MediaPlayer(); try { @@ -215,8 +213,6 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram Thread.sleep(1000); mOutputVideoHeight = mediaPlayer.getVideoHeight(); mOutputVideoWidth = mediaPlayer.getVideoWidth(); - //mOutputVideoHeight = CodecTest.videoHeight(outputFilePath); - //mOutputVideoWidth = CodecTest.videoWidth(outputFilePath); mediaPlayer.release(); } catch (Exception e) { Log.v(TAG, e.toString()); @@ -224,11 +220,6 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram } } - private void removeFile(String filePath) { - File fileRemove = new File(filePath); - fileRemove.delete(); - } - private boolean validateVideo(String filePath, int width, int height) { boolean validVideo = false; getOutputVideoProperty(filePath); @@ -237,72 +228,9 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram validVideo = true; } Log.v(TAG, "width = " + mOutputVideoWidth + " height = " + mOutputVideoHeight + " Duration = " + mOutputDuration); - //removeFile(filePath); return validVideo; } - - - //Format: HVGA h263 - @Suppress - public void testHVGAH263() throws Exception { - boolean videoRecordedResult = false; - recordVideo(15, 480, 320, MediaRecorder.VideoEncoder.H263, - MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_HVGA_H263, false); - videoRecordedResult = validateVideo(MediaNames.RECORDED_HVGA_H263, 480, 320); - assertTrue("HVGAH263", videoRecordedResult); - } - - //Format: QVGA h263 - @Suppress - public void testQVGAH263() throws Exception { - boolean videoRecordedResult = false; - recordVideo(15, 320, 240, MediaRecorder.VideoEncoder.H263, - MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_QVGA_H263, false); - videoRecordedResult = validateVideo(MediaNames.RECORDED_QVGA_H263, 320, 240); - assertTrue("QVGAH263", videoRecordedResult); - } - - //Format: SQVGA h263 - @Suppress - public void testSQVGAH263() throws Exception { - boolean videoRecordedResult = false; - recordVideo(15, 240, 160, MediaRecorder.VideoEncoder.H263, - MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_SQVGA_H263, false); - videoRecordedResult = validateVideo(MediaNames.RECORDED_SQVGA_H263, 240, 160); - assertTrue("SQVGAH263", videoRecordedResult); - } - - //Format: QCIF h263 - @LargeTest - public void testQCIFH263() throws Exception { - boolean videoRecordedResult = false; - recordVideo(15, 176, 144, MediaRecorder.VideoEncoder.H263, - MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_QCIF_H263, false); - videoRecordedResult = validateVideo(MediaNames.RECORDED_QCIF_H263, 176, 144); - assertTrue("QCIFH263", videoRecordedResult); - } - - //Format: CIF h263 - @LargeTest - public void testCIFH263() throws Exception { - boolean videoRecordedResult = false; - recordVideo(15, 352, 288, MediaRecorder.VideoEncoder.H263, - MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_CIF_H263, false); - videoRecordedResult = validateVideo(MediaNames.RECORDED_CIF_H263, 352, 288); - assertTrue("CIFH263", videoRecordedResult); - } - - - - @LargeTest - public void testVideoOnly() throws Exception { - boolean videoRecordedResult = false; - recordVideo(15, 176, 144, MediaRecorder.VideoEncoder.H263, - MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, true); - videoRecordedResult = validateVideo(MediaNames.RECORDED_VIDEO_3GP, 176, 144); - assertTrue("QCIFH263 Video Only", videoRecordedResult); - } - + @LargeTest /* * This test case set the camera in portrait mode. @@ -332,74 +260,6 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram assertTrue("PortraitH263", videoRecordedResult); } - @Suppress - public void testHVGAMP4() throws Exception { - boolean videoRecordedResult = false; - recordVideo(15, 480, 320, MediaRecorder.VideoEncoder.MPEG_4_SP, - MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_HVGA_MP4, false); - videoRecordedResult = validateVideo(MediaNames.RECORDED_HVGA_MP4, 480, 320); - assertTrue("HVGAMP4", videoRecordedResult); - } - - @Suppress - public void testQVGAMP4() throws Exception { - boolean videoRecordedResult = false; - recordVideo(15, 320, 240, MediaRecorder.VideoEncoder.MPEG_4_SP, - MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_QVGA_MP4, false); - videoRecordedResult = validateVideo(MediaNames.RECORDED_QVGA_MP4, 320, 240); - assertTrue("QVGAMP4", videoRecordedResult); - } - - @Suppress - public void testSQVGAMP4() throws Exception { - boolean videoRecordedResult = false; - recordVideo(15, 240, 160, MediaRecorder.VideoEncoder.MPEG_4_SP, - MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_SQVGA_MP4, false); - videoRecordedResult = validateVideo(MediaNames.RECORDED_SQVGA_MP4, 240, 160); - assertTrue("SQVGAMP4", videoRecordedResult); - } - - //Format: QCIF MP4 - @LargeTest - public void testQCIFMP4() throws Exception { - boolean videoRecordedResult = false; - recordVideo(15, 176, 144, MediaRecorder.VideoEncoder.MPEG_4_SP, - MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_QCIF_MP4, false); - videoRecordedResult = validateVideo(MediaNames.RECORDED_QCIF_MP4, 176, 144); - assertTrue("QCIFMP4", videoRecordedResult); - } - - - //Format: CIF MP4 - @LargeTest - public void testCIFMP4() throws Exception { - boolean videoRecordedResult = false; - recordVideo(15, 352, 288, MediaRecorder.VideoEncoder.MPEG_4_SP, - MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_CIF_MP4, false); - videoRecordedResult = validateVideo(MediaNames.RECORDED_CIF_MP4, 352, 288); - assertTrue("CIFMP4", videoRecordedResult); - } - - - //Format: CIF MP4 output format 3gpp - @LargeTest - public void testCIFMP43GPP() throws Exception { - boolean videoRecordedResult = false; - recordVideo(15, 352, 288, MediaRecorder.VideoEncoder.MPEG_4_SP, - MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false); - videoRecordedResult = validateVideo(MediaNames.RECORDED_VIDEO_3GP, 352, 288); - assertTrue("CIFMP4 3GPP", videoRecordedResult); - } - - @LargeTest - public void testQCIFH2633GPP() throws Exception { - boolean videoRecordedResult = false; - recordVideo(15, 176, 144, MediaRecorder.VideoEncoder.H263, - MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false); - videoRecordedResult = validateVideo(MediaNames.RECORDED_VIDEO_3GP, 176, 144); - assertTrue("QCIFH263 3GPP", videoRecordedResult); - } - @LargeTest public void testInvalidVideoPath() throws Exception { boolean isTestInvalidVideoPathSuccessful = false; @@ -408,23 +268,6 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram assertTrue("Invalid outputFile Path", isTestInvalidVideoPathSuccessful); } - @Suppress - public void testInvalidVideoSize() throws Exception { - boolean isTestInvalidVideoSizeSuccessful = false; - isTestInvalidVideoSizeSuccessful = invalidRecordSetting(15, 800, 600, MediaRecorder.VideoEncoder.H263, - MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false); - assertTrue("Invalid video Size", isTestInvalidVideoSizeSuccessful); - } - - @Suppress - @LargeTest - public void testInvalidFrameRate() throws Exception { - boolean isTestInvalidFrameRateSuccessful = false; - isTestInvalidFrameRateSuccessful = invalidRecordSetting(50, 176, 144, MediaRecorder.VideoEncoder.H263, - MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false); - assertTrue("Invalid FrameRate", isTestInvalidFrameRateSuccessful); - } - @LargeTest //test cases for the new codec public void testDeviceSpecificCodec() throws Exception { diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java index 0e3029b..34affa7 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java @@ -17,7 +17,9 @@ package com.android.mediaframeworktest.performance; import com.android.mediaframeworktest.MediaFrameworkTest; +import com.android.mediaframeworktest.MediaFrameworkPerfTestRunner; import com.android.mediaframeworktest.MediaNames; +import com.android.mediaframeworktest.MediaTestUtil; import android.database.sqlite.SQLiteDatabase; import android.hardware.Camera; @@ -27,7 +29,7 @@ import android.media.MediaRecorder; import android.os.ConditionVariable; import android.os.Looper; import android.os.SystemClock; -import android.test.ActivityInstrumentationTestCase; +import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.Suppress; import android.util.Log; @@ -52,7 +54,7 @@ import android.hardware.Camera.PreviewCallback; * Junit / Instrumentation - performance measurement for media player and * recorder */ -public class MediaPlayerPerformance extends ActivityInstrumentationTestCase<MediaFrameworkTest> { +public class MediaPlayerPerformance extends ActivityInstrumentationTestCase2<MediaFrameworkTest> { private String TAG = "MediaPlayerPerformance"; @@ -87,6 +89,15 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase<Medi protected void setUp() throws Exception { super.setUp(); + getActivity(); + if (MediaFrameworkPerfTestRunner.mGetNativeHeapDump) + MediaTestUtil.getNativeHeapDump(this.getName() + "_before"); + } + + protected void tearDown() throws Exception { + super.tearDown(); + if (MediaFrameworkPerfTestRunner.mGetNativeHeapDump) + MediaTestUtil.getNativeHeapDump(this.getName() + "_after"); } public void createDB() { diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png Binary files differindex e4d5a32..7b54daf 100644 --- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg.png b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg.png Binary files differindex 9f72549..87a67c9 100644 --- a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg.png +++ b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg.png diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png Binary files differnew file mode 100644 index 0000000..7f86fb3 --- /dev/null +++ b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_thumbnail_bg_press.png diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml b/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml index d7e1633..bfa6c36 100644 --- a/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml +++ b/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml @@ -22,14 +22,14 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="wrap_content" - android:layout_width="156dip"> + android:layout_width="@dimen/status_bar_recents_thumbnail_view_width"> <ImageView android:id="@+id/app_thumbnail" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" - android:layout_marginLeft="105dip" + android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin" android:scaleType="center" /> @@ -40,8 +40,8 @@ android:layout_alignParentTop="true" android:layout_marginLeft="123dip" android:layout_marginTop="16dip" - android:maxWidth="64dip" - android:maxHeight="64dip" + android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width" + android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height" android:adjustViewBounds="true" /> diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml index ecd2b6f..4be57a2 100644 --- a/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml +++ b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml @@ -36,36 +36,35 @@ <LinearLayout android:id="@+id/recents_glow" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:orientation="horizontal" - android:layout_marginBottom="-28dip" + android:layout_marginBottom="-52dip" android:layout_gravity="bottom" - android:background="@drawable/recents_blue_glow"> + android:background="@drawable/recents_blue_glow" + android:orientation="horizontal" + > - <LinearLayout android:id="@+id/recents_container" - android:layout_width="356dip" + <ListView android:id="@+id/recents_container" + android:layout_width="@dimen/status_bar_recents_width" android:layout_height="wrap_content" - android:orientation="vertical" android:layout_marginRight="100dip" + android:divider="@null" + android:scrollingCache="true" + android:stackFromBottom="true" + android:fadingEdge="vertical" + android:scrollbars="none" + android:fadingEdgeLength="30dip" + android:listSelector="@drawable/recents_thumbnail_bg_press" /> </LinearLayout> </FrameLayout> - <!-- The outer FrameLayout is just used as an opaque background for the dismiss icon --> - <FrameLayout + <View android:id="@+id/recents_dismiss_button" android:layout_width="80px" android:layout_height="@*android:dimen/status_bar_height" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" - android:background="#ff000000"> - - <View android:id="@+id/recents_dismiss_button" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@drawable/ic_sysbar_back_ime" - /> - - </FrameLayout> + android:background="@drawable/ic_sysbar_back_ime" + /> </com.android.systemui.statusbar.tablet.RecentAppsPanel> diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel_footer.xml b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel_footer.xml new file mode 100644 index 0000000..4d14d1f --- /dev/null +++ b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel_footer.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* apps/common/assets/default/default/skins/StatusBar.xml +** +** Copyright 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. +*/ +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/listview_footer_padding" + android:layout_height="24dip" + android:layout_width="match_parent"> +</FrameLayout> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 93cf377..88cd43c 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -2,21 +2,34 @@ <!-- * Copyright (c) 2006, 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 + * 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 + * 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 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and * limitations under the License. */ --> <resources> <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. --> <dimen name="status_bar_edge_ignore">5dp</dimen> + + <!-- Recent Applications parameters --> + <!-- Width of a recent app view, including all content --> + <dimen name="status_bar_recents_thumbnail_view_width">156dp</dimen> + <!-- How far the thumbnail for a recent app appears from left edge --> + <dimen name="status_bar_recents_thumbnail_left_margin">110dp</dimen> + <!-- Upper width limit for application icon --> + <dimen name="status_bar_recents_thumbnail_max_width">64dp</dimen> + <!-- Upper height limit for application icon --> + <dimen name="status_bar_recents_thumbnail_max_height">64dp</dimen> + <!-- Width of scrollable area in recents --> + <dimen name="status_bar_recents_width">356dp</dimen> + </resources> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java index e0d558f..ebe1a7c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java @@ -40,37 +40,43 @@ import android.graphics.RectF; import android.graphics.Shader.TileMode; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.os.Parcelable; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.util.Slog; +import android.view.LayoutInflater; import android.view.View; -import android.view.View.OnClickListener; -import android.view.animation.DecelerateInterpolator; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.BaseAdapter; import android.widget.ImageView; -import android.widget.LinearLayout; +import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; import com.android.systemui.R; -public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, OnClickListener { +public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, OnItemClickListener { private static final int GLOW_PADDING = 15; private static final String TAG = "RecentAppsPanel"; private static final boolean DEBUG = TabletStatusBar.DEBUG; - private static final int DISPLAY_TASKS_PORTRAIT = 7; // Limited by max binder transaction size - private static final int DISPLAY_TASKS_LANDSCAPE = 5; // number of recent tasks to display - private static final int MAX_TASKS = DISPLAY_TASKS_PORTRAIT + 1; // allow extra for non-apps + private static final int DISPLAY_TASKS = 20; + private static final int MAX_TASKS = DISPLAY_TASKS + 1; // allow extra for non-apps + private static final int BOTTOM_OFFSET = 28; // TODO: Get from dimens.xml private TabletStatusBar mBar; private ArrayList<ActivityDescription> mActivityDescriptions; private int mIconDpi; private View mRecentsScrim; private View mRecentsGlowView; - private LinearLayout mRecentsContainer; + private ListView mRecentsContainer; private Bitmap mGlowBitmap; private boolean mShowing; private Choreographer mChoreo; private View mRecentsDismissButton; + private ActvityDescriptionAdapter mListAdapter; + protected int mLastVisibleItem; static class ActivityDescription { int id; @@ -98,6 +104,63 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O } }; + private static class ViewHolder { + private ImageView thumbnailView; + private ImageView iconView; + private TextView labelView; + private TextView descriptionView; + private ActivityDescription activityDescription; + } + + private class ActvityDescriptionAdapter extends BaseAdapter { + private LayoutInflater mInflater; + + public ActvityDescriptionAdapter(Context context) { + mInflater = LayoutInflater.from(context); + } + + public int getCount() { + return mActivityDescriptions != null ? mActivityDescriptions.size() : 0; + } + + public Object getItem(int position) { + return position; // we only need the index + } + + public long getItemId(int position) { + return position; // we just need something unique for this position + } + + public View getView(int position, View convertView, ViewGroup parent) { + ViewHolder holder; + if (convertView == null) { + convertView = mInflater.inflate(R.layout.status_bar_recent_item, null); + holder = new ViewHolder(); + holder.thumbnailView = (ImageView) convertView.findViewById(R.id.app_thumbnail); + holder.iconView = (ImageView) convertView.findViewById(R.id.app_icon); + holder.labelView = (TextView) convertView.findViewById(R.id.app_label); + holder.descriptionView = (TextView) convertView.findViewById(R.id.app_description); + convertView.setTag(holder); + } else { + holder = (ViewHolder) convertView.getTag(); + } + + // activityId is reverse since most recent appears at the bottom... + final int activityId = mActivityDescriptions.size() - position - 1; + + final ActivityDescription activityDescription = mActivityDescriptions.get(activityId); + final Bitmap thumb = activityDescription.thumbnail; + holder.thumbnailView.setImageBitmap(compositeBitmap(mGlowBitmap, thumb)); + holder.iconView.setImageDrawable(activityDescription.icon); + holder.labelView.setText(activityDescription.label); + holder.descriptionView.setText(activityDescription.description); + holder.thumbnailView.setTag(activityDescription); + holder.activityDescription = activityDescription; + + return convertView; + } + } + public boolean isInContentArea(int x, int y) { // use mRecentsContainer's exact bounds to determine horizontal position final int l = mRecentsContainer.getLeft(); @@ -267,9 +330,41 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O } @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + // Keep track of the last visible item in the list so we can restore it + // to the bottom when the orientation changes. + int childCount = mRecentsContainer.getChildCount(); + if (childCount > 0) { + mLastVisibleItem = mRecentsContainer.getFirstVisiblePosition() + childCount - 1; + View view = mRecentsContainer.getChildAt(childCount - 1); + final int distanceFromBottom = mRecentsContainer.getHeight() - view.getTop(); + //final int distanceFromBottom = view.getHeight() + BOTTOM_OFFSET; + + // This has to happen post-layout, so run it "in the future" + post(new Runnable() { + public void run() { + mRecentsContainer.setSelectionFromTop(mLastVisibleItem, + mRecentsContainer.getHeight() - distanceFromBottom); + } + }); + } + } + + @Override protected void onFinishInflate() { super.onFinishInflate(); - mRecentsContainer = (LinearLayout) findViewById(R.id.recents_container); + LayoutInflater inflater = (LayoutInflater) + mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + mRecentsContainer = (ListView) findViewById(R.id.recents_container); + View footer = inflater.inflate(R.layout.status_bar_recent_panel_footer, + mRecentsContainer, false); + mRecentsContainer.setScrollbarFadingEnabled(true); + mRecentsContainer.addFooterView(footer); + mRecentsContainer.setAdapter(mListAdapter = new ActvityDescriptionAdapter(mContext)); + mRecentsContainer.setOnItemClickListener(this); + mRecentsGlowView = findViewById(R.id.recents_glow); mRecentsScrim = (View) findViewById(R.id.recents_bg_protect); mChoreo = new Choreographer(this, mRecentsScrim, mRecentsGlowView); @@ -287,20 +382,16 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O } @Override - protected void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - // we show more in portrait mode, so update UI if orientation changes - updateUiElements(newConfig, false); - } - - @Override protected void onVisibilityChanged(View changedView, int visibility) { super.onVisibilityChanged(changedView, visibility); if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + changedView + ", " + visibility + ")"); if (visibility == View.VISIBLE && changedView == this) { refreshApplicationList(); - mRecentsContainer.setScrollbarFadingEnabled(true); - mRecentsContainer.scrollTo(0, 0); + post(new Runnable() { + public void run() { + mRecentsContainer.setSelection(mActivityDescriptions.size() - 1); + } + }); } } @@ -402,11 +493,12 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O private void refreshApplicationList() { mActivityDescriptions = getRecentTasks(); + mListAdapter.notifyDataSetInvalidated(); if (mActivityDescriptions.size() > 0) { - updateUiElements(getResources().getConfiguration(), true); + mLastVisibleItem = mActivityDescriptions.size() - 1; // scroll to bottom after reloading + updateUiElements(getResources().getConfiguration()); } else { // Immediately hide this panel - mShowing = false; hide(false); } } @@ -426,44 +518,29 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O canvas.drawBitmap(thumbnail, new Rect(0, 0, srcWidth-1, srcHeight-1), new RectF(GLOW_PADDING, - GLOW_PADDING - 4.0f, - outBitmap.getWidth() - GLOW_PADDING + 2.0f, - outBitmap.getHeight() - GLOW_PADDING + 3.0f), paint); + GLOW_PADDING - 7.0f, + outBitmap.getWidth() - GLOW_PADDING + 3.0f, + outBitmap.getHeight() - GLOW_PADDING + 7.0f), paint); } return outBitmap; } - private void updateUiElements(Configuration config, boolean animate) { - mRecentsContainer.removeAllViews(); - - final int first = 0; - final boolean isPortrait = config.orientation == Configuration.ORIENTATION_PORTRAIT; - final int taskCount = isPortrait ? DISPLAY_TASKS_PORTRAIT : DISPLAY_TASKS_LANDSCAPE; - final int last = Math.min(mActivityDescriptions.size(), taskCount) - 1; - for (int i = last; i >= first; i--) { - ActivityDescription activityDescription = mActivityDescriptions.get(i); - View view = View.inflate(mContext, R.layout.status_bar_recent_item, null); - ImageView appThumbnail = (ImageView) view.findViewById(R.id.app_thumbnail); - ImageView appIcon = (ImageView) view.findViewById(R.id.app_icon); - TextView appLabel = (TextView) view.findViewById(R.id.app_label); - TextView appDesc = (TextView) view.findViewById(R.id.app_description); - final Bitmap thumb = activityDescription.thumbnail; - appThumbnail.setImageBitmap(compositeBitmap(mGlowBitmap, thumb)); - appIcon.setImageDrawable(activityDescription.icon); - appLabel.setText(activityDescription.label); - appDesc.setText(activityDescription.description); - appThumbnail.setOnClickListener(this); - appThumbnail.setTag(activityDescription); - mRecentsContainer.addView(view); - } + private void updateUiElements(Configuration config) { + final int items = mActivityDescriptions.size(); + + mRecentsContainer.setVisibility(items > 0 ? View.VISIBLE : View.GONE); + mRecentsGlowView.setVisibility(items > 0 ? View.VISIBLE : View.GONE); + } - int views = mRecentsContainer.getChildCount(); - mRecentsContainer.setVisibility(views > 0 ? View.VISIBLE : View.GONE); - mRecentsGlowView.setVisibility(views > 0 ? View.VISIBLE : View.GONE); + private void hide(boolean animate) { + if (!animate) { + setVisibility(View.GONE); + } + mBar.animateCollapse(); } - public void onClick(View v) { - ActivityDescription ad = (ActivityDescription)v.getTag(); + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + ActivityDescription ad = ((ViewHolder) view.getTag()).activityDescription; final ActivityManager am = (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE); if (ad.id >= 0) { @@ -478,11 +555,4 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O } hide(true); } - - private void hide(boolean animate) { - setVisibility(View.GONE); - if (animate) { - mBar.animateCollapse(); - } - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index 233d601..f0408a2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -267,6 +267,8 @@ public class TabletStatusBar extends StatusBar implements lp.gravity = Gravity.BOTTOM | Gravity.LEFT; lp.setTitle("RecentsPanel"); lp.windowAnimations = R.style.Animation_RecentPanel; + lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED + | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; WindowManagerImpl.getDefault().addView(mRecentsPanel, lp); mRecentsPanel.setBar(this); @@ -509,7 +511,7 @@ public class TabletStatusBar extends StatusBar implements final int peekIndex = m.arg1; if (peekIndex < N) { //Slog.d(TAG, "loading peek: " + peekIndex); - NotificationData.Entry entry = + NotificationData.Entry entry = mNotificationDNDMode ? mNotificationDNDDummyEntry : mNotificationData.get(N-1-peekIndex); @@ -555,7 +557,7 @@ public class TabletStatusBar extends StatusBar implements final int N = mNotificationData.size(); if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) { - NotificationData.Entry entry = + NotificationData.Entry entry = mNotificationDNDMode ? mNotificationDNDDummyEntry : mNotificationData.get(N-1-mNotificationPeekIndex); @@ -584,6 +586,8 @@ public class TabletStatusBar extends StatusBar implements case MSG_OPEN_RECENTS_PANEL: if (DEBUG) Slog.d(TAG, "opening recents panel"); if (mRecentsPanel != null) { + disable(StatusBarManager.DISABLE_NAVIGATION + | StatusBarManager.DISABLE_BACK); mRecentsPanel.setVisibility(View.VISIBLE); mRecentsPanel.show(true, true); } @@ -591,6 +595,7 @@ public class TabletStatusBar extends StatusBar implements case MSG_CLOSE_RECENTS_PANEL: if (DEBUG) Slog.d(TAG, "closing recents panel"); if (mRecentsPanel != null && mRecentsPanel.isShowing()) { + disable(StatusBarManager.DISABLE_NONE); mRecentsPanel.show(false, true); } break; @@ -701,7 +706,7 @@ public class TabletStatusBar extends StatusBar implements && oldContentView.getLayoutId() == contentView.getLayoutId(); ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent(); boolean orderUnchanged = notification.notification.when==oldNotification.notification.when - && notification.priority == oldNotification.priority; + && notification.priority == oldNotification.priority; // priority now encompasses isOngoing() boolean isLastAnyway = rowParent.indexOfChild(oldEntry.row) == rowParent.getChildCount()-1; if (contentsUnchanged && (orderUnchanged || isLastAnyway)) { 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 Binary files differnew file mode 100644 index 0000000..8074c4c --- /dev/null +++ b/packages/WAPPushManager/tests/res/drawable-hdpi/icon.png diff --git a/packages/WAPPushManager/tests/res/drawable-ldpi/icon.png b/packages/WAPPushManager/tests/res/drawable-ldpi/icon.png Binary files differnew file mode 100644 index 0000000..1095584 --- /dev/null +++ b/packages/WAPPushManager/tests/res/drawable-ldpi/icon.png diff --git a/packages/WAPPushManager/tests/res/drawable-mdpi/icon.png b/packages/WAPPushManager/tests/res/drawable-mdpi/icon.png Binary files differnew file mode 100644 index 0000000..a07c69f --- /dev/null +++ b/packages/WAPPushManager/tests/res/drawable-mdpi/icon.png 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/libs/rs/java/HelloCompute/src/com/android/example/hellocompute/mono.rs b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/IDataVerify.aidl index 9647c61..f0670fa 100644 --- a/libs/rs/java/HelloCompute/src/com/android/example/hellocompute/mono.rs +++ b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/IDataVerify.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 The Android Open Source Project + * 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. @@ -14,23 +14,20 @@ * limitations under the License. */ -#pragma version(1) -#pragma rs java_package_name(com.android.example.hellocompute) +package com.android.smspush.unitTests; -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); -} +/** + * Interface to receiver application data verifyer class + */ +interface IDataVerify { + /** + * Verify data + */ + boolean verifyData(in byte[] pdu); -void filter() { - rsForEach(gScript, gIn, gOut, 0); + /** + * 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/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 @@ void AudioPolicyManagerBase::initializeVolumeCurves() { 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/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index afa8d69..f28e2b1 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -1029,7 +1029,7 @@ class AppWidgetService extends IAppWidgetService.Stub com.android.internal.R.styleable.AppWidgetProviderInfo_previewImage, 0); info.autoAdvanceViewId = sa.getResourceId( com.android.internal.R.styleable.AppWidgetProviderInfo_autoAdvanceViewId, -1); - info.resizableMode = sa.getInt( + info.resizeMode = sa.getInt( com.android.internal.R.styleable.AppWidgetProviderInfo_resizeMode, AppWidgetProviderInfo.RESIZE_NONE); 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const } 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 @@ public class WapPushOverSms { */ 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 @@ public class WapPushOverSms { } 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 @@ public class WapPushOverSms { 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 @@ public class WapPushOverSms { 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 @@ public class WspTypeDecoder { 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 @@ public class WspTypeDecoder { } /** + * 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 @@ public abstract class SingleLaunchActivityTestCase<T extends Activity> 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 @@ public: 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 @@ public: 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 @@ private: 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 @@ void usage(void) " 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 @@ int main(int argc, char* const argv[]) 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 writeLayoutClasses( 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 @@ static status_t writeSymbolClass( 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 @@ static status_t writeSymbolClass( 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 @@ static status_t writeSymbolClass( 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 @@ status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets, "\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; } |