summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.xml292
-rw-r--r--cmds/installd/commands.c28
-rw-r--r--cmds/installd/installd.c14
-rw-r--r--cmds/installd/installd.h6
-rw-r--r--core/java/android/app/ActionBar.java148
-rw-r--r--core/java/android/app/BackStackEntry.java4
-rw-r--r--core/java/android/app/ContextImpl.java101
-rw-r--r--core/java/android/app/FragmentTransaction.java6
-rw-r--r--core/java/android/app/NativeActivity.java13
-rw-r--r--core/java/android/app/backup/SharedPreferencesBackupHelper.java8
-rw-r--r--core/java/android/database/sqlite/SQLiteClosable.java15
-rw-r--r--core/java/android/database/sqlite/SQLiteCompiledSql.java25
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabase.java45
-rw-r--r--core/java/android/database/sqlite/SQLiteProgram.java12
-rw-r--r--core/java/android/database/sqlite/SQLiteUnfinalizedObjectsException.java31
-rw-r--r--core/java/android/os/BatteryStats.java47
-rw-r--r--core/java/android/text/method/ArrowKeyMovementMethod.java14
-rw-r--r--core/java/android/util/TimeUtils.java181
-rw-r--r--core/java/android/view/View.java12
-rw-r--r--core/java/android/view/ViewDebug.java9
-rw-r--r--core/java/android/view/ViewGroup.java5
-rw-r--r--core/java/android/view/ViewRoot.java14
-rw-r--r--core/java/android/webkit/WebSettings.java21
-rw-r--r--core/java/android/webkit/ZoomManager.java3
-rw-r--r--core/java/android/widget/AdapterViewAnimator.java96
-rw-r--r--core/java/android/widget/QuickContactBadge.java3
-rw-r--r--core/java/android/widget/StackView.java384
-rw-r--r--core/java/com/android/internal/app/ActionBarImpl.java137
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java14
-rw-r--r--core/java/com/android/internal/widget/ActionBarView.java82
-rw-r--r--core/jni/android_app_NativeActivity.cpp7
-rw-r--r--core/jni/android_database_SQLiteDatabase.cpp3
-rw-r--r--core/jni/android_util_Process.cpp3
-rw-r--r--core/res/res/values/public.xml6
-rw-r--r--core/tests/coretests/src/android/database/sqlite/SQLiteUnfinalizedExceptionTest.java81
-rw-r--r--docs/html/guide/practices/design/performance.jd223
-rw-r--r--graphics/java/android/renderscript/Element.java25
-rw-r--r--graphics/java/android/renderscript/RenderScript.java6
-rw-r--r--graphics/jni/android_renderscript_RenderScript.cpp8
-rw-r--r--include/android_runtime/android_app_NativeActivity.h2
-rw-r--r--include/utils/PollLoop.h14
-rw-r--r--libs/gui/SensorEventQueue.cpp2
-rw-r--r--libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java8
-rw-r--r--libs/rs/java/ModelViewer/res/raw/robot.a3dbin144500 -> 144528 bytes
-rw-r--r--libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java9
-rw-r--r--libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java5
-rw-r--r--libs/rs/java/ModelViewer/src/com/android/modelviewer/scenegraph.rs4
-rw-r--r--libs/rs/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs8
-rw-r--r--libs/rs/java/Samples/res/raw/torus.a3dbin571236 -> 571248 bytes
-rw-r--r--libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java6
-rw-r--r--libs/rs/rs.spec1
-rw-r--r--libs/rs/rsElement.cpp30
-rw-r--r--libs/rs/rsElement.h3
-rw-r--r--libs/rs/rsFont.cpp3
-rw-r--r--libs/rs/rsScriptC.cpp2
-rw-r--r--libs/utils/PollLoop.cpp19
-rw-r--r--libs/utils/Threads.cpp39
-rw-r--r--libs/utils/ZipFileRO.cpp14
-rw-r--r--media/libstagefright/colorconversion/SoftwareRenderer.cpp11
-rw-r--r--native/android/input.cpp4
-rw-r--r--native/android/looper.cpp4
-rw-r--r--native/android/sensor.cpp4
-rw-r--r--native/include/android/input.h4
-rw-r--r--native/include/android/looper.h16
-rw-r--r--native/include/android/sensor.h2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java7
-rwxr-xr-xtelephony/java/com/android/internal/telephony/sip/SipPhoneBase.java3
-rw-r--r--test-runner/src/android/test/ProviderTestCase2.java7
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java4
-rw-r--r--tests/HwAccelerationTest/AndroidManifest.xml10
-rw-r--r--tests/HwAccelerationTest/res/layout/form.xml66
-rw-r--r--tests/HwAccelerationTest/src/com/google/android/test/hwui/ResizeActivity.java30
72 files changed, 1494 insertions, 979 deletions
diff --git a/api/current.xml b/api/current.xml
index eb21d97ed826..d393930c224c 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -16482,6 +16482,50 @@
visibility="public"
>
</field>
+<field name="TextAppearance_StatusBar_EventContent"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16973927"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TextAppearance_StatusBar_EventContent_Title"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16973928"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TextAppearance_StatusBar_Icon"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16973926"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TextAppearance_StatusBar_Title"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16973925"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="TextAppearance_Theme"
type="int"
transient="false"
@@ -17824,50 +17868,6 @@
visibility="public"
>
</field>
-<field name="kraken_resource_pad41"
- type="int"
- transient="false"
- volatile="false"
- value="16973928"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="kraken_resource_pad42"
- type="int"
- transient="false"
- volatile="false"
- value="16973927"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="kraken_resource_pad43"
- type="int"
- transient="false"
- volatile="false"
- value="16973926"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="kraken_resource_pad44"
- type="int"
- transient="false"
- volatile="false"
- value="16973925"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="kraken_resource_pad5"
type="int"
transient="false"
@@ -21707,6 +21707,21 @@
<parameter name="tab" type="android.app.ActionBar.Tab">
</parameter>
</method>
+<method name="addTab"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tab" type="android.app.ActionBar.Tab">
+</parameter>
+<parameter name="position" type="int">
+</parameter>
+</method>
<method name="getCustomNavigationView"
return="android.view.View"
abstract="true"
@@ -21762,8 +21777,8 @@
visibility="public"
>
</method>
-<method name="getSubtitle"
- return="java.lang.CharSequence"
+<method name="getSelectedTab"
+ return="android.app.ActionBar.Tab"
abstract="true"
native="false"
synchronized="false"
@@ -21773,7 +21788,7 @@
visibility="public"
>
</method>
-<method name="getTitle"
+<method name="getSubtitle"
return="java.lang.CharSequence"
abstract="true"
native="false"
@@ -21784,8 +21799,8 @@
visibility="public"
>
</method>
-<method name="hide"
- return="void"
+<method name="getTitle"
+ return="java.lang.CharSequence"
abstract="true"
native="false"
synchronized="false"
@@ -21795,7 +21810,7 @@
visibility="public"
>
</method>
-<method name="insertTab"
+<method name="hide"
return="void"
abstract="true"
native="false"
@@ -21805,10 +21820,6 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="tab" type="android.app.ActionBar.Tab">
-</parameter>
-<parameter name="position" type="int">
-</parameter>
</method>
<method name="isShowing"
return="boolean"
@@ -21980,62 +21991,6 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="title" type="java.lang.CharSequence">
-</parameter>
-<parameter name="subtitle" type="java.lang.CharSequence">
-</parameter>
-</method>
-<method name="setStandardNavigationMode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="titleResId" type="int">
-</parameter>
-<parameter name="subtitleResId" type="int">
-</parameter>
-</method>
-<method name="setStandardNavigationMode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="title" type="java.lang.CharSequence">
-</parameter>
-</method>
-<method name="setStandardNavigationMode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="titleResId" type="int">
-</parameter>
-</method>
-<method name="setStandardNavigationMode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
</method>
<method name="setSubtitle"
return="void"
@@ -22074,19 +22029,6 @@
visibility="public"
>
</method>
-<method name="setTabNavigationMode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="containerViewId" type="int">
-</parameter>
-</method>
<method name="setTitle"
return="void"
abstract="true"
@@ -22230,8 +22172,8 @@
visibility="public"
>
</constructor>
-<method name="getFragment"
- return="android.app.Fragment"
+<method name="getCustomView"
+ return="android.view.View"
abstract="true"
native="false"
synchronized="false"
@@ -22263,6 +22205,17 @@
visibility="public"
>
</method>
+<method name="getTag"
+ return="java.lang.Object"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getText"
return="java.lang.CharSequence"
abstract="true"
@@ -22285,7 +22238,7 @@
visibility="public"
>
</method>
-<method name="setFragment"
+<method name="setCustomView"
return="void"
abstract="true"
native="false"
@@ -22295,7 +22248,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="fragment" type="android.app.Fragment">
+<parameter name="view" type="android.view.View">
</parameter>
</method>
<method name="setIcon"
@@ -22311,6 +22264,32 @@
<parameter name="icon" type="android.graphics.drawable.Drawable">
</parameter>
</method>
+<method name="setTabListener"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.app.ActionBar.TabListener">
+</parameter>
+</method>
+<method name="setTag"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="obj" type="java.lang.Object">
+</parameter>
+</method>
<method name="setText"
return="void"
abstract="true"
@@ -22336,6 +22315,44 @@
>
</field>
</class>
+<interface name="ActionBar.TabListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onTabSelected"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tab" type="android.app.ActionBar.Tab">
+</parameter>
+<parameter name="ft" type="android.app.FragmentTransaction">
+</parameter>
+</method>
+<method name="onTabUnselected"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tab" type="android.app.ActionBar.Tab">
+</parameter>
+<parameter name="ft" type="android.app.FragmentTransaction">
+</parameter>
+</method>
+</interface>
<class name="Activity"
extends="android.view.ContextThemeWrapper"
abstract="false"
@@ -29326,6 +29343,17 @@
<parameter name="fragment" type="android.app.Fragment">
</parameter>
</method>
+<method name="isEmpty"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="remove"
return="android.app.FragmentTransaction"
abstract="true"
@@ -175921,16 +175949,6 @@
<parameter name="cursorController" type="android.widget.TextView.CursorController">
</parameter>
</method>
-<field name="mCursorController"
- type="android.widget.TextView.CursorController"
- transient="false"
- volatile="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="protected"
->
-</field>
</class>
<class name="BaseKeyListener"
extends="android.text.method.MetaKeyKeyListener"
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 2e8739412985..f6f80d1d47e2 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -136,7 +136,7 @@ int delete_cache(const char *pkgname, int encrypted_fs_flag)
/* TODO(oam): depending on use case (ecryptfs or dmcrypt)
* change implementation
*/
-static int disk_free()
+static int64_t disk_free()
{
struct statfs sfs;
if (statfs(PKG_DIR_PREFIX, &sfs) == 0) {
@@ -154,18 +154,18 @@ static int disk_free()
* also require that apps constantly modify file metadata even
* when just reading from the cache, which is pretty awful.
*/
-int free_cache(int free_size)
+int free_cache(int64_t free_size)
{
const char *name;
int dfd, subfd;
DIR *d;
struct dirent *de;
- int avail;
+ int64_t avail;
avail = disk_free();
if (avail < 0) return -1;
- LOGI("free_cache(%d) avail %d\n", free_size, avail);
+ LOGI("free_cache(%" PRId64 ") avail %" PRId64 "\n", free_size, avail);
if (avail >= free_size) return 0;
/* First try encrypted dir */
@@ -327,10 +327,10 @@ int protect(char *pkgname, gid_t gid)
return 0;
}
-static int stat_size(struct stat *s)
+static int64_t stat_size(struct stat *s)
{
- int blksize = s->st_blksize;
- int size = s->st_size;
+ int64_t blksize = s->st_blksize;
+ int64_t size = s->st_size;
if (blksize) {
/* round up to filesystem block size */
@@ -340,9 +340,9 @@ static int stat_size(struct stat *s)
return size;
}
-static int calculate_dir_size(int dfd)
+static int64_t calculate_dir_size(int dfd)
{
- int size = 0;
+ int64_t size = 0;
struct stat s;
DIR *d;
struct dirent *de;
@@ -378,7 +378,7 @@ static int calculate_dir_size(int dfd)
int get_size(const char *pkgname, const char *apkpath,
const char *fwdlock_apkpath,
- int *_codesize, int *_datasize, int *_cachesize, int encrypted_fs_flag)
+ int64_t *_codesize, int64_t *_datasize, int64_t *_cachesize, int encrypted_fs_flag)
{
DIR *d;
int dfd;
@@ -386,9 +386,9 @@ int get_size(const char *pkgname, const char *apkpath,
struct stat s;
char path[PKG_PATH_MAX];
- int codesize = 0;
- int datasize = 0;
- int cachesize = 0;
+ int64_t codesize = 0;
+ int64_t datasize = 0;
+ int64_t cachesize = 0;
/* count the source apk as code -- but only if it's not
* on the /system partition and its not on the sdcard.
@@ -445,7 +445,7 @@ int get_size(const char *pkgname, const char *apkpath,
}
subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY);
if (subfd >= 0) {
- int size = calculate_dir_size(subfd);
+ int64_t size = calculate_dir_size(subfd);
if (!strcmp(name,"lib")) {
codesize += size;
} else if(!strcmp(name,"cache")) {
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index 882c493b5971..c9918459e957 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -60,7 +60,7 @@ static int do_rename(char **arg, char reply[REPLY_MAX])
static int do_free_cache(char **arg, char reply[REPLY_MAX]) /* TODO int:free_size */
{
- return free_cache(atoi(arg[0])); /* free_size */
+ return free_cache((int64_t)atoll(arg[0])); /* free_size */
}
static int do_rm_cache(char **arg, char reply[REPLY_MAX])
@@ -75,15 +75,19 @@ static int do_protect(char **arg, char reply[REPLY_MAX])
static int do_get_size(char **arg, char reply[REPLY_MAX])
{
- int codesize = 0;
- int datasize = 0;
- int cachesize = 0;
+ int64_t codesize = 0;
+ int64_t datasize = 0;
+ int64_t cachesize = 0;
int res = 0;
/* pkgdir, apkpath */
res = get_size(arg[0], arg[1], arg[2], &codesize, &datasize, &cachesize, atoi(arg[3]));
- sprintf(reply,"%d %d %d", codesize, datasize, cachesize);
+ /*
+ * Each int64_t can take up 22 characters printed out. Make sure it
+ * doesn't go over REPLY_MAX in the future.
+ */
+ snprintf(reply, REPLY_MAX, "%" PRId64 " %" PRId64 " %" PRId64, codesize, datasize, cachesize);
return res;
}
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 8e4adb10ff2b..479e4b255f8c 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -19,6 +19,8 @@
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
@@ -105,7 +107,7 @@ int move_dex(const char *src, const char *dst);
int rm_dex(const char *path);
int protect(char *pkgname, gid_t gid);
int get_size(const char *pkgname, const char *apkpath, const char *fwdlock_apkpath,
- int *codesize, int *datasize, int *cachesize, int encrypted_fs_flag);
-int free_cache(int free_size);
+ int64_t *codesize, int64_t *datasize, int64_t *cachesize, int encrypted_fs_flag);
+int free_cache(int64_t free_size);
int dexopt(const char *apk_path, uid_t uid, int is_public);
int movefiles();
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 38086f072745..29f2e3088c0a 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -123,72 +123,6 @@ public abstract class ActionBar {
public abstract int getSelectedNavigationItem();
/**
- * Set the action bar into standard navigation mode, supplying a title and subtitle.
- *
- * Standard navigation mode is default. The title is automatically set to the
- * name of your Activity. Subtitles are displayed underneath the title, usually
- * in a smaller font or otherwise less prominently than the title. Subtitles are
- * good for extended descriptions of activity state.
- *
- * @param title The action bar's title. null is treated as an empty string.
- * @param subtitle The action bar's subtitle. null will remove the subtitle entirely.
- *
- * @see #setStandardNavigationMode()
- * @see #setStandardNavigationMode(CharSequence)
- * @see #setStandardNavigationMode(int)
- * @see #setStandardNavigationMode(int, int)
- */
- public abstract void setStandardNavigationMode(CharSequence title, CharSequence subtitle);
-
- /**
- * Set the action bar into standard navigation mode, supplying a title and subtitle.
- *
- * Standard navigation mode is default. The title is automatically set to the
- * name of your Activity. Subtitles are displayed underneath the title, usually
- * in a smaller font or otherwise less prominently than the title. Subtitles are
- * good for extended descriptions of activity state.
- *
- * @param titleResId Resource ID of a title string
- * @param subtitleResId Resource ID of a subtitle string
- *
- * @see #setStandardNavigationMode()
- * @see #setStandardNavigationMode(CharSequence)
- * @see #setStandardNavigationMode(CharSequence, CharSequence)
- * @see #setStandardNavigationMode(int)
- */
- public abstract void setStandardNavigationMode(int titleResId, int subtitleResId);
-
- /**
- * Set the action bar into standard navigation mode, supplying a title and subtitle.
- *
- * Standard navigation mode is default. The title is automatically set to the
- * name of your Activity on startup if an action bar is present.
- *
- * @param title The action bar's title. null is treated as an empty string.
- *
- * @see #setStandardNavigationMode()
- * @see #setStandardNavigationMode(CharSequence, CharSequence)
- * @see #setStandardNavigationMode(int)
- * @see #setStandardNavigationMode(int, int)
- */
- public abstract void setStandardNavigationMode(CharSequence title);
-
- /**
- * Set the action bar into standard navigation mode, supplying a title and subtitle.
- *
- * Standard navigation mode is default. The title is automatically set to the
- * name of your Activity on startup if an action bar is present.
- *
- * @param titleResId Resource ID of a title string
- *
- * @see #setStandardNavigationMode()
- * @see #setStandardNavigationMode(CharSequence)
- * @see #setStandardNavigationMode(CharSequence, CharSequence)
- * @see #setStandardNavigationMode(int, int)
- */
- public abstract void setStandardNavigationMode(int titleResId);
-
- /**
* Set the action bar into standard navigation mode, using the currently set title
* and/or subtitle.
*
@@ -324,18 +258,6 @@ public abstract class ActionBar {
public abstract void setTabNavigationMode();
/**
- * Set the action bar into tabbed navigation mode.
- *
- * @param containerViewId Id of the container view where tab content fragments should appear.
- *
- * @see #addTab(Tab)
- * @see #insertTab(Tab, int)
- * @see #removeTab(Tab)
- * @see #removeTabAt(int)
- */
- public abstract void setTabNavigationMode(int containerViewId);
-
- /**
* Create and return a new {@link Tab}.
* This tab will not be included in the action bar until it is added.
*
@@ -354,13 +276,13 @@ public abstract class ActionBar {
public abstract void addTab(Tab tab);
/**
- * Insert a tab for use in tabbed navigation mode. The tab will be inserted at
+ * Add a tab for use in tabbed navigation mode. The tab will be inserted at
* <code>position</code>.
*
* @param tab The tab to add
* @param position The new position of the tab
*/
- public abstract void insertTab(Tab tab, int position);
+ public abstract void addTab(Tab tab, int position);
/**
* Remove a tab from the action bar.
@@ -384,6 +306,14 @@ public abstract class ActionBar {
public abstract void selectTab(Tab tab);
/**
+ * Returns the currently selected tab if in tabbed navigation mode and there is at least
+ * one tab present.
+ *
+ * @return The currently selected tab or null
+ */
+ public abstract Tab getSelectedTab();
+
+ /**
* Retrieve the current height of the ActionBar.
*
* @return The ActionBar's height
@@ -477,22 +407,68 @@ public abstract class ActionBar {
public abstract void setText(CharSequence text);
/**
- * Returns the fragment that will be shown when this tab is selected.
+ * Set a custom view to be used for this tab. This overrides values set by
+ * {@link #setText(CharSequence)} and {@link #setIcon(Drawable)}.
*
- * @return Fragment associated with this tab
+ * @param view Custom view to be used as a tab.
*/
- public abstract Fragment getFragment();
+ public abstract void setCustomView(View view);
/**
- * Set the fragment that will be shown when this tab is selected.
+ * Retrieve a previously set custom view for this tab.
*
- * @param fragment Fragment to associate with this tab
+ * @return The custom view set by {@link #setCustomView(View)}.
*/
- public abstract void setFragment(Fragment fragment);
+ public abstract View getCustomView();
+
+ /**
+ * Give this Tab an arbitrary object to hold for later use.
+ *
+ * @param obj Object to store
+ */
+ public abstract void setTag(Object obj);
+
+ /**
+ * @return This Tab's tag object.
+ */
+ public abstract Object getTag();
+
+ /**
+ * Set the {@link TabListener} that will handle switching to and from this tab.
+ * All tabs must have a TabListener set before being added to the ActionBar.
+ *
+ * @param listener Listener to handle tab selection events
+ */
+ public abstract void setTabListener(TabListener listener);
/**
* Select this tab. Only valid if the tab has been added to the action bar.
*/
public abstract void select();
}
+
+ /**
+ * Callback interface invoked when a tab is focused, unfocused, added, or removed.
+ */
+ public interface TabListener {
+ /**
+ * Called when a tab enters the selected state.
+ *
+ * @param tab The tab that was selected
+ * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute
+ * during a tab switch. The previous tab's unselect and this tab's select will be
+ * executed in a single transaction.
+ */
+ public void onTabSelected(Tab tab, FragmentTransaction ft);
+
+ /**
+ * Called when a tab exits the selected state.
+ *
+ * @param tab The tab that was unselected
+ * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute
+ * during a tab switch. This tab's unselect and the newly selected tab's select
+ * will be executed in a single transaction.
+ */
+ public void onTabUnselected(Tab tab, FragmentTransaction ft);
+ }
}
diff --git a/core/java/android/app/BackStackEntry.java b/core/java/android/app/BackStackEntry.java
index 00c2fc476900..71fd5e5db560 100644
--- a/core/java/android/app/BackStackEntry.java
+++ b/core/java/android/app/BackStackEntry.java
@@ -490,4 +490,8 @@ final class BackStackEntry implements FragmentTransaction, Runnable {
public int getTransitionStyle() {
return mTransitionStyle;
}
+
+ public boolean isEmpty() {
+ return mNumOp == 0;
+ }
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 6886abadeb2e..74971364aafd 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -323,54 +323,54 @@ class ContextImpl extends Context {
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
SharedPreferencesImpl sp;
+ File prefsFile;
+ boolean needInitialLoad = false;
synchronized (sSharedPrefs) {
sp = sSharedPrefs.get(name);
- if (sp != null && !sp.hasFileChanged()) {
- //Log.i(TAG, "Returning existing prefs " + name + ": " + sp);
+ if (sp != null && !sp.hasFileChangedUnexpectedly()) {
return sp;
}
- }
- File f = getSharedPrefsFile(name);
- FileInputStream str = null;
- File backup = makeBackupFile(f);
- if (backup.exists()) {
- f.delete();
- backup.renameTo(f);
+ prefsFile = getSharedPrefsFile(name);
+ if (sp == null) {
+ sp = new SharedPreferencesImpl(prefsFile, mode, null);
+ sSharedPrefs.put(name, sp);
+ needInitialLoad = true;
+ }
}
- // Debugging
- if (f.exists() && !f.canRead()) {
- Log.w(TAG, "Attempt to read preferences file " + f + " without permission");
- }
+ synchronized (sp) {
+ if (needInitialLoad && sp.isLoaded()) {
+ // lost the race to load; another thread handled it
+ return sp;
+ }
+ File backup = makeBackupFile(prefsFile);
+ if (backup.exists()) {
+ prefsFile.delete();
+ backup.renameTo(prefsFile);
+ }
- Map map = null;
- if (f.exists() && f.canRead()) {
- try {
- str = new FileInputStream(f);
- map = XmlUtils.readMapXml(str);
- str.close();
- } catch (org.xmlpull.v1.XmlPullParserException e) {
- Log.w(TAG, "getSharedPreferences", e);
- } catch (FileNotFoundException e) {
- Log.w(TAG, "getSharedPreferences", e);
- } catch (IOException e) {
- Log.w(TAG, "getSharedPreferences", e);
+ // Debugging
+ if (prefsFile.exists() && !prefsFile.canRead()) {
+ Log.w(TAG, "Attempt to read preferences file " + prefsFile + " without permission");
}
- }
- synchronized (sSharedPrefs) {
- if (sp != null) {
- //Log.i(TAG, "Updating existing prefs " + name + " " + sp + ": " + map);
- sp.replace(map);
- } else {
- sp = sSharedPrefs.get(name);
- if (sp == null) {
- sp = new SharedPreferencesImpl(f, mode, map);
- sSharedPrefs.put(name, sp);
+ Map map = null;
+ if (prefsFile.exists() && prefsFile.canRead()) {
+ try {
+ FileInputStream str = new FileInputStream(prefsFile);
+ map = XmlUtils.readMapXml(str);
+ str.close();
+ } catch (org.xmlpull.v1.XmlPullParserException e) {
+ Log.w(TAG, "getSharedPreferences", e);
+ } catch (FileNotFoundException e) {
+ Log.w(TAG, "getSharedPreferences", e);
+ } catch (IOException e) {
+ Log.w(TAG, "getSharedPreferences", e);
}
}
- return sp;
+ sp.replace(map);
}
+ return sp;
}
private File getPreferencesDir() {
@@ -2718,6 +2718,10 @@ class ContextImpl extends Context {
private static final class SharedPreferencesImpl implements SharedPreferences {
+ // Lock ordering rules:
+ // - acquire SharedPreferencesImpl.this before EditorImpl.this
+ // - acquire mWritingToDiskLock before EditorImpl.this
+
private final File mFile;
private final File mBackupFile;
private final int mMode;
@@ -2725,6 +2729,7 @@ class ContextImpl extends Context {
private Map<String, Object> mMap; // guarded by 'this'
private long mTimestamp; // guarded by 'this'
private int mDiskWritesInFlight = 0; // guarded by 'this'
+ private boolean mLoaded = false; // guarded by 'this'
private final Object mWritingToDiskLock = new Object();
private static final Object mContent = new Object();
@@ -2735,6 +2740,7 @@ class ContextImpl extends Context {
mFile = file;
mBackupFile = makeBackupFile(file);
mMode = mode;
+ mLoaded = initialContents != null;
mMap = initialContents != null ? initialContents : new HashMap<String, Object>();
FileStatus stat = new FileStatus();
if (FileUtils.getFileStatus(file.getPath(), stat)) {
@@ -2743,7 +2749,23 @@ class ContextImpl extends Context {
mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
}
- public boolean hasFileChanged() {
+ // Has this SharedPreferences ever had values assigned to it?
+ boolean isLoaded() {
+ synchronized (this) {
+ return mLoaded;
+ }
+ }
+
+ // Has the file changed out from under us? i.e. writes that
+ // we didn't instigate.
+ public boolean hasFileChangedUnexpectedly() {
+ synchronized (this) {
+ if (mDiskWritesInFlight > 0) {
+ // If we know we caused it, it's not unexpected.
+ Log.d(TAG, "disk write in flight, not unexpected.");
+ return false;
+ }
+ }
FileStatus stat = new FileStatus();
if (!FileUtils.getFileStatus(mFile.getPath(), stat)) {
return true;
@@ -2754,8 +2776,9 @@ class ContextImpl extends Context {
}
public void replace(Map newContents) {
- if (newContents != null) {
- synchronized (this) {
+ synchronized (this) {
+ mLoaded = true;
+ if (newContents != null) {
mMap = newContents;
}
}
diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java
index 04598a375c90..9d44106db8dc 100644
--- a/core/java/android/app/FragmentTransaction.java
+++ b/core/java/android/app/FragmentTransaction.java
@@ -85,6 +85,12 @@ public interface FragmentTransaction {
* @return Returns the same FragmentTransaction instance.
*/
public FragmentTransaction show(Fragment fragment);
+
+ /**
+ * @return <code>true</code> if this transaction contains no operations,
+ * <code>false</code> otherwise.
+ */
+ public boolean isEmpty();
/**
* Bit mask that is set for all enter transitions.
diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java
index 4dc88b31f1d9..d7a041243acb 100644
--- a/core/java/android/app/NativeActivity.java
+++ b/core/java/android/app/NativeActivity.java
@@ -3,8 +3,6 @@ package android.app;
import com.android.internal.view.IInputMethodCallback;
import com.android.internal.view.IInputMethodSession;
-import dalvik.system.PathClassLoader;
-
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -168,17 +166,14 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
// If the application does not have (Java) code, then no ClassLoader
// has been set up for it. We will need to do our own search for
// the native code.
- path = ai.applicationInfo.dataDir + "/lib/" + System.mapLibraryName(libname);
- if (!(new File(path)).exists()) {
- path = null;
+ File libraryFile = new File(ai.applicationInfo.nativeLibraryDir,
+ System.mapLibraryName(libname));
+ if (libraryFile.exists()) {
+ path = libraryFile.getPath();
}
}
if (path == null) {
- path = ((PathClassLoader)getClassLoader()).findLibrary(libname);
- }
-
- if (path == null) {
throw new IllegalArgumentException("Unable to find native library: " + libname);
}
diff --git a/core/java/android/app/backup/SharedPreferencesBackupHelper.java b/core/java/android/app/backup/SharedPreferencesBackupHelper.java
index 23b170360daa..213bd31698de 100644
--- a/core/java/android/app/backup/SharedPreferencesBackupHelper.java
+++ b/core/java/android/app/backup/SharedPreferencesBackupHelper.java
@@ -16,6 +16,7 @@
package android.app.backup;
+import android.app.QueuedWork;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.ParcelFileDescriptor;
@@ -94,7 +95,11 @@ public class SharedPreferencesBackupHelper extends FileBackupHelperBase implemen
public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
ParcelFileDescriptor newState) {
Context context = mContext;
-
+
+ // If a SharedPreference has an outstanding write in flight,
+ // wait for it to finish flushing to disk.
+ QueuedWork.waitToFinish();
+
// make filenames for the prefGroups
String[] prefGroups = mPrefGroups;
final int N = prefGroups.length;
@@ -123,4 +128,3 @@ public class SharedPreferencesBackupHelper extends FileBackupHelperBase implemen
}
}
}
-
diff --git a/core/java/android/database/sqlite/SQLiteClosable.java b/core/java/android/database/sqlite/SQLiteClosable.java
index 1830f6c84498..21d2ab0aa6e3 100644
--- a/core/java/android/database/sqlite/SQLiteClosable.java
+++ b/core/java/android/database/sqlite/SQLiteClosable.java
@@ -30,6 +30,7 @@ public abstract class SQLiteClosable {
public void acquireReference() {
synchronized(mLock) {
+ checkRefCount();
if (mReferenceCount <= 0) {
throw new IllegalStateException(
"attempt to re-open an already-closed object: " + getObjInfo());
@@ -40,6 +41,7 @@ public abstract class SQLiteClosable {
public void releaseReference() {
synchronized(mLock) {
+ checkRefCount();
mReferenceCount--;
if (mReferenceCount == 0) {
onAllReferencesReleased();
@@ -49,6 +51,7 @@ public abstract class SQLiteClosable {
public void releaseReferenceFromContainer() {
synchronized(mLock) {
+ checkRefCount();
mReferenceCount--;
if (mReferenceCount == 0) {
onAllReferencesReleasedFromContainer();
@@ -63,8 +66,7 @@ public abstract class SQLiteClosable {
if (this instanceof SQLiteDatabase) {
buff.append("database = ");
buff.append(((SQLiteDatabase)this).getPath());
- } else if (this instanceof SQLiteProgram || this instanceof SQLiteStatement ||
- this instanceof SQLiteQuery) {
+ } else if (this instanceof SQLiteProgram) {
buff.append("mSql = ");
buff.append(((SQLiteProgram)this).mSql);
} else if (this instanceof CursorWindow) {
@@ -74,4 +76,13 @@ public abstract class SQLiteClosable {
buff.append(") ");
return buff.toString();
}
+
+ private void checkRefCount() {
+ if (SQLiteDebug.DEBUG_ACTIVE_CURSOR_FINALIZATION) {
+ if (mReferenceCount > 1000) {
+ throw new IllegalStateException("refcount: " + mReferenceCount + ", " +
+ getObjInfo());
+ }
+ }
+ }
}
diff --git a/core/java/android/database/sqlite/SQLiteCompiledSql.java b/core/java/android/database/sqlite/SQLiteCompiledSql.java
index aa0a57d00cbc..0b5a4dff3d4d 100644
--- a/core/java/android/database/sqlite/SQLiteCompiledSql.java
+++ b/core/java/android/database/sqlite/SQLiteCompiledSql.java
@@ -92,9 +92,6 @@ import android.util.Log;
// Note that native_finalize() checks to make sure that nStatement is
// non-null before destroying it.
if (nStatement != 0) {
- if (SQLiteDebug.DEBUG_ACTIVE_CURSOR_FINALIZATION) {
- Log.v(TAG, "closed and deallocated DbObj (id#" + nStatement +")");
- }
mDatabase.finalizeStatementLater(nStatement);
nStatement = 0;
}
@@ -109,16 +106,10 @@ import android.util.Log;
return false;
}
mInUse = true;
- if (SQLiteDebug.DEBUG_ACTIVE_CURSOR_FINALIZATION) {
- Log.v(TAG, "Acquired DbObj (id#" + nStatement + ") from DB cache");
- }
return true;
}
/* package */ synchronized void release() {
- if (SQLiteDebug.DEBUG_ACTIVE_CURSOR_FINALIZATION) {
- Log.v(TAG, "Released DbObj (id#" + nStatement + ") back to DB cache");
- }
mInUse = false;
}
@@ -144,6 +135,22 @@ import android.util.Log;
}
}
+ @Override public String toString() {
+ synchronized(this) {
+ StringBuilder buff = new StringBuilder();
+ buff.append(" nStatement=");
+ buff.append(nStatement);
+ buff.append(", db=");
+ buff.append(mDatabase.getPath());
+ buff.append(", db_connectionNum=");
+ buff.append(mDatabase.mConnectionNum);
+ buff.append(", sql=");
+ int len = mSqlStmt.length();
+ buff.append(mSqlStmt.substring(0, (len > 100) ? 100 : len));
+ return buff.toString();
+ }
+ }
+
/**
* Compiles SQL into a SQLite program.
*
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 0137ea62edba..6937da01f645 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -1066,7 +1066,7 @@ public class SQLiteDatabase extends SQLiteClosable {
closePendingStatements();
releaseCustomFunctions();
// close this database instance - regardless of its reference count value
- dbclose();
+ closeDatabase();
if (mConnectionPool != null) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
assert mConnectionPool != null;
@@ -1075,7 +1075,7 @@ public class SQLiteDatabase extends SQLiteClosable {
mConnectionPool.close();
}
} finally {
- unlock();
+ unlock();
}
}
@@ -1100,6 +1100,47 @@ public class SQLiteDatabase extends SQLiteClosable {
}
/**
+ * package level access for testing purposes
+ */
+ /* package */ void closeDatabase() throws SQLiteException {
+ try {
+ dbclose();
+ } catch (SQLiteUnfinalizedObjectsException e) {
+ String msg = e.getMessage();
+ String[] tokens = msg.split(",", 2);
+ int stmtId = Integer.parseInt(tokens[0]);
+ // get extra info about this statement, if it is still to be released by closeClosable()
+ Iterator<Map.Entry<SQLiteClosable, Object>> iter = mPrograms.entrySet().iterator();
+ boolean found = false;
+ while (iter.hasNext()) {
+ Map.Entry<SQLiteClosable, Object> entry = iter.next();
+ SQLiteClosable program = entry.getKey();
+ if (program != null && program instanceof SQLiteProgram) {
+ SQLiteCompiledSql compiledSql = ((SQLiteProgram)program).mCompiledSql;
+ if (compiledSql.nStatement == stmtId) {
+ msg = compiledSql.toString();
+ found = true;
+ }
+ }
+ }
+ if (!found) {
+ // the statement is already released by closeClosable(). is it waiting to be
+ // finalized?
+ if (mClosedStatementIds.contains(stmtId)) {
+ Log.w(TAG, "this shouldn't happen. finalizing the statement now: ");
+ closePendingStatements();
+ // try to close the database again
+ closeDatabase();
+ }
+ } else {
+ // the statement is not yet closed. most probably programming error in the app.
+ Log.w(TAG, "dbclose failed due to un-close()d SQL statements: " + msg);
+ throw e;
+ }
+ }
+ }
+
+ /**
* Native call to close the database.
*/
private native void dbclose();
diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java
index 9b7d823636cb..bcb0c48b6453 100644
--- a/core/java/android/database/sqlite/SQLiteProgram.java
+++ b/core/java/android/database/sqlite/SQLiteProgram.java
@@ -52,7 +52,7 @@ public abstract class SQLiteProgram extends SQLiteClosable {
/**
* the SQLiteCompiledSql object for the given sql statement.
*/
- private SQLiteCompiledSql mCompiledSql;
+ /* package */ SQLiteCompiledSql mCompiledSql;
/**
* SQLiteCompiledSql statement id is populated with the corresponding object from the above
@@ -130,10 +130,6 @@ public abstract class SQLiteProgram extends SQLiteClosable {
// make sure it is acquired by me.
mCompiledSql.acquire();
mDatabase.addToCompiledQueries(mSql, mCompiledSql);
- if (SQLiteDebug.DEBUG_ACTIVE_CURSOR_FINALIZATION) {
- Log.v(TAG, "Created DbObj (id#" + mCompiledSql.nStatement +
- ") for sql: " + mSql);
- }
} else {
// it is already in compiled-sql cache.
// try to acquire the object.
@@ -144,12 +140,6 @@ public abstract class SQLiteProgram extends SQLiteClosable {
// CompiledSql object. create a new one.
// finalize it when I am done with it in "this" object.
mCompiledSql = new SQLiteCompiledSql(mDatabase, mSql);
- if (SQLiteDebug.DEBUG_ACTIVE_CURSOR_FINALIZATION) {
- Log.v(TAG, "** possible bug ** Created NEW DbObj (id#" +
- mCompiledSql.nStatement +
- ") because the previously created DbObj (id#" + last +
- ") was not released for sql:" + mSql);
- }
// since it is not in the cache, no need to acquire() it.
}
}
diff --git a/core/java/android/database/sqlite/SQLiteUnfinalizedObjectsException.java b/core/java/android/database/sqlite/SQLiteUnfinalizedObjectsException.java
new file mode 100644
index 000000000000..bcf95e2ef1fe
--- /dev/null
+++ b/core/java/android/database/sqlite/SQLiteUnfinalizedObjectsException.java
@@ -0,0 +1,31 @@
+/*
+ * 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 android.database.sqlite;
+
+/**
+ * Thrown if the database can't be closed because of some un-closed
+ * Cursor or SQLiteStatement objects. Could happen when a thread is trying to close
+ * the database while another thread still hasn't closed a Cursor on that database.
+ * @hide
+ */
+public class SQLiteUnfinalizedObjectsException extends SQLiteException {
+ public SQLiteUnfinalizedObjectsException() {}
+
+ public SQLiteUnfinalizedObjectsException(String error) {
+ super(error);
+ }
+}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 9fe6e0136e5b..a857e582beaf 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -216,6 +216,11 @@ public abstract class BatteryStats implements Parcelable {
public abstract Map<Integer, ? extends Sensor> getSensorStats();
/**
+ * Returns a mapping containing active process data.
+ */
+ public abstract SparseArray<? extends Pid> getPidStats();
+
+ /**
* Returns a mapping containing process statistics.
*
* @return a Map from Strings to Uid.Proc objects.
@@ -286,6 +291,11 @@ public abstract class BatteryStats implements Parcelable {
public abstract Timer getSensorTime();
}
+ public class Pid {
+ public long mWakeSum;
+ public long mWakeStart;
+ }
+
/**
* The statistics associated with a particular process.
*/
@@ -521,6 +531,11 @@ public abstract class BatteryStats implements Parcelable {
public abstract HistoryItem getHistory();
/**
+ * Return the base time offset for the battery history.
+ */
+ public abstract long getHistoryBaseTime();
+
+ /**
* Returns the number of times the device has been started.
*/
public abstract int getStartCount();
@@ -1673,6 +1688,7 @@ public abstract class BatteryStats implements Parcelable {
HistoryItem rec = getHistory();
if (rec != null) {
pw.println("Battery History:");
+ long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
int oldState = 0;
int oldStatus = -1;
int oldHealth = -1;
@@ -1681,7 +1697,7 @@ public abstract class BatteryStats implements Parcelable {
int oldVolt = -1;
while (rec != null) {
pw.print(" ");
- pw.print(rec.time);
+ TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
pw.print(" ");
if (rec.cmd == HistoryItem.CMD_START) {
pw.println(" START");
@@ -1784,6 +1800,35 @@ public abstract class BatteryStats implements Parcelable {
oldState = rec.states;
rec = rec.next;
}
+ pw.println("");
+ }
+
+ SparseArray<? extends Uid> uidStats = getUidStats();
+ final int NU = uidStats.size();
+ boolean didPid = false;
+ long nowRealtime = SystemClock.elapsedRealtime();
+ StringBuilder sb = new StringBuilder(64);
+ for (int i=0; i<NU; i++) {
+ Uid uid = uidStats.valueAt(i);
+ SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
+ if (pids != null) {
+ for (int j=0; j<pids.size(); j++) {
+ Uid.Pid pid = pids.valueAt(j);
+ if (!didPid) {
+ pw.println("Per-PID Stats:");
+ didPid = true;
+ }
+ long time = pid.mWakeSum + (pid.mWakeStart != 0
+ ? (nowRealtime - pid.mWakeStart) : 0);
+ pw.print(" PID "); pw.print(pids.keyAt(j));
+ pw.print(" wake time: ");
+ TimeUtils.formatDuration(time, pw);
+ pw.println("");
+ }
+ }
+ }
+ if (didPid) {
+ pw.println("");
}
pw.println("Statistics since last charge:");
diff --git a/core/java/android/text/method/ArrowKeyMovementMethod.java b/core/java/android/text/method/ArrowKeyMovementMethod.java
index 3fe14f9b0943..04086737523c 100644
--- a/core/java/android/text/method/ArrowKeyMovementMethod.java
+++ b/core/java/android/text/method/ArrowKeyMovementMethod.java
@@ -34,7 +34,7 @@ public class ArrowKeyMovementMethod implements MovementMethod {
* An optional controller for the cursor.
* Use {@link #setCursorController(CursorController)} to set this field.
*/
- protected CursorController mCursorController;
+ private CursorController mCursorController;
private boolean isCap(Spannable buffer) {
return ((MetaKeyKeyListener.getMetaState(buffer, KeyEvent.META_SHIFT_ON) == 1) ||
@@ -302,7 +302,17 @@ public class ArrowKeyMovementMethod implements MovementMethod {
/**
* Defines the cursor controller.
*
- * When set, this object can be used to handle events, that can be translated in cursor updates.
+ * When set, this object can be used to handle touch events, that can be translated into cursor
+ * updates.
+ *
+ * {@link MotionEvent#ACTION_MOVE} events will call back the
+ * {@link CursorController#updatePosition(int, int)} controller's method, passing the current
+ * finger coordinates (offset by {@link CursorController#getOffsetX()} and
+ * {@link CursorController#getOffsetY()}) as parameters.
+ *
+ * When the gesture is finished (on a {@link MotionEvent#ACTION_UP} or
+ * {@link MotionEvent#ACTION_CANCEL} event), the controller is reset to null.
+ *
* @param cursorController A cursor controller implementation
*/
public void setCursorController(CursorController cursorController) {
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index b01a71d0248a..60ca3849d6f9 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -132,75 +132,76 @@ public class TimeUtils {
return ZoneInfoDB.getVersion();
}
+ /** @hide Field length that can hold 999 days of time */
+ public static final int HUNDRED_DAY_FIELD_LEN = 19;
+
private static final int SECONDS_PER_MINUTE = 60;
private static final int SECONDS_PER_HOUR = 60 * 60;
private static final int SECONDS_PER_DAY = 24 * 60 * 60;
- /** @hide Just for debugging; not internationalized. */
- public static void formatDuration(long duration, StringBuilder builder) {
- if (duration == 0) {
- builder.append("0");
- return;
- }
- if (duration > 0) {
- builder.append("+");
- } else {
- builder.append("-");
- duration = -duration;
- }
-
- int millis = (int)(duration%1000);
- int seconds = (int) Math.floor(duration / 1000);
- int days = 0, hours = 0, minutes = 0;
-
- if (seconds > SECONDS_PER_DAY) {
- days = seconds / SECONDS_PER_DAY;
- seconds -= days * SECONDS_PER_DAY;
- }
- if (seconds > SECONDS_PER_HOUR) {
- hours = seconds / SECONDS_PER_HOUR;
- seconds -= hours * SECONDS_PER_HOUR;
- }
- if (seconds > SECONDS_PER_MINUTE) {
- minutes = seconds / SECONDS_PER_MINUTE;
- seconds -= minutes * SECONDS_PER_MINUTE;
- }
-
- boolean doall = false;
- if (days > 0) {
- builder.append(days);
- builder.append('d');
- doall = true;
+ private static final Object sFormatSync = new Object();
+ private static char[] sFormatStr = new char[HUNDRED_DAY_FIELD_LEN+5];
+
+ static private int accumField(int amt, int suffix, boolean always, int zeropad) {
+ if (amt > 99 || (always && zeropad >= 3)) {
+ return 3+suffix;
}
- if (doall || hours > 0) {
- builder.append(hours);
- builder.append('h');
- doall = true;
+ if (amt > 9 || (always && zeropad >= 2)) {
+ return 2+suffix;
}
- if (doall || minutes > 0) {
- builder.append(minutes);
- builder.append('m');
- doall = true;
+ if (always || amt > 0) {
+ return 1+suffix;
}
- if (doall || seconds > 0) {
- builder.append(seconds);
- builder.append('s');
- doall = true;
+ return 0;
+ }
+
+ static private int printField(char[] formatStr, int amt, char suffix, int pos,
+ boolean always, int zeropad) {
+ if (always || amt > 0) {
+ if ((always && zeropad >= 3) || amt > 99) {
+ int dig = amt/100;
+ formatStr[pos] = (char)(dig + '0');
+ pos++;
+ always = true;
+ amt -= (dig*100);
+ }
+ if ((always && zeropad >= 2) || amt > 9) {
+ int dig = amt/10;
+ formatStr[pos] = (char)(dig + '0');
+ pos++;
+ always = true;
+ amt -= (dig*10);
+ }
+ formatStr[pos] = (char)(amt + '0');
+ pos++;
+ formatStr[pos] = suffix;
+ pos++;
}
- builder.append(millis);
- builder.append("ms");
+ return pos;
}
-
- /** @hide Just for debugging; not internationalized. */
- public static void formatDuration(long duration, PrintWriter pw) {
+
+ private static int formatDurationLocked(long duration, int fieldLen) {
+ if (sFormatStr.length < fieldLen) {
+ sFormatStr = new char[fieldLen];
+ }
+
+ char[] formatStr = sFormatStr;
+
if (duration == 0) {
- pw.print("0");
- return;
+ int pos = 0;
+ fieldLen -= 1;
+ while (pos < fieldLen) {
+ formatStr[pos] = ' ';
+ }
+ formatStr[pos] = '0';
+ return pos+1;
}
+
+ char prefix;
if (duration > 0) {
- pw.print("+");
+ prefix = '+';
} else {
- pw.print("-");
+ prefix = '-';
duration = -duration;
}
@@ -221,38 +222,62 @@ public class TimeUtils {
seconds -= minutes * SECONDS_PER_MINUTE;
}
- boolean doall = false;
- if (days > 0) {
- pw.print(days);
- pw.print('d');
- doall = true;
- }
- if (doall || hours > 0) {
- pw.print(hours);
- pw.print('h');
- doall = true;
- }
- if (doall || minutes > 0) {
- pw.print(minutes);
- pw.print('m');
- doall = true;
+ int pos = 0;
+
+ if (fieldLen != 0) {
+ int myLen = accumField(days, 1, false, 0);
+ myLen += accumField(hours, 1, myLen > 0, 2);
+ myLen += accumField(minutes, 1, myLen > 0, 2);
+ myLen += accumField(seconds, 1, myLen > 0, 2);
+ myLen += accumField(millis, 2, true, myLen > 0 ? 3 : 0) + 1;
+ while (myLen < fieldLen) {
+ formatStr[pos] = ' ';
+ pos++;
+ myLen++;
+ }
}
- if (doall || seconds > 0) {
- pw.print(seconds);
- pw.print('s');
- doall = true;
+
+ formatStr[pos] = prefix;
+ pos++;
+
+ int start = pos;
+ boolean zeropad = fieldLen != 0;
+ pos = printField(formatStr, days, 'd', pos, false, 0);
+ pos = printField(formatStr, hours, 'h', pos, pos != start, zeropad ? 2 : 0);
+ pos = printField(formatStr, minutes, 'm', pos, pos != start, zeropad ? 2 : 0);
+ pos = printField(formatStr, seconds, 's', pos, pos != start, zeropad ? 2 : 0);
+ pos = printField(formatStr, millis, 'm', pos, true, (zeropad && pos != start) ? 3 : 0);
+ formatStr[pos] = 's';
+ return pos + 1;
+ }
+
+ /** @hide Just for debugging; not internationalized. */
+ public static void formatDuration(long duration, StringBuilder builder) {
+ synchronized (sFormatSync) {
+ int len = formatDurationLocked(duration, 0);
+ builder.append(sFormatStr, 0, len);
}
- pw.print(millis);
- pw.print("ms");
}
+ /** @hide Just for debugging; not internationalized. */
+ public static void formatDuration(long duration, PrintWriter pw, int fieldLen) {
+ synchronized (sFormatSync) {
+ int len = formatDurationLocked(duration, fieldLen);
+ pw.print(new String(sFormatStr, 0, len));
+ }
+ }
/** @hide Just for debugging; not internationalized. */
+ public static void formatDuration(long duration, PrintWriter pw) {
+ formatDuration(duration, pw, 0);
+ }
+
+ /** @hide Just for debugging; not internationalized. */
public static void formatDuration(long time, long now, PrintWriter pw) {
if (time == 0) {
pw.print("--");
return;
}
- formatDuration(time-now, pw);
+ formatDuration(time-now, pw, 0);
}
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 735535350e07..f8d79e5694aa 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7298,9 +7298,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.BUILD_CACHE);
}
- if (Config.DEBUG && ViewDebug.profileDrawing) {
- EventLog.writeEvent(60002, hashCode());
- }
int width = mRight - mLeft;
int height = mBottom - mTop;
@@ -7738,7 +7735,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
saveCount = canvas.getSaveCount();
int solidColor = getSolidColor();
- if (solidColor == 0) {
+ // TODO: Temporarily disable fading edges with hardware acceleration
+ if (solidColor == 0 && !canvas.isHardwareAccelerated()) {
final int flags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;
if (drawTop) {
@@ -7946,6 +7944,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
* @param r Right position, relative to parent
* @param b Bottom position, relative to parent
*/
+ @SuppressWarnings({"unchecked"})
public final void layout(int l, int t, int r, int b) {
int oldL = mLeft;
int oldT = mTop;
@@ -10129,11 +10128,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
final RectF mTmpTransformRect = new RectF();
/**
- * Temporary for use in computing invalidation areas with transformed views
- */
- final float[] mTmpTransformBounds = new float[8];
-
- /**
* Temporary list for use in collecting focusable descendents of a view.
*/
final ArrayList<View> mFocusablesTempList = new ArrayList<View>(24);
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 22cc3a8503e1..b1d52725257e 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -119,24 +119,21 @@ public class ViewDebug {
*
* @hide
*/
- @Debug.DebugProperty
- public static boolean profileDrawing = false;
+ public static final boolean DEBUG_PROFILE_DRAWING = false;
/**
* Profiles layout times in the events log.
*
* @hide
*/
- @Debug.DebugProperty
- public static boolean profileLayout = false;
+ public static final boolean DEBUG_PROFILE_LAYOUT = false;
/**
* Profiles real fps (times between draws) and displays the result.
*
* @hide
*/
- @Debug.DebugProperty
- public static boolean showFps = false;
+ public static final boolean DEBUG_SHOW_FPS = false;
/**
* <p>Enables or disables views consistency check. Even when this property is enabled,
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index dee6e736b26a..363ccd687737 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -32,8 +32,6 @@ import android.graphics.Region;
import android.os.Parcelable;
import android.os.SystemClock;
import android.util.AttributeSet;
-import android.util.Config;
-import android.util.EventLog;
import android.util.Log;
import android.util.SparseArray;
import android.view.accessibility.AccessibilityEvent;
@@ -2020,9 +2018,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
cachePaint.setAlpha(255);
mGroupFlags &= ~FLAG_ALPHA_LOWER_THAN_ONE;
}
- if (Config.DEBUG && ViewDebug.profileDrawing) {
- EventLog.writeEvent(60003, hashCode());
- }
canvas.drawBitmap(cache, 0.0f, 0.0f, cachePaint);
}
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 5d4ac375b638..e5fc859fe333 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -946,8 +946,8 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
mSurfaceHolder.mSurfaceLock.unlock();
}
}
-
- if (hwIntialized) {
+
+ if (hwIntialized || (windowShouldResize && mHwRenderer != null)) {
mHwRenderer.setup(mWidth, mHeight);
}
@@ -1008,7 +1008,7 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
TAG, "Laying out " + host + " to (" +
host.mMeasuredWidth + ", " + host.mMeasuredHeight + ")");
long startTime = 0L;
- if (ViewDebug.profileLayout) {
+ if (ViewDebug.DEBUG_PROFILE_LAYOUT) {
startTime = SystemClock.elapsedRealtime();
}
host.layout(0, 0, host.mMeasuredWidth, host.mMeasuredHeight);
@@ -1021,7 +1021,7 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
}
}
- if (ViewDebug.profileLayout) {
+ if (ViewDebug.DEBUG_PROFILE_LAYOUT) {
EventLog.writeEvent(60001, SystemClock.elapsedRealtime() - startTime);
}
@@ -1321,7 +1321,7 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
//canvas.drawARGB(255, 255, 0, 0);
}
- if (ViewDebug.profileDrawing) {
+ if (ViewDebug.DEBUG_PROFILE_DRAWING) {
startTime = SystemClock.elapsedRealtime();
}
@@ -1364,7 +1364,7 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
}
- if (SHOW_FPS || ViewDebug.showFps) {
+ if (SHOW_FPS || ViewDebug.DEBUG_SHOW_FPS) {
int now = (int)SystemClock.elapsedRealtime();
if (sDrawTime != 0) {
nativeShowFPS(canvas, now - sDrawTime);
@@ -1372,7 +1372,7 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
sDrawTime = now;
}
- if (ViewDebug.profileDrawing) {
+ if (ViewDebug.DEBUG_PROFILE_DRAWING) {
EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
}
}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 0ed5fc585f72..d81d7f2e88fd 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -211,6 +211,7 @@ public class WebSettings {
private boolean mNavDump = false;
private boolean mSupportZoom = true;
private boolean mBuiltInZoomControls = false;
+ private boolean mDisplayZoomControls = true;
private boolean mAllowFileAccess = true;
private boolean mLoadWithOverviewMode = false;
private boolean mEnableSmoothTransition = false;
@@ -508,6 +509,26 @@ public class WebSettings {
}
/**
+ * Sets whether the on screen zoom buttons are used.
+ * A combination of built in zoom controls enabled
+ * and on screen zoom controls disabled allows for pinch to zoom
+ * to work without the on screen controls
+ * @hide
+ */
+ public void setDisplayZoomControls(boolean enabled) {
+ mDisplayZoomControls = enabled;
+ mWebView.updateMultiTouchSupport(mContext);
+ }
+
+ /**
+ * Returns true if the on screen zoom buttons are being used.
+ * @hide
+ */
+ public boolean getDisplayZoomControls() {
+ return mDisplayZoomControls;
+ }
+
+ /**
* Enable or disable file access within WebView. File access is enabled by
* default.
*/
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 33ebcf595110..132321721ba5 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -856,7 +856,8 @@ class ZoomManager {
private ZoomControlBase getCurrentZoomControl() {
if (mWebView.getSettings() != null && mWebView.getSettings().supportZoom()) {
if (mWebView.getSettings().getBuiltInZoomControls()) {
- if (mEmbeddedZoomControl == null) {
+ if ((mEmbeddedZoomControl == null)
+ && mWebView.getSettings().getDisplayZoomControls()) {
mEmbeddedZoomControl = new ZoomControlEmbedded(this, mWebView);
}
return mEmbeddedZoomControl;
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index 0636d721c148..830e89960209 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -31,6 +31,7 @@ import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
@@ -128,6 +129,13 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
boolean mShouldLoop = true;
/**
+ * The width and height of some child, used as a size reference in-case our
+ * dimensions are unspecified by the parent.
+ */
+ int mReferenceChildWidth = -1;
+ int mReferenceChildHeight = -1;
+
+ /**
* TODO: Animation stuff is still in flux, waiting on the new framework to settle a bit.
*/
Animation mInAnimation;
@@ -414,7 +422,7 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
FrameLayout fl = new FrameLayout(mContext);
fl.addView(newView);
mActiveViews[index] = fl;
- addViewInLayout(fl, -1, createOrReuseLayoutParams(fl));
+ addChild(fl);
applyTransformForChildAtIndex(fl, newRelativeIndex);
animateViewForTransition(-1, newRelativeIndex, fl);
}
@@ -451,6 +459,64 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
}
}
+ private void addChild(View child) {
+ addViewInLayout(child, -1, createOrReuseLayoutParams(child));
+
+ // This code is used to obtain a reference width and height of a child in case we need
+ // to decide our own size. TODO: Do we want to update the size of the child that we're
+ // using for reference size? If so, when?
+ if (mReferenceChildWidth == -1 || mReferenceChildHeight == -1) {
+ int measureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ child.measure(measureSpec, measureSpec);
+ mReferenceChildWidth = child.getMeasuredWidth();
+ mReferenceChildHeight = child.getMeasuredHeight();
+ }
+ }
+
+ private void measureChildren() {
+ final int count = getChildCount();
+ final int childWidth = mMeasuredWidth - mPaddingLeft - mPaddingRight;
+ final int childHeight = mMeasuredHeight - mPaddingTop - mPaddingBottom;
+
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ child.measure(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY));
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
+ int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
+ final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
+ final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
+
+ boolean haveChildRefSize = (mReferenceChildWidth != -1 && mReferenceChildHeight != -1);
+
+ // We need to deal with the case where our parent hasn't told us how
+ // big we should be. In this case we try to use the desired size of the first
+ // child added.
+ if (heightSpecMode == MeasureSpec.UNSPECIFIED) {
+ heightSpecSize = haveChildRefSize ? mReferenceChildHeight + mPaddingTop +
+ mPaddingBottom : 0;
+ } else if (heightSpecMode == MeasureSpec.AT_MOST) {
+ heightSpecSize = haveChildRefSize ? Math.min(mReferenceChildHeight + mPaddingTop +
+ mPaddingBottom, heightSpecSize) : 0;
+ }
+
+ if (widthSpecMode == MeasureSpec.UNSPECIFIED) {
+ widthSpecSize = haveChildRefSize ? mReferenceChildWidth + mPaddingLeft +
+ mPaddingRight : 0;
+ } else if (heightSpecMode == MeasureSpec.AT_MOST) {
+ widthSpecSize = haveChildRefSize ? Math.min(mReferenceChildWidth + mPaddingLeft +
+ mPaddingRight, widthSpecSize) : 0;
+ }
+
+ setMeasuredDimension(widthSpecSize, heightSpecSize);
+ measureChildren();
+ }
+
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
boolean dataChanged = mDataChanged;
@@ -472,8 +538,7 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
int childRight = mPaddingLeft + child.getMeasuredWidth();
int childBottom = mPaddingTop + child.getMeasuredHeight();
- child.layout(mPaddingLeft, mPaddingTop,
- childRight, childBottom);
+ child.layout(mPaddingLeft, mPaddingTop, childRight, childBottom);
}
mDataChanged = false;
}
@@ -538,31 +603,6 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
setDisplayedChild(mWhichChild);
}
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- final int count = getChildCount();
-
- int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
- int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
-
- for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
-
- final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
- lp.width = widthSpecSize - mPaddingLeft - mPaddingRight;
- lp.height = heightSpecSize - mPaddingTop - mPaddingBottom;
-
- int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width,
- MeasureSpec.EXACTLY);
- int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height,
- MeasureSpec.EXACTLY);
-
- child.measure(childWidthMeasureSpec, childheightMeasureSpec);
- }
- setMeasuredDimension(widthSpecSize, heightSpecSize);
- }
-
/**
* Shows only the specified child. The other displays Views exit the screen
* with the {@link #getOutAnimation() out animation} and the specified child
diff --git a/core/java/android/widget/QuickContactBadge.java b/core/java/android/widget/QuickContactBadge.java
index 50fbb6b30c26..5598c6546dec 100644
--- a/core/java/android/widget/QuickContactBadge.java
+++ b/core/java/android/widget/QuickContactBadge.java
@@ -247,6 +247,7 @@ public class QuickContactBadge extends ImageView implements OnClickListener {
trigger = true;
createUri = Uri.fromParts("tel", (String)cookie, null);
+ //$FALL-THROUGH$
case TOKEN_PHONE_LOOKUP: {
if (cursor != null && cursor.moveToFirst()) {
long contactId = cursor.getLong(PHONE_ID_COLUMN_INDEX);
@@ -260,12 +261,14 @@ public class QuickContactBadge extends ImageView implements OnClickListener {
trigger = true;
createUri = Uri.fromParts("mailto", (String)cookie, null);
+ //$FALL-THROUGH$
case TOKEN_EMAIL_LOOKUP: {
if (cursor != null && cursor.moveToFirst()) {
long contactId = cursor.getLong(EMAIL_ID_COLUMN_INDEX);
String lookupKey = cursor.getString(EMAIL_LOOKUP_STRING_COLUMN_INDEX);
lookupUri = Contacts.getLookupUri(contactId, lookupKey);
}
+ break;
}
case TOKEN_CONTACT_LOOKUP_AND_TRIGGER: {
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 9816b395a2a1..9025b83d5022 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -16,11 +16,11 @@
package android.widget;
-import java.util.WeakHashMap;
-
import android.animation.PropertyAnimator;
+import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.graphics.Bitmap;
+import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
@@ -28,6 +28,7 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.graphics.TableMaskFilter;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
@@ -35,6 +36,8 @@ import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
+import android.view.View.MeasureSpec;
+import android.view.ViewGroup.LayoutParams;
import android.view.animation.LinearInterpolator;
import android.widget.RemoteViews.RemoteView;
@@ -53,6 +56,19 @@ public class StackView extends AdapterViewAnimator {
private final int MINIMUM_ANIMATION_DURATION = 50;
/**
+ * Parameters effecting the perspective visuals
+ */
+ private static float PERSPECTIVE_SHIFT_FACTOR = 0.12f;
+ private static float PERSPECTIVE_SCALE_FACTOR = 0.35f;
+
+ /**
+ * Represent the two possible stack modes, one where items slide up, and the other
+ * where items slide down. The perspective is also inverted between these two modes.
+ */
+ private static final int ITEMS_SLIDE_UP = 0;
+ private static final int ITEMS_SLIDE_DOWN = 1;
+
+ /**
* These specify the different gesture states
*/
private static final int GESTURE_NONE = 0;
@@ -66,8 +82,6 @@ public class StackView extends AdapterViewAnimator {
private static final float SWIPE_THRESHOLD_RATIO = 0.35f;
private static final float SLIDE_UP_RATIO = 0.7f;
- private final WeakHashMap<View, Float> mRotations = new WeakHashMap<View, Float>();
-
/**
* Sentinel value for no current active pointer.
* Used by {@link #mActivePointerId}.
@@ -75,6 +89,12 @@ public class StackView extends AdapterViewAnimator {
private static final int INVALID_POINTER = -1;
/**
+ * Number of active views in the stack. One fewer view is actually visible, as one is hidden.
+ */
+ private static final int NUM_ACTIVE_VIEWS = 5;
+
+
+ /**
* These variables are all related to the current state of touch interaction
* with the stack
*/
@@ -95,6 +115,7 @@ public class StackView extends AdapterViewAnimator {
private boolean mFirstLayoutHappened = false;
private ViewGroup mAncestorContainingAllChildren = null;
private int mAncestorHeight = 0;
+ private int mStackMode;
public StackView(Context context) {
super(context);
@@ -107,7 +128,7 @@ public class StackView extends AdapterViewAnimator {
}
private void initStackView() {
- configureViewAnimator(4, 2, false);
+ configureViewAnimator(NUM_ACTIVE_VIEWS, NUM_ACTIVE_VIEWS - 2, false);
setStaticTransformationsEnabled(true);
final ViewConfiguration configuration = ViewConfiguration.get(getContext());
mTouchSlop = configuration.getScaledTouchSlop();
@@ -125,6 +146,11 @@ public class StackView extends AdapterViewAnimator {
setClipChildren(false);
setClipToPadding(false);
+ // This sets the form of the StackView, which is currently to have the perspective-shifted
+ // views above the active view, and have items slide down when sliding out. The opposite is
+ // available by using ITEMS_SLIDE_UP.
+ mStackMode = ITEMS_SLIDE_DOWN;
+
// This is a flag to indicate the the stack is loading for the first time
mWhichChild = -1;
}
@@ -140,7 +166,7 @@ public class StackView extends AdapterViewAnimator {
}
view.setVisibility(VISIBLE);
- PropertyAnimator fadeIn = new PropertyAnimator(DEFAULT_ANIMATION_DURATION,
+ PropertyAnimator<Float> fadeIn = new PropertyAnimator<Float>(DEFAULT_ANIMATION_DURATION,
view, "alpha", view.getAlpha(), 1.0f);
fadeIn.start();
} else if (fromIndex == mNumActiveViews - 1 && toIndex == mNumActiveViews - 2) {
@@ -148,49 +174,32 @@ public class StackView extends AdapterViewAnimator {
view.setVisibility(VISIBLE);
LayoutParams lp = (LayoutParams) view.getLayoutParams();
- int largestDuration =
- Math.round(mStackSlider.getDurationForNeutralPosition()*DEFAULT_ANIMATION_DURATION);
-
- int duration = largestDuration;
- if (mYVelocity != 0) {
- duration = 1000*(0 - lp.verticalOffset)/Math.abs(mYVelocity);
- }
-
- duration = Math.min(duration, largestDuration);
- duration = Math.max(duration, MINIMUM_ANIMATION_DURATION);
+ int duration = Math.round(mStackSlider.getDurationForNeutralPosition(mYVelocity));
StackSlider animationSlider = new StackSlider(mStackSlider);
- PropertyAnimator slideInY = new PropertyAnimator(duration, animationSlider,
- "YProgress", mStackSlider.getYProgress(), 0);
- slideInY.setInterpolator(new LinearInterpolator());
- slideInY.start();
- PropertyAnimator slideInX = new PropertyAnimator(duration, animationSlider,
- "XProgress", mStackSlider.getXProgress(), 0);
- slideInX.setInterpolator(new LinearInterpolator());
- slideInX.start();
+ PropertyValuesHolder<Float> slideInY =
+ new PropertyValuesHolder<Float>("YProgress", 0.0f);
+ PropertyValuesHolder<Float> slideInX =
+ new PropertyValuesHolder<Float>("XProgress", 0.0f);
+ PropertyAnimator pa = new PropertyAnimator(duration, animationSlider,
+ slideInX, slideInY);
+ pa.setInterpolator(new LinearInterpolator());
+ pa.start();
} else if (fromIndex == mNumActiveViews - 2 && toIndex == mNumActiveViews - 1) {
// Slide item out
LayoutParams lp = (LayoutParams) view.getLayoutParams();
- int largestDuration = Math.round(mStackSlider.getDurationForOffscreenPosition()*
- DEFAULT_ANIMATION_DURATION);
- int duration = largestDuration;
- if (mYVelocity != 0) {
- duration = 1000*(lp.verticalOffset + mViewHeight)/Math.abs(mYVelocity);
- }
-
- duration = Math.min(duration, largestDuration);
- duration = Math.max(duration, MINIMUM_ANIMATION_DURATION);
+ int duration = Math.round(mStackSlider.getDurationForOffscreenPosition(mYVelocity));
StackSlider animationSlider = new StackSlider(mStackSlider);
- PropertyAnimator slideOutY = new PropertyAnimator(duration, animationSlider,
- "YProgress", mStackSlider.getYProgress(), 1);
- slideOutY.setInterpolator(new LinearInterpolator());
- slideOutY.start();
- PropertyAnimator slideOutX = new PropertyAnimator(duration, animationSlider,
- "XProgress", mStackSlider.getXProgress(), 0);
- slideOutX.setInterpolator(new LinearInterpolator());
- slideOutX.start();
+ PropertyValuesHolder<Float> slideOutY =
+ new PropertyValuesHolder<Float>("YProgress", 1.0f);
+ PropertyValuesHolder<Float> slideOutX =
+ new PropertyValuesHolder<Float>("XProgress", 0.0f);
+ PropertyAnimator pa = new PropertyAnimator(duration, animationSlider,
+ slideOutX, slideOutY);
+ pa.setInterpolator(new LinearInterpolator());
+ pa.start();
} else if (fromIndex == -1 && toIndex == mNumActiveViews - 1) {
// Make sure this view that is "waiting in the wings" is invisible
view.setAlpha(0.0f);
@@ -199,28 +208,41 @@ public class StackView extends AdapterViewAnimator {
lp.setVerticalOffset(-mViewHeight);
} else if (toIndex == -1) {
// Fade item out
- PropertyAnimator fadeOut = new PropertyAnimator(DEFAULT_ANIMATION_DURATION,
- view, "alpha", view.getAlpha(), 0);
+ PropertyAnimator<Float> fadeOut = new PropertyAnimator<Float>
+ (DEFAULT_ANIMATION_DURATION, view, "alpha", view.getAlpha(), 0.0f);
fadeOut.start();
}
+
+ // Implement the faked perspective
+ if (toIndex != -1) {
+ float maxPerpectiveShift = mViewHeight * PERSPECTIVE_SHIFT_FACTOR;
+ int index = toIndex;
+
+ if (toIndex == mNumActiveViews -1) index--;
+
+ float r = (index * 1.0f) / (mNumActiveViews - 2);
+
+ float scale = 1 - PERSPECTIVE_SCALE_FACTOR * (1 - r);
+ PropertyValuesHolder<Float> scaleX = new PropertyValuesHolder<Float>("scaleX", scale);
+ PropertyValuesHolder<Float> scaleY = new PropertyValuesHolder<Float>("scaleY", scale);
+
+ r = (float) Math.pow(r, 2);
+
+ int stackDirection = (mStackMode == ITEMS_SLIDE_UP) ? 1 : -1;
+ float transY = -stackDirection * r * maxPerpectiveShift +
+ stackDirection * (1 - scale) * (mViewHeight / 2.0f);
+
+ PropertyValuesHolder<Float> translationY =
+ new PropertyValuesHolder<Float>("translationY", transY);
+ PropertyAnimator pa = new PropertyAnimator(100, view, scaleX, scaleY, translationY);
+ pa.start();
+ }
}
/**
* Apply any necessary tranforms for the child that is being added.
*/
void applyTransformForChildAtIndex(View child, int relativeIndex) {
- if (!mRotations.containsKey(child)) {
- float rotation = (float) (Math.random()*26 - 13);
- mRotations.put(child, rotation);
- child.setRotation(rotation);
- }
-
- // Child has been removed
- if (relativeIndex == -1) {
- if (mRotations.containsKey(child)) {
- mRotations.remove(child);
- }
- }
}
@Override
@@ -248,8 +270,8 @@ public class StackView extends AdapterViewAnimator {
private void onLayout() {
if (!mFirstLayoutHappened) {
- mViewHeight = Math.round(SLIDE_UP_RATIO*getMeasuredHeight());
- mSwipeThreshold = Math.round(SWIPE_THRESHOLD_RATIO*mViewHeight);
+ mViewHeight = Math.round(SLIDE_UP_RATIO * getMeasuredHeight());
+ mSwipeThreshold = Math.round(SWIPE_THRESHOLD_RATIO * mViewHeight);
mFirstLayoutHappened = true;
}
}
@@ -299,8 +321,14 @@ public class StackView extends AdapterViewAnimator {
cancelLongPress();
requestDisallowInterceptTouchEvent(true);
- int activeIndex = swipeGestureType == GESTURE_SLIDE_DOWN ? mNumActiveViews - 1
- : mNumActiveViews - 2;
+ int activeIndex;
+ if (mStackMode == ITEMS_SLIDE_UP) {
+ activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ?
+ mNumActiveViews - 1 : mNumActiveViews - 2;
+ } else {
+ activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ?
+ mNumActiveViews - 2 : mNumActiveViews - 1;
+ }
if (mAdapter == null) return;
@@ -317,6 +345,8 @@ public class StackView extends AdapterViewAnimator {
if (v == null) return;
mHighlight.setImageBitmap(sHolographicHelper.createOutline(v));
+ mHighlight.setRotation(v.getRotation());
+ mHighlight.setTranslationY(v.getTranslationY());
mHighlight.bringToFront();
v.bringToFront();
mStackSlider.setView(v);
@@ -352,14 +382,16 @@ public class StackView extends AdapterViewAnimator {
case MotionEvent.ACTION_MOVE: {
beginGestureIfNeeded(deltaY);
- float rx = deltaX/(mViewHeight*1.0f);
+ float rx = deltaX / (mViewHeight * 1.0f);
if (mSwipeGestureType == GESTURE_SLIDE_DOWN) {
- float r = (deltaY-mTouchSlop*1.0f)/mViewHeight*1.0f;
+ float r = (deltaY - mTouchSlop * 1.0f) / mViewHeight * 1.0f;
+ if (mStackMode == ITEMS_SLIDE_DOWN) r = 1 - r;
mStackSlider.setYProgress(1 - r);
mStackSlider.setXProgress(rx);
return true;
} else if (mSwipeGestureType == GESTURE_SLIDE_UP) {
- float r = -(deltaY + mTouchSlop*1.0f)/mViewHeight*1.0f;
+ float r = -(deltaY + mTouchSlop * 1.0f) / mViewHeight * 1.0f;
+ if (mStackMode == ITEMS_SLIDE_DOWN) r = 1 - r;
mStackSlider.setYProgress(r);
mStackSlider.setXProgress(rx);
return true;
@@ -447,41 +479,59 @@ public class StackView extends AdapterViewAnimator {
if (deltaY > mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_DOWN
&& mStackSlider.mMode == StackSlider.NORMAL_MODE) {
// Swipe threshold exceeded, swipe down
- showNext();
+ if (mStackMode == ITEMS_SLIDE_UP) {
+ showNext();
+ } else {
+ showPrevious();
+ }
mHighlight.bringToFront();
} else if (deltaY < -mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_UP
&& mStackSlider.mMode == StackSlider.NORMAL_MODE) {
// Swipe threshold exceeded, swipe up
- showPrevious();
+ if (mStackMode == ITEMS_SLIDE_UP) {
+ showPrevious();
+ } else {
+ showNext();
+ }
+
mHighlight.bringToFront();
- } else if (mSwipeGestureType == GESTURE_SLIDE_UP) {
+ } else if (mSwipeGestureType == GESTURE_SLIDE_UP ) {
// Didn't swipe up far enough, snap back down
- int duration =
- Math.round(mStackSlider.getDurationForNeutralPosition()*DEFAULT_ANIMATION_DURATION);
+ int duration;
+ float finalYProgress = (mStackMode == ITEMS_SLIDE_DOWN) ? 1 : 0;
+ if (mStackMode == ITEMS_SLIDE_UP || mStackSlider.mMode != StackSlider.NORMAL_MODE) {
+ duration = Math.round(mStackSlider.getDurationForNeutralPosition());
+ } else {
+ duration = Math.round(mStackSlider.getDurationForOffscreenPosition());
+ }
StackSlider animationSlider = new StackSlider(mStackSlider);
- PropertyAnimator snapBackY = new PropertyAnimator(duration, animationSlider,
- "YProgress", mStackSlider.getYProgress(), 0);
- snapBackY.setInterpolator(new LinearInterpolator());
- snapBackY.start();
- PropertyAnimator snapBackX = new PropertyAnimator(duration, animationSlider,
- "XProgress", mStackSlider.getXProgress(), 0);
- snapBackX.setInterpolator(new LinearInterpolator());
- snapBackX.start();
+ PropertyValuesHolder<Float> snapBackY =
+ new PropertyValuesHolder<Float>("YProgress", finalYProgress);
+ PropertyValuesHolder<Float> snapBackX =
+ new PropertyValuesHolder<Float>("XProgress", 0.0f);
+ PropertyAnimator pa = new PropertyAnimator(duration, animationSlider,
+ snapBackX, snapBackY);
+ pa.setInterpolator(new LinearInterpolator());
+ pa.start();
} else if (mSwipeGestureType == GESTURE_SLIDE_DOWN) {
// Didn't swipe down far enough, snap back up
- int duration = Math.round(mStackSlider.getDurationForOffscreenPosition()*
- DEFAULT_ANIMATION_DURATION);
+ float finalYProgress = (mStackMode == ITEMS_SLIDE_DOWN) ? 0 : 1;
+ int duration;
+ if (mStackMode == ITEMS_SLIDE_DOWN || mStackSlider.mMode != StackSlider.NORMAL_MODE) {
+ duration = Math.round(mStackSlider.getDurationForNeutralPosition());
+ } else {
+ duration = Math.round(mStackSlider.getDurationForOffscreenPosition());
+ }
StackSlider animationSlider = new StackSlider(mStackSlider);
- PropertyAnimator snapBackY = new PropertyAnimator(duration, animationSlider,
- "YProgress", mStackSlider.getYProgress(), 1);
- snapBackY.setInterpolator(new LinearInterpolator());
- snapBackY.start();
- PropertyAnimator snapBackX = new PropertyAnimator(duration, animationSlider,
- "XProgress", mStackSlider.getXProgress(), 0);
- snapBackX.setInterpolator(new LinearInterpolator());
- snapBackX.start();
+ PropertyValuesHolder<Float> snapBackY =
+ new PropertyValuesHolder<Float>("YProgress", finalYProgress);
+ PropertyValuesHolder<Float> snapBackX =
+ new PropertyValuesHolder<Float>("XProgress", 0.0f);
+ PropertyAnimator pa = new PropertyAnimator(duration, animationSlider,
+ snapBackX, snapBackY);
+ pa.start();
}
mActivePointerId = INVALID_POINTER;
@@ -510,22 +560,22 @@ public class StackView extends AdapterViewAnimator {
}
private float cubic(float r) {
- return (float) (Math.pow(2*r-1, 3) + 1)/2.0f;
+ return (float) (Math.pow(2 * r - 1, 3) + 1) / 2.0f;
}
private float highlightAlphaInterpolator(float r) {
float pivot = 0.4f;
if (r < pivot) {
- return 0.85f*cubic(r/pivot);
+ return 0.85f * cubic(r / pivot);
} else {
- return 0.85f*cubic(1 - (r-pivot)/(1-pivot));
+ return 0.85f * cubic(1 - (r - pivot) / (1 - pivot));
}
}
private float viewAlphaInterpolator(float r) {
float pivot = 0.3f;
if (r > pivot) {
- return (r - pivot)/(1 - pivot);
+ return (r - pivot) / (1 - pivot);
} else {
return 0;
}
@@ -536,7 +586,7 @@ public class StackView extends AdapterViewAnimator {
if (r < pivot) {
return 0;
} else {
- return (r-pivot)/(1-pivot);
+ return (r - pivot) / (1 - pivot);
}
}
@@ -553,13 +603,15 @@ public class StackView extends AdapterViewAnimator {
final LayoutParams viewLp = (LayoutParams) mView.getLayoutParams();
final LayoutParams highlightLp = (LayoutParams) mHighlight.getLayoutParams();
+ int stackDirection = (mStackMode == ITEMS_SLIDE_UP) ? 1 : -1;
+
switch (mMode) {
case NORMAL_MODE:
- viewLp.setVerticalOffset(Math.round(-r*mViewHeight));
- highlightLp.setVerticalOffset(Math.round(-r*mViewHeight));
+ viewLp.setVerticalOffset(Math.round(-r * stackDirection * mViewHeight));
+ highlightLp.setVerticalOffset(Math.round(-r * stackDirection * mViewHeight));
mHighlight.setAlpha(highlightAlphaInterpolator(r));
- float alpha = viewAlphaInterpolator(1-r);
+ float alpha = viewAlphaInterpolator(1 - r);
// We make sure that views which can't be seen (have 0 alpha) are also invisible
// so that they don't interfere with click events.
@@ -571,19 +623,19 @@ public class StackView extends AdapterViewAnimator {
}
mView.setAlpha(alpha);
- mView.setRotationX(90.0f*rotationInterpolator(r));
- mHighlight.setRotationX(90.0f*rotationInterpolator(r));
+ mView.setRotationX(stackDirection * 90.0f * rotationInterpolator(r));
+ mHighlight.setRotationX(stackDirection * 90.0f * rotationInterpolator(r));
break;
case BEGINNING_OF_STACK_MODE:
- r = r*0.2f;
- viewLp.setVerticalOffset(Math.round(-r*mViewHeight));
- highlightLp.setVerticalOffset(Math.round(-r*mViewHeight));
+ r = r * 0.2f;
+ viewLp.setVerticalOffset(Math.round(-stackDirection * r * mViewHeight));
+ highlightLp.setVerticalOffset(Math.round(-stackDirection * r * mViewHeight));
mHighlight.setAlpha(highlightAlphaInterpolator(r));
break;
case END_OF_STACK_MODE:
- r = (1-r)*0.2f;
- viewLp.setVerticalOffset(Math.round(r*mViewHeight));
- highlightLp.setVerticalOffset(Math.round(r*mViewHeight));
+ r = (1-r) * 0.2f;
+ viewLp.setVerticalOffset(Math.round(stackDirection * r * mViewHeight));
+ highlightLp.setVerticalOffset(Math.round(stackDirection * r * mViewHeight));
mHighlight.setAlpha(highlightAlphaInterpolator(r));
break;
}
@@ -600,8 +652,8 @@ public class StackView extends AdapterViewAnimator {
final LayoutParams highlightLp = (LayoutParams) mHighlight.getLayoutParams();
r *= 0.2f;
- viewLp.setHorizontalOffset(Math.round(r*mViewHeight));
- highlightLp.setHorizontalOffset(Math.round(r*mViewHeight));
+ viewLp.setHorizontalOffset(Math.round(r * mViewHeight));
+ highlightLp.setHorizontalOffset(Math.round(r * mViewHeight));
}
void setMode(int mode) {
@@ -609,31 +661,51 @@ public class StackView extends AdapterViewAnimator {
}
float getDurationForNeutralPosition() {
- return getDuration(false);
+ return getDuration(false, 0);
}
float getDurationForOffscreenPosition() {
- return getDuration(mMode == END_OF_STACK_MODE ? false : true);
+ return getDuration(true, 0);
+ }
+
+ float getDurationForNeutralPosition(float velocity) {
+ return getDuration(false, velocity);
+ }
+
+ float getDurationForOffscreenPosition(float velocity) {
+ return getDuration(true, velocity);
}
- private float getDuration(boolean invert) {
+ private float getDuration(boolean invert, float velocity) {
if (mView != null) {
final LayoutParams viewLp = (LayoutParams) mView.getLayoutParams();
- float d = (float) Math.sqrt(Math.pow(viewLp.horizontalOffset,2) +
- Math.pow(viewLp.verticalOffset,2));
+ float d = (float) Math.sqrt(Math.pow(viewLp.horizontalOffset, 2) +
+ Math.pow(viewLp.verticalOffset, 2));
float maxd = (float) Math.sqrt(Math.pow(mViewHeight, 2) +
- Math.pow(0.4f*mViewHeight, 2));
- return invert ? (1-d/maxd) : d/maxd;
+ Math.pow(0.4f * mViewHeight, 2));
+
+ if (velocity == 0) {
+ return (invert ? (1 - d / maxd) : d / maxd) * DEFAULT_ANIMATION_DURATION;
+ } else {
+ float duration = invert ? d / Math.abs(velocity) :
+ (maxd - d) / Math.abs(velocity);
+ if (duration < MINIMUM_ANIMATION_DURATION ||
+ duration > DEFAULT_ANIMATION_DURATION) {
+ return getDuration(invert, 0);
+ } else {
+ return duration;
+ }
+ }
}
return 0;
}
- float getYProgress() {
+ public float getYProgress() {
return mYProgress;
}
- float getXProgress() {
+ public float getXProgress() {
return mXProgress;
}
}
@@ -654,6 +726,8 @@ public class StackView extends AdapterViewAnimator {
LayoutParams lp = (LayoutParams) currentLp;
lp.setHorizontalOffset(0);
lp.setVerticalOffset(0);
+ lp.width = 0;
+ lp.width = 0;
return lp;
}
return new LayoutParams(v);
@@ -684,15 +758,59 @@ public class StackView extends AdapterViewAnimator {
child.layout(mPaddingLeft + lp.horizontalOffset, mPaddingTop + lp.verticalOffset,
childRight + lp.horizontalOffset, childBottom + lp.verticalOffset);
- //TODO: temp until fix in View
- child.setPivotX(child.getMeasuredWidth()/2);
- child.setPivotY(child.getMeasuredHeight()/2);
}
mDataChanged = false;
onLayout();
}
+ private void measureChildren() {
+ final int count = getChildCount();
+ final int childWidth = mMeasuredWidth - mPaddingLeft - mPaddingRight;
+ final int childHeight = Math.round(mMeasuredHeight*(1-PERSPECTIVE_SHIFT_FACTOR))
+ - mPaddingTop - mPaddingBottom;
+
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ child.measure(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY));
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
+ int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
+ final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
+ final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
+
+ boolean haveChildRefSize = (mReferenceChildWidth != -1 && mReferenceChildHeight != -1);
+
+ // We need to deal with the case where our parent hasn't told us how
+ // big we should be. In this case we should
+ float factor = 1/(1 - PERSPECTIVE_SHIFT_FACTOR);
+ if (heightSpecMode == MeasureSpec.UNSPECIFIED) {
+ heightSpecSize = haveChildRefSize ?
+ Math.round(mReferenceChildHeight * (1 + factor)) +
+ mPaddingTop + mPaddingBottom : 0;
+ } else if (heightSpecMode == MeasureSpec.AT_MOST) {
+ heightSpecSize = haveChildRefSize ? Math.min(
+ Math.round(mReferenceChildHeight * (1 + factor)) + mPaddingTop +
+ mPaddingBottom, heightSpecSize) : 0;
+ }
+
+ if (widthSpecMode == MeasureSpec.UNSPECIFIED) {
+ widthSpecSize = haveChildRefSize ? mReferenceChildWidth + mPaddingLeft +
+ mPaddingRight : 0;
+ } else if (heightSpecMode == MeasureSpec.AT_MOST) {
+ widthSpecSize = haveChildRefSize ? Math.min(mReferenceChildWidth + mPaddingLeft +
+ mPaddingRight, widthSpecSize) : 0;
+ }
+
+ setMeasuredDimension(widthSpecSize, heightSpecSize);
+ measureChildren();
+ }
+
class LayoutParams extends ViewGroup.LayoutParams {
int horizontalOffset;
int verticalOffset;
@@ -700,6 +818,8 @@ public class StackView extends AdapterViewAnimator {
LayoutParams(View view) {
super(0, 0);
+ width = 0;
+ height = 0;
horizontalOffset = 0;
verticalOffset = 0;
mView = view;
@@ -709,6 +829,8 @@ public class StackView extends AdapterViewAnimator {
super(c, attrs);
horizontalOffset = 0;
verticalOffset = 0;
+ width = 0;
+ height = 0;
}
private Rect parentRect = new Rect();
@@ -731,6 +853,10 @@ public class StackView extends AdapterViewAnimator {
gp = (View) p.getParent();
parentRect.set(p.getLeft() - gp.getScrollX(), p.getTop() - gp.getScrollY(),
p.getRight() - gp.getScrollX(), p.getBottom() - gp.getScrollY());
+
+ // TODO: we need to stop early here if we've hit the edge of the screen
+ // so as to prevent us from walking too high in the hierarchy. A lot of this
+ // code might become a lot more straightforward.
}
if (depth > mAncestorHeight) {
@@ -799,7 +925,7 @@ public class StackView extends AdapterViewAnimator {
private static class HolographicHelper {
private final Paint mHolographicPaint = new Paint();
private final Paint mErasePaint = new Paint();
- private final float STROKE_WIDTH = 3.0f;
+ private final Paint mBlurPaint = new Paint();
HolographicHelper() {
initializePaints();
@@ -808,8 +934,10 @@ public class StackView extends AdapterViewAnimator {
void initializePaints() {
mHolographicPaint.setColor(0xff6699ff);
mHolographicPaint.setFilterBitmap(true);
+ mHolographicPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));
mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
mErasePaint.setFilterBitmap(true);
+ mBlurPaint.setMaskFilter(new BlurMaskFilter(2, BlurMaskFilter.Blur.NORMAL));
}
Bitmap createOutline(View v) {
@@ -822,31 +950,31 @@ public class StackView extends AdapterViewAnimator {
Canvas canvas = new Canvas(bitmap);
float rotationX = v.getRotationX();
+ float rotation = v.getRotation();
+ float translationY = v.getTranslationY();
v.setRotationX(0);
+ v.setRotation(0);
+ v.setTranslationY(0);
canvas.concat(v.getMatrix());
v.draw(canvas);
-
v.setRotationX(rotationX);
+ v.setRotation(rotation);
+ v.setTranslationY(translationY);
+ canvas.setMatrix(id);
drawOutline(canvas, bitmap);
return bitmap;
}
final Matrix id = new Matrix();
- final Matrix scaleMatrix = new Matrix();
void drawOutline(Canvas dest, Bitmap src) {
- Bitmap mask = src.extractAlpha();
-
+ int[] xy = new int[2];
+ Bitmap mask = src.extractAlpha(mBlurPaint, xy);
+ Canvas maskCanvas = new Canvas(mask);
+ maskCanvas.drawBitmap(src, -xy[0], -xy[1], mErasePaint);
dest.drawColor(0, PorterDuff.Mode.CLEAR);
-
- float xScale = STROKE_WIDTH*2/(dest.getWidth());
- float yScale = STROKE_WIDTH*2/(dest.getHeight());
-
- scaleMatrix.reset();
- scaleMatrix.preScale(1+xScale, 1+yScale, dest.getWidth()/2, dest.getHeight()/2);
dest.setMatrix(id);
- dest.drawBitmap(mask, scaleMatrix, mHolographicPaint);
- dest.drawBitmap(mask, id, mErasePaint);
+ dest.drawBitmap(mask, xy[0], xy[1], mHolographicPaint);
mask.recycle();
}
}
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 104835283b21..cf029d23874b 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -122,17 +122,6 @@ public class ActionBarImpl extends ActionBar {
}
@Override
- public void setStandardNavigationMode(int titleResId, int subtitleResId) {
- setStandardNavigationMode(mContext.getString(titleResId),
- mContext.getString(subtitleResId));
- }
-
- @Override
- public void setStandardNavigationMode(int titleResId) {
- setStandardNavigationMode(mContext.getString(titleResId));
- }
-
- @Override
public void setTitle(int resId) {
setTitle(mContext.getString(resId));
}
@@ -169,19 +158,6 @@ public class ActionBarImpl extends ActionBar {
mActionView.setCallback(null);
}
- public void setStandardNavigationMode(CharSequence title) {
- cleanupTabs();
- setStandardNavigationMode(title, null);
- }
-
- public void setStandardNavigationMode(CharSequence title, CharSequence subtitle) {
- cleanupTabs();
- mActionView.setNavigationMode(NAVIGATION_MODE_STANDARD);
- mActionView.setTitle(title);
- mActionView.setSubtitle(subtitle);
- mActionView.setCallback(null);
- }
-
public void setSelectedNavigationItem(int position) {
switch (mActionView.getNavigationMode()) {
case NAVIGATION_MODE_TABS:
@@ -211,17 +187,7 @@ public class ActionBarImpl extends ActionBar {
if (mSelectedTab != null) {
selectTab(null);
}
- if (!mTabs.isEmpty()) {
- if (mTabSwitchMode == TAB_SWITCH_SHOW_HIDE) {
- final FragmentTransaction trans = mActivity.openFragmentTransaction();
- final int tabCount = mTabs.size();
- for (int i = 0; i < tabCount; i++) {
- trans.remove(mTabs.get(i).getFragment());
- }
- trans.commit();
- }
- mTabs.clear();
- }
+ mTabs.clear();
}
public void setTitle(CharSequence title) {
@@ -295,31 +261,23 @@ public class ActionBarImpl extends ActionBar {
private void configureTab(Tab tab, int position) {
final TabImpl tabi = (TabImpl) tab;
final boolean isFirstTab = mTabs.isEmpty();
- final FragmentTransaction trans = mActivity.openFragmentTransaction();
- final Fragment frag = tabi.getFragment();
+ final ActionBar.TabListener callback = tabi.getCallback();
+
+ if (callback == null) {
+ throw new IllegalStateException("Action Bar Tab must have a Callback");
+ }
tabi.setPosition(position);
mTabs.add(position, tabi);
- if (mTabSwitchMode == TAB_SWITCH_SHOW_HIDE) {
- if (!frag.isAdded()) {
- trans.add(mTabContainerViewId, frag);
- }
- }
-
if (isFirstTab) {
- if (mTabSwitchMode == TAB_SWITCH_SHOW_HIDE) {
- trans.show(frag);
- } else if (mTabSwitchMode == TAB_SWITCH_ADD_REMOVE) {
- trans.add(mTabContainerViewId, frag);
- }
+ final FragmentTransaction trans = mActivity.getFragmentManager().openTransaction();
mSelectedTab = tabi;
- } else {
- if (mTabSwitchMode == TAB_SWITCH_SHOW_HIDE) {
- trans.hide(frag);
+ callback.onTabSelected(tab, trans);
+ if (!trans.isEmpty()) {
+ trans.commit();
}
}
- trans.commit();
}
@Override
@@ -329,8 +287,8 @@ public class ActionBarImpl extends ActionBar {
}
@Override
- public void insertTab(Tab tab, int position) {
- mActionView.insertTab(tab, position);
+ public void addTab(Tab tab, int position) {
+ mActionView.addTab(tab, position);
configureTab(tab, position);
}
@@ -367,35 +325,29 @@ public class ActionBarImpl extends ActionBar {
}
@Override
- public void setTabNavigationMode(int containerViewId) {
- mTabContainerViewId = containerViewId;
- setTabNavigationMode();
- }
-
- @Override
public void selectTab(Tab tab) {
if (mSelectedTab == tab) {
return;
}
mActionView.setTabSelected(tab != null ? tab.getPosition() : Tab.INVALID_POSITION);
- final FragmentTransaction trans = mActivity.openFragmentTransaction();
+ final FragmentTransaction trans = mActivity.getFragmentManager().openTransaction();
if (mSelectedTab != null) {
- if (mTabSwitchMode == TAB_SWITCH_SHOW_HIDE) {
- trans.hide(mSelectedTab.getFragment());
- } else if (mTabSwitchMode == TAB_SWITCH_ADD_REMOVE) {
- trans.remove(mSelectedTab.getFragment());
- }
- }
- if (tab != null) {
- if (mTabSwitchMode == TAB_SWITCH_SHOW_HIDE) {
- trans.show(tab.getFragment());
- } else if (mTabSwitchMode == TAB_SWITCH_ADD_REMOVE) {
- trans.add(mTabContainerViewId, tab.getFragment());
- }
+ mSelectedTab.getCallback().onTabUnselected(mSelectedTab, trans);
}
mSelectedTab = (TabImpl) tab;
- trans.commit();
+ if (mSelectedTab != null) {
+ mSelectedTab.getCallback().onTabSelected(mSelectedTab, trans);
+ }
+
+ if (!trans.isEmpty()) {
+ trans.commit();
+ }
+ }
+
+ @Override
+ public Tab getSelectedTab() {
+ return mSelectedTab;
}
@Override
@@ -542,14 +494,40 @@ public class ActionBarImpl extends ActionBar {
* @hide
*/
public class TabImpl extends ActionBar.Tab {
- private Fragment mFragment;
+ private ActionBar.TabListener mCallback;
+ private Object mTag;
private Drawable mIcon;
private CharSequence mText;
private int mPosition;
+ private View mCustomView;
@Override
- public Fragment getFragment() {
- return mFragment;
+ public Object getTag() {
+ return mTag;
+ }
+
+ @Override
+ public void setTag(Object tag) {
+ mTag = tag;
+ }
+
+ public ActionBar.TabListener getCallback() {
+ return mCallback;
+ }
+
+ @Override
+ public void setTabListener(ActionBar.TabListener callback) {
+ mCallback = callback;
+ }
+
+ @Override
+ public View getCustomView() {
+ return mCustomView;
+ }
+
+ @Override
+ public void setCustomView(View view) {
+ mCustomView = view;
}
@Override
@@ -572,11 +550,6 @@ public class ActionBarImpl extends ActionBar {
}
@Override
- public void setFragment(Fragment fragment) {
- mFragment = fragment;
- }
-
- @Override
public void setIcon(Drawable icon) {
mIcon = icon;
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 0a1c8ffb17f4..a6a031a2c98c 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -3345,11 +3345,6 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
- public class Pid {
- long mWakeSum;
- long mWakeStart;
- }
-
/**
* Retrieve the statistics object for a particular process, creating
* if needed.
@@ -3364,6 +3359,10 @@ public final class BatteryStatsImpl extends BatteryStats {
return ps;
}
+ public SparseArray<? extends Pid> getPidStats() {
+ return mPids;
+ }
+
public Pid getPidStatsLocked(int pid) {
Pid p = mPids.get(pid);
if (p == null) {
@@ -3588,6 +3587,11 @@ public final class BatteryStatsImpl extends BatteryStats {
}
@Override
+ public long getHistoryBaseTime() {
+ return mHistoryBaseTime;
+ }
+
+ @Override
public int getStartCount() {
return mStartCount;
}
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index b9e4e46b0d6f..6b3d3532e1ca 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -41,6 +41,7 @@ import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
+import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Spinner;
@@ -87,6 +88,7 @@ public class ActionBarView extends ViewGroup {
private TextView mTitleView;
private TextView mSubtitleView;
private Spinner mSpinner;
+ private HorizontalScrollView mTabScrollView;
private LinearLayout mTabLayout;
private View mCustomNavView;
@@ -119,6 +121,8 @@ public class ActionBarView extends ViewGroup {
private OnClickListener mHomeClickListener = null;
+ private OnClickListener mTabClickListener = null;
+
public ActionBarView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -346,8 +350,9 @@ public class ActionBarView extends ViewGroup {
break;
case ActionBar.NAVIGATION_MODE_TABS:
if (mTabLayout != null) {
- removeView(mTabLayout);
+ removeView(mTabScrollView);
mTabLayout = null;
+ mTabScrollView = null;
}
}
@@ -365,8 +370,10 @@ public class ActionBarView extends ViewGroup {
addView(mCustomNavView);
break;
case ActionBar.NAVIGATION_MODE_TABS:
+ mTabScrollView = new HorizontalScrollView(getContext());
mTabLayout = new LinearLayout(getContext());
- addView(mTabLayout);
+ mTabScrollView.addView(mTabLayout);
+ addView(mTabScrollView);
break;
}
mNavigationMode = mode;
@@ -401,20 +408,24 @@ public class ActionBarView extends ViewGroup {
private TabView createTabView(ActionBar.Tab tab) {
final TabView tabView = new TabView(getContext(), tab);
tabView.setFocusable(true);
- tabView.setOnClickListener(new TabClickListener());
+
+ if (mTabClickListener == null) {
+ mTabClickListener = new TabClickListener();
+ }
+ tabView.setOnClickListener(mTabClickListener);
return tabView;
}
public void addTab(ActionBar.Tab tab) {
final boolean isFirst = mTabLayout.getChildCount() == 0;
- final TabView tabView = createTabView(tab);
+ View tabView = createTabView(tab);
mTabLayout.addView(tabView);
if (isFirst) {
tabView.setSelected(true);
}
}
- public void insertTab(ActionBar.Tab tab, int position) {
+ public void addTab(ActionBar.Tab tab, int position) {
final boolean isFirst = mTabLayout.getChildCount() == 0;
final TabView tabView = createTabView(tab);
mTabLayout.addView(tabView, position);
@@ -595,8 +606,8 @@ public class ActionBarView extends ViewGroup {
}
break;
case ActionBar.NAVIGATION_MODE_TABS:
- if (mTabLayout != null) {
- mTabLayout.measure(
+ if (mTabScrollView != null) {
+ mTabScrollView.measure(
MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
}
@@ -663,8 +674,8 @@ public class ActionBarView extends ViewGroup {
}
break;
case ActionBar.NAVIGATION_MODE_TABS:
- if (mTabLayout != null) {
- x += positionChild(mTabLayout, x, y, contentHeight) + mSpacing;
+ if (mTabScrollView != null) {
+ x += positionChild(mTabScrollView, x, y, contentHeight) + mSpacing;
}
}
@@ -703,31 +714,36 @@ public class ActionBarView extends ViewGroup {
super(context);
mTab = tab;
- // TODO Style tabs based on the theme
-
- final Drawable icon = tab.getIcon();
- final CharSequence text = tab.getText();
-
- if (icon != null) {
- ImageView iconView = new ImageView(context);
- iconView.setImageDrawable(icon);
- LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
- LayoutParams.WRAP_CONTENT);
- lp.gravity = Gravity.CENTER_VERTICAL;
- iconView.setLayoutParams(lp);
- addView(iconView);
- }
+ final View custom = tab.getCustomView();
+ if (custom != null) {
+ addView(custom);
+ } else {
+ // TODO Style tabs based on the theme
+
+ final Drawable icon = tab.getIcon();
+ final CharSequence text = tab.getText();
+
+ if (icon != null) {
+ ImageView iconView = new ImageView(context);
+ iconView.setImageDrawable(icon);
+ LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT);
+ lp.gravity = Gravity.CENTER_VERTICAL;
+ iconView.setLayoutParams(lp);
+ addView(iconView);
+ }
- if (text != null) {
- TextView textView = new TextView(context);
- textView.setText(text);
- textView.setSingleLine();
- textView.setEllipsize(TruncateAt.END);
- LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
- LayoutParams.WRAP_CONTENT);
- lp.gravity = Gravity.CENTER_VERTICAL;
- textView.setLayoutParams(lp);
- addView(textView);
+ if (text != null) {
+ TextView textView = new TextView(context);
+ textView.setText(text);
+ textView.setSingleLine();
+ textView.setEllipsize(TruncateAt.END);
+ LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT);
+ lp.gravity = Gravity.CENTER_VERTICAL;
+ textView.setLayoutParams(lp);
+ addView(textView);
+ }
}
setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 0932473aa859..2517a8a4adaf 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -127,12 +127,13 @@ AInputQueue::~AInputQueue() {
close(mDispatchKeyWrite);
}
-void AInputQueue::attachLooper(ALooper* looper, ALooper_callbackFunc* callback, void* data) {
+void AInputQueue::attachLooper(ALooper* looper, int ident,
+ ALooper_callbackFunc* callback, void* data) {
mPollLoop = static_cast<android::PollLoop*>(looper);
mPollLoop->setLooperCallback(mConsumer.getChannel()->getReceivePipeFd(),
- POLLIN, callback, data);
+ ident, POLLIN, callback, data);
mPollLoop->setLooperCallback(mDispatchKeyRead,
- POLLIN, callback, data);
+ ident, POLLIN, callback, data);
}
void AInputQueue::detachLooper() {
diff --git a/core/jni/android_database_SQLiteDatabase.cpp b/core/jni/android_database_SQLiteDatabase.cpp
index 4b3f1c0b40a9..36e90899765f 100644
--- a/core/jni/android_database_SQLiteDatabase.cpp
+++ b/core/jni/android_database_SQLiteDatabase.cpp
@@ -593,6 +593,9 @@ void throw_sqlite3_exception(JNIEnv* env, int errcode,
case SQLITE_MISMATCH:
exceptionClass = "android/database/sqlite/SQLiteDatatypeMismatchException";
break;
+ case SQLITE_UNCLOSED:
+ exceptionClass = "android/database/sqlite/SQLiteUnfinalizedObjectsException";
+ break;
default:
exceptionClass = "android/database/sqlite/SQLiteException";
break;
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 7c9927117fe3..7dfb71693d9c 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -261,8 +261,7 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
continue;
}
- if (set_sched_policy(t_pid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
- SP_BACKGROUND : SP_FOREGROUND)) {
+ if (androidSetThreadSchedulingGroup(t_pid, grp) != NO_ERROR) {
signalExceptionForGroupError(env, clazz, errno);
break;
}
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 1951d141c6ba..85940273f3d7 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1265,7 +1265,13 @@
<public type="drawable" name="presence_audio_online" id="0x010800b1" />
<public-padding type="drawable" name="kraken_resource_pad" end="0x01080100" />
+ <public type="style" name="TextAppearance.StatusBar.Title" id="0x01030065" />
+ <public type="style" name="TextAppearance.StatusBar.Icon" id="0x01030066" />
+ <public type="style" name="TextAppearance.StatusBar.EventContent" id="0x01030067" />
+ <public type="style" name="TextAppearance.StatusBar.EventContent.Title" id="0x01030068" />
+
<public-padding type="style" name="kraken_resource_pad" end="0x01030090" />
+
<public-padding type="string" name="kraken_resource_pad" end="0x01040020" />
<public-padding type="integer" name="kraken_resource_pad" end="0x010e0010" />
<public-padding type="layout" name="kraken_resource_pad" end="0x01090020" />
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteUnfinalizedExceptionTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteUnfinalizedExceptionTest.java
new file mode 100644
index 000000000000..cd2005dd16ff
--- /dev/null
+++ b/core/tests/coretests/src/android/database/sqlite/SQLiteUnfinalizedExceptionTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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 android.database.sqlite;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabaseTest.ClassToTestSqlCompilationAndCaching;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.io.File;
+
+public class SQLiteUnfinalizedExceptionTest extends AndroidTestCase {
+ private SQLiteDatabase mDatabase;
+ private File mDatabaseFile;
+ private static final String TABLE_NAME = "testCursor";
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ File dbDir = getContext().getDir(this.getClass().getName(), Context.MODE_PRIVATE);
+ mDatabaseFile = new File(dbDir, "UnfinalizedExceptionTest.db");
+ if (mDatabaseFile.exists()) {
+ mDatabaseFile.delete();
+ }
+ mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
+ assertNotNull(mDatabase);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mDatabase.close();
+ mDatabaseFile.delete();
+ super.tearDown();
+ }
+
+ @SmallTest
+ public void testUnfinalizedExceptionNotExcpected() {
+ mDatabase.execSQL("CREATE TABLE " + TABLE_NAME + " (i int, j int);");
+ // the above statement should be in SQLiteDatabase.mPrograms
+ // and should automatically be finalized when database is closed
+ mDatabase.lock();
+ try {
+ mDatabase.closeDatabase();
+ } finally {
+ mDatabase.unlock();
+ }
+ }
+
+ @SmallTest
+ public void testUnfinalizedException() {
+ mDatabase.execSQL("CREATE TABLE " + TABLE_NAME + " (i int, j int);");
+ mDatabase.lock();
+ mDatabase.closePendingStatements(); // clears the above from finalizer queue in mdatabase
+ mDatabase.unlock();
+ ClassToTestSqlCompilationAndCaching.create(mDatabase, "select * from " + TABLE_NAME);
+ // since the above is NOT closed, closing database should fail
+ mDatabase.lock();
+ try {
+ mDatabase.closeDatabase();
+ fail("exception expected");
+ } catch (SQLiteUnfinalizedObjectsException e) {
+ // expected
+ } finally {
+ mDatabase.unlock();
+ }
+ }
+}
diff --git a/docs/html/guide/practices/design/performance.jd b/docs/html/guide/practices/design/performance.jd
index f22d2d31a80c..56872a72b783 100644
--- a/docs/html/guide/practices/design/performance.jd
+++ b/docs/html/guide/practices/design/performance.jd
@@ -42,188 +42,39 @@ outside the scope of this document.</p>
<h2 id="optimize_judiciously">Optimize Judiciously</h2>
-<p>As you get started thinking about how to design your application, and as
-you write it, consider
-the cautionary points about optimization that Josh Bloch makes in his book
-<em>Effective Java</em>. Here's "Item 47: Optimize Judiciously", excerpted from
-the latest edition of the book with permission. Although Josh didn't have
-Android application development in mind when writing this section &mdash; for
-example, the <code style="color:black">java.awt.Component</code> class
-referenced is not available in Android, and Android uses the
-Dalvik VM, rather than a standard JVM &mdash; his points are still valid. </p>
-
-<blockquote>
-
-<p>There are three aphorisms concerning optimization that everyone should know.
-They are perhaps beginning to suffer from overexposure, but in case you aren't
-yet familiar with them, here they are:</p>
-
-<div style="padding-left:3em;padding-right:4em;">
-
-<p style="margin-bottom:.5em;">More computing sins are committed in the name of
-efficiency (without necessarily achieving it) than for any other single
-reason&mdash;including blind stupidity.</p>
-<p>&mdash;William A. Wulf <span style="font-size:80%;"><sup>1</sup></span></p>
-
-<p style="margin-bottom:.5em;">We should forget about small efficiencies, say
-about 97% of the time: premature optimization is the root of all evil. </p>
-<p>&mdash;Donald E. Knuth <span style="font-size:80%;"><sup>2</sup></span></p>
-
-
-<p style="margin-bottom:.5em;">We follow two rules in the matter of optimization:</p>
-<ul style="margin-bottom:0">
-<li>Rule 1. Don't do it.</li>
-<li>Rule 2 (for experts only). Don't do it yet &mdash; that is, not until you have a
-perfectly clear and unoptimized solution. </li>
-</ul>
-<p>&mdash;M. A. Jackson <span style="font-size:80%;"><sup>3</sup></span></p>
-</div>
-
-<p>All of these aphorisms predate the Java programming language by two decades.
-They tell a deep truth about optimization: it is easy to do more harm than good,
-especially if you optimize prematurely. In the process, you may produce software
-that is neither fast nor correct and cannot easily be fixed.</p>
-
-<p>Don't sacrifice sound architectural principles for performance.
-<strong>Strive to write good programs rather than fast ones.</strong> If a good
-program is not fast enough, its architecture will allow it to be optimized. Good
-programs embody the principle of <em>information hiding</em>: where possible,
-they localize design decisions within individual modules, so individual
-decisions can be changed without affecting the remainder of the system (Item
-13).</p>
-
-<p>This does <em>not</em> mean that you can ignore performance concerns until
-your program is complete. Implementation problems can be fixed by later
-optimization, but pervasive architectural flaws that limit performance can be
-impossible to fix without rewriting the system. Changing a fundamental facet of
-your design after the fact can result in an ill-structured system that is
-difficult to maintain and evolve. Therefore you must think about performance
-during the design process.</p>
-
-<p><strong>Strive to avoid design decisions that limit performance.</strong> The
-components of a design that are most difficult to change after the fact are
-those specifying interactions between modules and with the outside world. Chief
-among these design components are APIs, wire-level protocols, and persistent
-data formats. Not only are these design components difficult or impossible to
-change after the fact, but all of them can place significant limitations on the
-performance that a system can ever achieve.</p>
-
-<p><strong>Consider the performance consequences of your API design
-decisions.</strong> Making a public type mutable may require a lot of needless
-defensive copying (Item 39). Similarly, using inheritance in a public class
-where composition would have been appropriate ties the class forever to its
-superclass, which can place artificial limits on the performance of the subclass
-(Item 16). As a final example, using an implementation type rather than an
-interface in an API ties you to a specific implementation, even though faster
-implementations may be written in the future (Item 52).</p>
-
-<p>The effects of API design on performance are very real. Consider the <code
-style="color:black">getSize</code> method in the <code
-style="color:black">java.awt.Component</code> class. The decision that this
-performance-critical method was to return a <code
-style="color:black">Dimension</code> instance, coupled with the decision that
-<code style="color:black">Dimension</code> instances are mutable, forces any
-implementation of this method to allocate a new <code
-style="color:black">Dimension</code> instance on every invocation. Even though
-allocating small objects is inexpensive on a modern VM, allocating millions of
-objects needlessly can do real harm to performance.</p>
-
-<p>In this case, several alternatives existed. Ideally, <code
-style="color:black">Dimension</code> should have been immutable (Item 15);
-alternatively, the <code style="color:black">getSize</code> method could have
-been replaced by two methods returning the individual primitive components of a
-<code style="color:black">Dimension</code> object. In fact, two such methods
-were added to the Component API in the 1.2 release for performance reasons.
-Preexisting client code, however, still uses the <code
-style="color:black">getSize</code> method and still suffers the performance
-consequences of the original API design decisions.</p>
-
-<p>Luckily, it is generally the case that good API design is consistent with
-good performance. <strong>It is a very bad idea to warp an API to achieve good
-performance.</strong> The performance issue that caused you to warp the API may
-go away in a future release of the platform or other underlying software, but
-the warped API and the support headaches that come with it will be with you for
-life.</p>
-
-<p>Once you've carefully designed your program and produced a clear, concise,
-and well-structured implementation, <em>then</em> it may be time to consider
-optimization, assuming you're not already satisfied with the performance of the
-program.</p>
-
-<p>Recall that Jackson's two rules of optimization were "Don't do it," and "(for
-experts only). Don't do it yet." He could have added one more: <strong>measure
-performance before and after each attempted optimization.</strong> You may be
-surprised by what you find. Often, attempted optimizations have no measurable
-effect on performance; sometimes, they make it worse. The main reason is that
-it's difficult to guess where your program is spending its time. The part of the
-program that you think is slow may not be at fault, in which case you'd be
-wasting your time trying to optimize it. Common wisdom says that programs spend
-80 percent of their time in 20 percent of their code.</p>
-
-<p>Profiling tools can help you decide where to focus your optimization efforts.
-Such tools give you runtime information, such as roughly how much time each
-method is consuming and how many times it is invoked. In addition to focusing
-your tuning efforts, this can alert you to the need for algorithmic changes. If
-a quadratic (or worse) algorithm lurks inside your program, no amount of tuning
-will fix the problem. You must replace the algorithm with one that is more
-efficient. The more code in the system, the more important it is to use a
-profiler. It's like looking for a needle in a haystack: the bigger the haystack,
-the more useful it is to have a metal detector. The JDK comes with a simple
-profiler and modern IDEs provide more sophisticated profiling tools.</p>
-
-<p>The need to measure the effects of attempted optimization is even greater on
-the Java platform than on more traditional platforms, because the Java
-programming language does not have a strong <em>performance model</em>. The
-relative costs of the various primitive operations are not well defined. The
-"semantic gap" between what the programmer writes and what the CPU executes is
-far greater than in traditional statically compiled languages, which makes it
-very difficult to reliably predict the performance consequences of any
-optimization. There are plenty of performance myths floating around that turn
-out to be half-truths or outright lies.</p>
-
-<p>Not only is Java's performance model ill-defined, but it varies from JVM
-implementation to JVM implementation, from release to release, and from
-processor to processor. If you will be running your program on multiple JVM
-implementations or multiple hardware platforms, it is important that you measure
-the effects of your optimization on each. Occasionally you may be forced to make
-trade-offs between performance on different JVM implementations or hardware
-platforms.</p>
-
-<p>To summarize, do not strive to write fast programs &mdash; strive to write
-good ones; speed will follow. Do think about performance issues while you're
-designing systems and especially while you're designing APIs, wire-level
-protocols, and persistent data formats. When you've finished building the
-system, measure its performance. If it's fast enough, you're done. If not,
-locate the source of the problems with the aid of a profiler, and go to work
-optimizing the relevant parts of the system. The first step is to examine your
-choice of algorithms: no amount of low-level optimization can make up for a poor
-choice of algorithm. Repeat this process as necessary, measuring the performance
-after every change, until you're satisfied.</p>
-
-<p>&mdash;Excerpted from Josh Bloch's <em>Effective Java</em>, Second Ed.
-(Addison-Wesley, 2008).</em></p>
-
-<p style="font-size:80%;margin-bottom:0;"><sup>1</sup> Wulf, W. A Case Against
-the GOTO. <em>Proceedings of the 25th ACM National
-Conference</em> 2 (1972): 791–797.</p>
-<p style="font-size:80%;margin-bottom:0;"><sup>2</sup> Knuth, Donald. Structured
-Programming with go to Statements. <em>Computing
-Surveys 6</em> (1974): 261–301.</p>
-<p style="font-size:80%"><sup>3</sup> Jackson, M. A. <em>Principles of Program
-Design</em>, Academic Press, London, 1975.
-ISBN: 0123790506.</p>
-
-</blockquote>
-
-<p>One of the trickiest problems you'll face when micro-optimizing Android
-apps is that the "if you will be running your program on ... multiple hardware
-platforms" clause above is always true. And it's not even generally the case
-that you can say "device X is a factor F faster/slower than device Y".
-This is especially true if one of the devices is the emulator, or one of the
-devices has a JIT. If you want to know how your app performs on a given device,
-you need to test it on that device. Drawing conclusions from the emulator is
-particularly dangerous, as is attempting to compare JIT versus non-JIT
-performance: the performance <em>profiles</em> can differ wildly.</p>
+<p>This document is about Android-specific micro-optimization, so it assumes
+that you've already used profiling to work out exactly what code needs to be
+optimized, and that you already have a way to measure the effect (good or bad)
+of any changes you make. You only have so much engineering time to invest, so
+it's important to know you're spending it wisely.
+
+<p>(See <a href="#closing_notes">Closing Notes</a> for more on profiling and
+writing effective benchmarks.)
+
+<p>This document also assumes that you made the best decisions about data
+structures and algorithms, and that you've also considered the future
+performance consequences of your API decisions. Using the right data
+structures and algorithms will make more difference than any of the advice
+here, and considering the performance consequences of your API decisions will
+make it easier to switch to better implementations later (this is more
+important for library code than for application code).
+
+<p>(If you need that kind of advice, see Josh Bloch's <em>Effective Java</em>,
+item 47.)</p>
+
+<p>One of the trickiest problems you'll face when micro-optimizing an Android
+app is that your app is pretty much guaranteed to be running on multiple
+hardware platforms. Different versions of the VM running on different
+processors running at different speeds. It's not even generally the case
+that you can simply say "device X is a factor F faster/slower than device Y",
+and scale your results from one device to others. In particular, measurement
+on the emulator tells you very little about performance on any device. There
+are also huge differences between devices with and without a JIT: the "best"
+code for a device with a JIT is not always the best code for a device
+without.</p>
+
+<p>If you want to know how your app performs on a given device, you need to
+test on that device.</p>
<a name="object_creation"></a>
<h2>Avoid Creating Objects</h2>
@@ -566,3 +417,11 @@ of its way to do the hard work for you, and even detect some cases where you're
not measuring what you think you're measuring (because, say, the VM has
managed to optimize all your code away). We highly recommend you use Caliper
to run your own microbenchmarks.</p>
+
+<p>You may also find
+<a href="{@docRoot}guide/developing/tools/traceview.html">Traceview</a> useful
+for profiling, but it's important to realize that it currently disables the JIT,
+which may cause it to misattribute time to code that the JIT may be able to win
+back. It's especially important after making changes suggested by Traceview
+data to ensure that the resulting code actually runs faster when run without
+Traceview.
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index ed09f89ac281..05b2d6019f32 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -27,6 +27,7 @@ public class Element extends BaseObj {
int mSize;
Element[] mElements;
String[] mElementNames;
+ int[] mArraySizes;
DataType mType;
DataKind mKind;
@@ -313,11 +314,12 @@ public class Element extends BaseObj {
return rs.mElement_MATRIX_2X2;
}
- Element(int id, RenderScript rs, Element[] e, String[] n) {
+ Element(int id, RenderScript rs, Element[] e, String[] n, int[] as) {
super(id, rs);
mSize = 0;
mElements = e;
mElementNames = n;
+ mArraySizes = as;
for (int ct = 0; ct < mElements.length; ct++ ) {
mSize += mElements[ct].mSize;
}
@@ -441,6 +443,7 @@ public class Element extends BaseObj {
RenderScript mRS;
Element[] mElements;
String[] mElementNames;
+ int[] mArraySizes;
int mCount;
public Builder(RenderScript rs) {
@@ -448,35 +451,49 @@ public class Element extends BaseObj {
mCount = 0;
mElements = new Element[8];
mElementNames = new String[8];
+ mArraySizes = new int[8];
}
- public void add(Element element, String name) {
+ public void add(Element element, String name, int arraySize) {
+ if (arraySize < 1) {
+ throw new IllegalArgumentException("Array size cannot be less than 1.");
+ }
if(mCount == mElements.length) {
Element[] e = new Element[mCount + 8];
String[] s = new String[mCount + 8];
+ int[] as = new int[mCount + 8];
System.arraycopy(mElements, 0, e, 0, mCount);
System.arraycopy(mElementNames, 0, s, 0, mCount);
+ System.arraycopy(mArraySizes, 0, as, 0, mCount);
mElements = e;
mElementNames = s;
+ mArraySizes = as;
}
mElements[mCount] = element;
mElementNames[mCount] = name;
+ mArraySizes[mCount] = arraySize;
mCount++;
}
+ public void add(Element element, String name) {
+ add(element, name, 1);
+ }
+
public Element create() {
mRS.validate();
Element[] ein = new Element[mCount];
String[] sin = new String[mCount];
+ int[] asin = new int[mCount];
java.lang.System.arraycopy(mElements, 0, ein, 0, mCount);
java.lang.System.arraycopy(mElementNames, 0, sin, 0, mCount);
+ java.lang.System.arraycopy(mArraySizes, 0, asin, 0, mCount);
int[] ids = new int[ein.length];
for (int ct = 0; ct < ein.length; ct++ ) {
ids[ct] = ein[ct].mID;
}
- int id = mRS.nElementCreate2(ids, sin);
- return new Element(id, mRS, ein, sin);
+ int id = mRS.nElementCreate2(ids, sin, asin);
+ return new Element(id, mRS, ein, sin, asin);
}
}
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 62d70a7b02e3..1f3e159122ca 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -152,9 +152,9 @@ public class RenderScript {
synchronized int nElementCreate(int type, int kind, boolean norm, int vecSize) {
return rsnElementCreate(mContext, type, kind, norm, vecSize);
}
- native int rsnElementCreate2(int con, int[] elements, String[] names);
- synchronized int nElementCreate2(int[] elements, String[] names) {
- return rsnElementCreate2(mContext, elements, names);
+ native int rsnElementCreate2(int con, int[] elements, String[] names, int[] arraySizes);
+ synchronized int nElementCreate2(int[] elements, String[] names, int[] arraySizes) {
+ return rsnElementCreate2(mContext, elements, names, arraySizes);
}
native void rsnElementGetNativeData(int con, int id, int[] elementData);
synchronized void nElementGetNativeData(int id, int[] elementData) {
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index c8e6656f5d4d..f07dbfd886e2 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -253,12 +253,13 @@ nElementCreate(JNIEnv *_env, jobject _this, RsContext con, jint type, jint kind,
}
static jint
-nElementCreate2(JNIEnv *_env, jobject _this, RsContext con, jintArray _ids, jobjectArray _names)
+nElementCreate2(JNIEnv *_env, jobject _this, RsContext con, jintArray _ids, jobjectArray _names, jintArray _arraySizes)
{
int fieldCount = _env->GetArrayLength(_ids);
LOG_API("nElementCreate2, con(%p)", con);
jint *ids = _env->GetIntArrayElements(_ids, NULL);
+ jint *arraySizes = _env->GetIntArrayElements(_arraySizes, NULL);
const char ** nameArray = (const char **)calloc(fieldCount, sizeof(char *));
size_t* sizeArray = (size_t*)calloc(fieldCount, sizeof(size_t));
@@ -267,12 +268,13 @@ nElementCreate2(JNIEnv *_env, jobject _this, RsContext con, jintArray _ids, jobj
nameArray[ct] = _env->GetStringUTFChars(s, NULL);
sizeArray[ct] = _env->GetStringUTFLength(s);
}
- jint id = (jint)rsElementCreate2(con, fieldCount, (RsElement *)ids, nameArray, sizeArray);
+ jint id = (jint)rsElementCreate2(con, fieldCount, (RsElement *)ids, nameArray, sizeArray, (const uint32_t *)arraySizes);
for (int ct=0; ct < fieldCount; ct++) {
jstring s = (jstring)_env->GetObjectArrayElement(_names, ct);
_env->ReleaseStringUTFChars(s, nameArray[ct]);
}
_env->ReleaseIntArrayElements(_ids, ids, JNI_ABORT);
+ _env->ReleaseIntArrayElements(_arraySizes, arraySizes, JNI_ABORT);
free(nameArray);
free(sizeArray);
return (jint)id;
@@ -1230,7 +1232,7 @@ static JNINativeMethod methods[] = {
{"rsnFontCreateFromFile", "(ILjava/lang/String;II)I", (void*)nFontCreateFromFile },
{"rsnElementCreate", "(IIIZI)I", (void*)nElementCreate },
-{"rsnElementCreate2", "(I[I[Ljava/lang/String;)I", (void*)nElementCreate2 },
+{"rsnElementCreate2", "(I[I[Ljava/lang/String;[I)I", (void*)nElementCreate2 },
{"rsnElementGetNativeData", "(II[I)V", (void*)nElementGetNativeData },
{"rsnElementGetSubElements", "(II[I[Ljava/lang/String;)V", (void*)nElementGetSubElements },
diff --git a/include/android_runtime/android_app_NativeActivity.h b/include/android_runtime/android_app_NativeActivity.h
index c388ba80a3bc..fdceb84836a4 100644
--- a/include/android_runtime/android_app_NativeActivity.h
+++ b/include/android_runtime/android_app_NativeActivity.h
@@ -69,7 +69,7 @@ public:
/* Destroys the consumer and releases its input channel. */
~AInputQueue();
- void attachLooper(ALooper* looper, ALooper_callbackFunc* callback, void* data);
+ void attachLooper(ALooper* looper, int ident, ALooper_callbackFunc* callback, void* data);
void detachLooper();
diff --git a/include/utils/PollLoop.h b/include/utils/PollLoop.h
index 81230e84dd98..bc616ebc7d53 100644
--- a/include/utils/PollLoop.h
+++ b/include/utils/PollLoop.h
@@ -111,12 +111,18 @@ public:
* This method can be called on any thread.
* This method may block briefly if it needs to wake the poll loop.
*/
- void setCallback(int fd, int events, Callback callback, void* data = NULL);
+ void setCallback(int fd, int ident, int events, Callback callback, void* data = NULL);
/**
+ * Convenience for above setCallback when ident is not used. In this case
+ * the ident is set to POLL_CALLBACK.
+ */
+ void setCallback(int fd, int events, Callback callback, void* data = NULL);
+
+ /**
* Like setCallback(), but for the NDK callback function.
*/
- void setLooperCallback(int fd, int events, ALooper_callbackFunc* callback,
+ void setLooperCallback(int fd, int ident, int events, ALooper_callbackFunc* callback,
void* data);
/**
@@ -153,11 +159,13 @@ private:
struct RequestedCallback {
Callback callback;
ALooper_callbackFunc* looperCallback;
+ int ident;
void* data;
};
struct PendingCallback {
int fd;
+ int ident;
int events;
Callback callback;
ALooper_callbackFunc* looperCallback;
@@ -185,7 +193,7 @@ private:
void openWakePipe();
void closeWakePipe();
- void setCallbackCommon(int fd, int events, Callback callback,
+ void setCallbackCommon(int fd, int ident, int events, Callback callback,
ALooper_callbackFunc* looperCallback, void* data);
ssize_t getRequestIndexLocked(int fd);
void wakeAndLock();
diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp
index 3396f25e714a..7eb6da5a6e9b 100644
--- a/libs/gui/SensorEventQueue.cpp
+++ b/libs/gui/SensorEventQueue.cpp
@@ -86,7 +86,7 @@ sp<PollLoop> SensorEventQueue::getPollLoop() const
Mutex::Autolock _l(mLock);
if (mPollLoop == 0) {
mPollLoop = new PollLoop(true);
- mPollLoop->setCallback(getFd(), POLLIN, NULL, NULL);
+ mPollLoop->setCallback(getFd(), getFd(), POLLIN, NULL, NULL);
}
return mPollLoop;
}
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index 4a4d8370328b..75b8d3349ebf 100644
--- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -42,8 +42,8 @@ public class ImageProcessingActivity extends Activity
private Bitmap mBitmapOut;
private Bitmap mBitmapScratch;
private ScriptC_Threshold mScript;
- private ScriptC_Vertical_blur mScriptVBlur;
- private ScriptC_Horizontal_blur mScriptHBlur;
+ private ScriptC_VerticalBlur mScriptVBlur;
+ private ScriptC_HorizontalBlur mScriptHBlur;
private int mRadius = 0;
private SeekBar mRadiusSeekBar;
@@ -380,8 +380,8 @@ public class ImageProcessingActivity extends Activity
mScratchPixelsAllocation1 = Allocation.createTyped(mRS, tb.create());
mScratchPixelsAllocation2 = Allocation.createTyped(mRS, tb.create());
- mScriptVBlur = new ScriptC_Vertical_blur(mRS, getResources(), R.raw.vertical_blur, false);
- mScriptHBlur = new ScriptC_Horizontal_blur(mRS, getResources(), R.raw.horizontal_blur, false);
+ mScriptVBlur = new ScriptC_VerticalBlur(mRS, getResources(), R.raw.verticalblur, false);
+ mScriptHBlur = new ScriptC_HorizontalBlur(mRS, getResources(), R.raw.horizontalblur, false);
mScript = new ScriptC_Threshold(mRS, getResources(), R.raw.threshold, false);
mScript.set_width(mBitmapIn.getWidth());
diff --git a/libs/rs/java/ModelViewer/res/raw/robot.a3d b/libs/rs/java/ModelViewer/res/raw/robot.a3d
index 2d7d32b6fb02..f48895cd8451 100644
--- a/libs/rs/java/ModelViewer/res/raw/robot.a3d
+++ b/libs/rs/java/ModelViewer/res/raw/robot.a3d
Binary files differ
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
index 9672a6a604bb..85c1d42de4da 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
@@ -105,7 +105,7 @@ public class SceneGraphRS {
bs.setMin(Sampler.Value.LINEAR);
bs.setMag(Sampler.Value.LINEAR);
bs.setWrapS(Sampler.Value.CLAMP);
- bs.setWrapT(Sampler.Value.WRAP);
+ bs.setWrapT(Sampler.Value.CLAMP);
mSampler = bs.create();
ProgramFragment.Builder b = new ProgramFragment.Builder(mRS);
@@ -123,7 +123,6 @@ public class SceneGraphRS {
mPVA = new ProgramVertex.MatrixAllocation(mRS);
mPVBackground.bindAllocation(mPVA);
- mPVA.setupProjectionNormalized(mWidth, mHeight);
mScript.set_gPVBackground(mPVBackground);
}
@@ -159,14 +158,14 @@ public class SceneGraphRS {
mGroup1.addChild(mRobot1);
mGroup1.addChild(mRobot2);
- mGroup1.setTransform(0, new Float4(0.0f, 0.0f, 5.0f, 0.0f), TransformType.TRANSLATE);
+ mGroup1.setTransform(0, new Float4(0.0f, 0.0f, -15.0f, 0.0f), TransformType.TRANSLATE);
mGroup1.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, 15.0f), TransformType.ROTATE);
- mRobot1.setTransform(0, new Float4(-2.0f, -0.5f, 0.0f, 0.0f), TransformType.TRANSLATE);
+ mRobot1.setTransform(0, new Float4(-3.0f, -0.5f, 0.0f, 0.0f), TransformType.TRANSLATE);
mRobot1.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, 20.0f), TransformType.ROTATE);
mRobot1.setTransform(2, new Float4(0.2f, 0.2f, 0.2f, 0.0f), TransformType.SCALE);
- mRobot2.setTransform(0, new Float4(2.0f, 0.0f, 0.0f, 0.0f), TransformType.TRANSLATE);
+ mRobot2.setTransform(0, new Float4(3.0f, 0.0f, 0.0f, 0.0f), TransformType.TRANSLATE);
mRobot2.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, -20.0f), TransformType.ROTATE);
mRobot2.setTransform(2, new Float4(0.3f, 0.3f, 0.3f, 0.0f), TransformType.SCALE);
}
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
index b8b0119e779c..d8d1a6e01039 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
@@ -79,7 +79,7 @@ public class SimpleModelRS {
mRotation += 360;
}
- mScript.set_gRotate(-(float)mRotation);
+ mScript.set_gRotate((float)mRotation);
mLastX = x;
mLastY = y;
@@ -101,7 +101,7 @@ public class SimpleModelRS {
bs.setMin(Sampler.Value.LINEAR);
bs.setMag(Sampler.Value.LINEAR);
bs.setWrapS(Sampler.Value.CLAMP);
- bs.setWrapT(Sampler.Value.WRAP);
+ bs.setWrapT(Sampler.Value.CLAMP);
mSampler = bs.create();
ProgramFragment.Builder b = new ProgramFragment.Builder(mRS);
@@ -119,7 +119,6 @@ public class SimpleModelRS {
mPVA = new ProgramVertex.MatrixAllocation(mRS);
mPVBackground.bindAllocation(mPVA);
- mPVA.setupProjectionNormalized(mWidth, mHeight);
mScript.set_gPVBackground(mPVBackground);
}
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/scenegraph.rs b/libs/rs/java/ModelViewer/src/com/android/modelviewer/scenegraph.rs
index c7944386e6b9..ce6bb1e02d7c 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/scenegraph.rs
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/scenegraph.rs
@@ -71,6 +71,10 @@ int root(int launchID) {
rsgClearDepth(1.0f);
rsgBindProgramVertex(gPVBackground);
+ rs_matrix4x4 proj;
+ float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+ rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
+ rsgProgramVertexLoadProjectionMatrix(&proj);
rsgBindProgramFragment(gPFBackground);
rsgBindProgramStore(gPFSBackground);
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs b/libs/rs/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs
index adb609c1eb0c..43be2667fe65 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs
@@ -46,6 +46,10 @@ int root(int launchID) {
rsgClearDepth(1.0f);
rsgBindProgramVertex(gPVBackground);
+ rs_matrix4x4 proj;
+ float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+ rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
+ rsgProgramVertexLoadProjectionMatrix(&proj);
rsgBindProgramFragment(gPFBackground);
rsgBindProgramStore(gPFSBackground);
@@ -54,9 +58,9 @@ int root(int launchID) {
rs_matrix4x4 matrix;
rsMatrixLoadIdentity(&matrix);
// Position our model on the screen
- rsMatrixTranslate(&matrix, 0.0f, -0.3f, 1.2f);
+ rsMatrixTranslate(&matrix, 0.0f, -0.3f, -10.0f);
rsMatrixScale(&matrix, 0.2f, 0.2f, 0.2f);
- rsMatrixRotate(&matrix, -25.0f, 1.0f, 0.0f, 0.0f);
+ rsMatrixRotate(&matrix, 25.0f, 1.0f, 0.0f, 0.0f);
rsMatrixRotate(&matrix, gRotate, 0.0f, 1.0f, 0.0f);
rsgProgramVertexLoadModelMatrix(&matrix);
diff --git a/libs/rs/java/Samples/res/raw/torus.a3d b/libs/rs/java/Samples/res/raw/torus.a3d
index d09bc136ace9..0322b01be8a8 100644
--- a/libs/rs/java/Samples/res/raw/torus.a3d
+++ b/libs/rs/java/Samples/res/raw/torus.a3d
Binary files differ
diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
index c1a16dd27bb9..eb1e48b68be5 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
@@ -30,10 +30,10 @@ public class RSTestCore {
private Resources mRes;
private RenderScriptGL mRS;
- private ScriptC_Test_root mRootScript;
+ private ScriptC_TestRoot mRootScript;
private boolean fp_mad() {
- ScriptC_Fp_mad s = new ScriptC_Fp_mad(mRS, mRes, R.raw.fp_mad, true);
+ ScriptC_FpMad s = new ScriptC_FpMad(mRS, mRes, R.raw.fpmad, true);
s.invoke_doTest(0, 0);
return true;
}
@@ -43,7 +43,7 @@ public class RSTestCore {
mRS = rs;
mRes = res;
- mRootScript = new ScriptC_Test_root(mRS, mRes, R.raw.test_root, true);
+ mRootScript = new ScriptC_TestRoot(mRS, mRes, R.raw.testroot, true);
fp_mad();
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index ad162bbbf535..c7fb2afdb51b 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -80,6 +80,7 @@ ElementCreate2 {
param const RsElement * elements
param const char ** names
param const size_t * nameLengths
+ param const uint32_t * arraySize
ret RsElement
}
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp
index 2602dd4d1ae8..0b7bb27a1f57 100644
--- a/libs/rs/rsElement.cpp
+++ b/libs/rs/rsElement.cpp
@@ -65,7 +65,7 @@ size_t Element::getSizeBits() const
size_t total = 0;
for (size_t ct=0; ct < mFieldCount; ct++) {
- total += mFields[ct].e->mBits;
+ total += mFields[ct].e->mBits * mFields[ct].arraySize;;
}
return total;
}
@@ -95,6 +95,7 @@ void Element::serialize(OStream *stream) const
stream->addU32(mFieldCount);
for(uint32_t ct = 0; ct < mFieldCount; ct++) {
stream->addString(&mFields[ct].name);
+ stream->addU32(mFields[ct].arraySize);
mFields[ct].e->serialize(stream);
}
}
@@ -122,6 +123,7 @@ Element *Element::createFromStream(Context *rsc, IStream *stream)
elem->mFields = new ElementField_t [elem->mFieldCount];
for(uint32_t ct = 0; ct < elem->mFieldCount; ct ++) {
stream->loadString(&elem->mFields[ct].name);
+ elem->mFields[ct].arraySize = stream->loadU32();
Element *fieldElem = Element::createFromStream(rsc, stream);
elem->mFields[ct].e.set(fieldElem);
elem->mFields[ct].offsetBits = offset;
@@ -155,7 +157,8 @@ Element *Element::createFromStream(Context *rsc, IStream *stream)
for (uint32_t i=0; i < elem->mFieldCount; i++) {
if ((ee->mFields[i].e.get() != elem->mFields[i].e.get()) ||
(ee->mFields[i].name.length() != elem->mFields[i].name.length()) ||
- (ee->mFields[i].name != elem->mFields[i].name)) {
+ (ee->mFields[i].name != elem->mFields[i].name) ||
+ (ee->mFields[i].arraySize != elem->mFields[i].arraySize)) {
match = false;
break;
}
@@ -200,7 +203,7 @@ const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
}
const Element * Element::create(Context *rsc, size_t count, const Element **ein,
- const char **nin, const size_t * lengths)
+ const char **nin, const size_t * lengths, const uint32_t *asin)
{
// Look for an existing match.
for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
@@ -210,7 +213,8 @@ const Element * Element::create(Context *rsc, size_t count, const Element **ein,
for (uint32_t i=0; i < count; i++) {
if ((ee->mFields[i].e.get() != ein[i]) ||
(ee->mFields[i].name.length() != lengths[i]) ||
- (ee->mFields[i].name != nin[i])) {
+ (ee->mFields[i].name != nin[i]) ||
+ (ee->mFields[i].arraySize != asin[i])) {
match = false;
break;
}
@@ -230,6 +234,7 @@ const Element * Element::create(Context *rsc, size_t count, const Element **ein,
e->mFields[ct].e.set(ein[ct]);
e->mFields[ct].name.setTo(nin[ct], lengths[ct]);
e->mFields[ct].offsetBits = bits;
+ e->mFields[ct].arraySize = asin[ct];
bits += ein[ct]->getSizeBits();
if (ein[ct]->mHasReference) {
@@ -274,7 +279,11 @@ void Element::incRefs(const void *ptr) const
const uint8_t *p = static_cast<const uint8_t *>(ptr);
for (uint32_t i=0; i < mFieldCount; i++) {
if (mFields[i].e->mHasReference) {
- mFields[i].e->incRefs(&p[mFields[i].offsetBits >> 3]);
+ p = &p[mFields[i].offsetBits >> 3];
+ for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
+ mFields[i].e->incRefs(p);
+ p += mFields[i].e->getSizeBytes();
+ }
}
}
}
@@ -293,7 +302,11 @@ void Element::decRefs(const void *ptr) const
const uint8_t *p = static_cast<const uint8_t *>(ptr);
for (uint32_t i=0; i < mFieldCount; i++) {
if (mFields[i].e->mHasReference) {
- mFields[i].e->decRefs(&p[mFields[i].offsetBits >> 3]);
+ p = &p[mFields[i].offsetBits >> 3];
+ for (uint32_t ct=0; ct < mFields[i].arraySize; ct++) {
+ mFields[i].e->decRefs(p);
+ p += mFields[i].e->getSizeBytes();
+ }
}
}
}
@@ -331,10 +344,11 @@ RsElement rsi_ElementCreate2(Context *rsc,
size_t count,
const RsElement * ein,
const char ** names,
- const size_t * nameLengths)
+ const size_t * nameLengths,
+ const uint32_t * arraySizes)
{
//LOGE("rsi_ElementCreate2 %i", count);
- const Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths);
+ const Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths, arraySizes);
e->incUserRef();
return (RsElement)e;
}
diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h
index b5dad7a23c4a..42eef4adcb0f 100644
--- a/libs/rs/rsElement.h
+++ b/libs/rs/rsElement.h
@@ -66,7 +66,7 @@ public:
static const Element * create(Context *rsc, RsDataType dt, RsDataKind dk,
bool isNorm, uint32_t vecSize);
static const Element * create(Context *rsc, size_t count, const Element **,
- const char **, const size_t * lengths);
+ const char **, const size_t * lengths, const uint32_t *asin);
void incRefs(const void *) const;
void decRefs(const void *) const;
@@ -80,6 +80,7 @@ protected:
String8 name;
ObjectBaseRef<const Element> e;
uint32_t offsetBits;
+ uint32_t arraySize;
} ElementField_t;
ElementField_t *mFields;
size_t mFieldCount;
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index 7661d499b84f..5889bfb23976 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -488,8 +488,9 @@ void FontState::initVertexArrayBuffers()
size_t lengths[2];
lengths[0] = posName.size();
lengths[1] = texName.size();
+ uint32_t arraySizes[2] = {1, 1};
- const Element *vertexDataElem = Element::create(mRSC, 2, elemArray, nameArray, lengths);
+ const Element *vertexDataElem = Element::create(mRSC, 2, elemArray, nameArray, lengths, arraySizes);
Type *vertexDataType = new Type(mRSC);
vertexDataType->setDimX(mMaxNumberOfQuads * 4);
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index a140e224a3f9..662791dbf949 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -17,7 +17,7 @@
#include "rsContext.h"
#include "rsScriptC.h"
#include "rsMatrix.h"
-#include "../../../external/llvm/libbcc/include/bcc/bcc.h"
+#include "../../compile/libbcc/include/bcc/bcc.h"
#include "utils/Timers.h"
#include <GLES/gl.h>
diff --git a/libs/utils/PollLoop.cpp b/libs/utils/PollLoop.cpp
index f740fa0d5255..6d3eeee15cfc 100644
--- a/libs/utils/PollLoop.cpp
+++ b/libs/utils/PollLoop.cpp
@@ -95,6 +95,7 @@ void PollLoop::openWakePipe() {
RequestedCallback requestedCallback;
requestedCallback.callback = NULL;
requestedCallback.looperCallback = NULL;
+ requestedCallback.ident = 0;
requestedCallback.data = NULL;
mRequestedCallbacks.insertAt(requestedCallback, 0);
}
@@ -116,7 +117,7 @@ int32_t PollLoop::pollOnce(int timeoutMillis, int* outEvents, void** outData) {
mPendingFdsPos++;
if (outEvents != NULL) *outEvents = pending.events;
if (outData != NULL) *outData = pending.data;
- return pending.fd;
+ return pending.ident;
}
mLock.lock();
@@ -182,6 +183,7 @@ int32_t PollLoop::pollOnce(int timeoutMillis, int* outEvents, void** outData) {
const RequestedCallback& requestedCallback = mRequestedCallbacks.itemAt(i);
PendingCallback pending;
pending.fd = requestedFd.fd;
+ pending.ident = requestedCallback.ident;
pending.events = revents;
pending.callback = requestedCallback.callback;
pending.looperCallback = requestedCallback.looperCallback;
@@ -191,7 +193,7 @@ int32_t PollLoop::pollOnce(int timeoutMillis, int* outEvents, void** outData) {
mPendingCallbacks.push(pending);
} else if (pending.fd != mWakeReadPipeFd) {
if (result == POLL_CALLBACK) {
- result = pending.fd;
+ result = pending.ident;
if (outEvents != NULL) *outEvents = pending.events;
if (outData != NULL) *outData = pending.data;
} else {
@@ -268,16 +270,20 @@ bool PollLoop::getAllowNonCallbacks() const {
return mAllowNonCallbacks;
}
+void PollLoop::setCallback(int fd, int ident, int events, Callback callback, void* data) {
+ setCallbackCommon(fd, ident, events, callback, NULL, data);
+}
+
void PollLoop::setCallback(int fd, int events, Callback callback, void* data) {
- setCallbackCommon(fd, events, callback, NULL, data);
+ setCallbackCommon(fd, POLL_CALLBACK, events, callback, NULL, data);
}
-void PollLoop::setLooperCallback(int fd, int events, ALooper_callbackFunc* callback,
+void PollLoop::setLooperCallback(int fd, int ident, int events, ALooper_callbackFunc* callback,
void* data) {
- setCallbackCommon(fd, events, NULL, callback, data);
+ setCallbackCommon(fd, ident, events, NULL, callback, data);
}
-void PollLoop::setCallbackCommon(int fd, int events, Callback callback,
+void PollLoop::setCallbackCommon(int fd, int ident, int events, Callback callback,
ALooper_callbackFunc* looperCallback, void* data) {
#if DEBUG_CALLBACKS
@@ -305,6 +311,7 @@ void PollLoop::setCallbackCommon(int fd, int events, Callback callback,
RequestedCallback requestedCallback;
requestedCallback.callback = callback;
requestedCallback.looperCallback = looperCallback;
+ requestedCallback.ident = ident;
requestedCallback.data = data;
ssize_t index = getRequestIndexLocked(fd);
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 2b1f49044d34..e5ece8e8a25a 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -21,6 +21,7 @@
#include <utils/Log.h>
#include <cutils/sched_policy.h>
+#include <cutils/properties.h>
#include <stdio.h>
#include <stdlib.h>
@@ -57,7 +58,7 @@ using namespace android;
// ----------------------------------------------------------------------------
/*
- * Create and run a new thead.
+ * Create and run a new thread.
*
* We create it "detached", so it cleans up after itself.
*/
@@ -280,6 +281,22 @@ pid_t androidGetTid()
#endif
}
+#if defined(HAVE_PTHREADS)
+static pthread_once_t gDoSchedulingGroupOnce = PTHREAD_ONCE_INIT;
+static bool gDoSchedulingGroup = true;
+
+static void checkDoSchedulingGroup(void) {
+ char buf[PROPERTY_VALUE_MAX];
+ int len = property_get("debug.sys.noschedgroups", buf, "");
+ if (len > 0) {
+ int temp;
+ if (sscanf(buf, "%d", &temp) == 1) {
+ gDoSchedulingGroup = temp == 0;
+ }
+ }
+}
+#endif
+
int androidSetThreadSchedulingGroup(pid_t tid, int grp)
{
if (grp > ANDROID_TGROUP_MAX || grp < 0) {
@@ -287,9 +304,12 @@ int androidSetThreadSchedulingGroup(pid_t tid, int grp)
}
#if defined(HAVE_PTHREADS)
- if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
- SP_BACKGROUND : SP_FOREGROUND)) {
- return PERMISSION_DENIED;
+ pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
+ if (gDoSchedulingGroup) {
+ if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
+ SP_BACKGROUND : SP_FOREGROUND)) {
+ return PERMISSION_DENIED;
+ }
}
#endif
@@ -303,10 +323,13 @@ int androidSetThreadPriority(pid_t tid, int pri)
#if defined(HAVE_PTHREADS)
int lasterr = 0;
- if (pri >= ANDROID_PRIORITY_BACKGROUND) {
- rc = set_sched_policy(tid, SP_BACKGROUND);
- } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
- rc = set_sched_policy(tid, SP_FOREGROUND);
+ pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
+ if (gDoSchedulingGroup) {
+ if (pri >= ANDROID_PRIORITY_BACKGROUND) {
+ rc = set_sched_policy(tid, SP_BACKGROUND);
+ } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
+ rc = set_sched_policy(tid, SP_FOREGROUND);
+ }
}
if (rc) {
diff --git a/libs/utils/ZipFileRO.cpp b/libs/utils/ZipFileRO.cpp
index a0e01c693dde..2d53136c1484 100644
--- a/libs/utils/ZipFileRO.cpp
+++ b/libs/utils/ZipFileRO.cpp
@@ -636,7 +636,7 @@ bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer) const
memcpy(buffer, ptr, uncompLen);
} else {
if (!inflateBuffer(buffer, ptr, uncompLen, compLen))
- goto unmap;
+ goto bail;
}
if (compLen > kSequentialMin)
@@ -644,8 +644,6 @@ bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer) const
result = true;
-unmap:
- file->release();
bail:
return result;
}
@@ -669,7 +667,7 @@ bool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const
getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
- FileMap* file = createEntryFileMap(entry);
+ const FileMap* file = createEntryFileMap(entry);
if (file == NULL) {
goto bail;
}
@@ -680,23 +678,21 @@ bool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const
ssize_t actual = write(fd, ptr, uncompLen);
if (actual < 0) {
LOGE("Write failed: %s\n", strerror(errno));
- goto unmap;
+ goto bail;
} else if ((size_t) actual != uncompLen) {
LOGE("Partial write during uncompress (%zd of %zd)\n",
(size_t)actual, (size_t)uncompLen);
- goto unmap;
+ goto bail;
} else {
LOGI("+++ successful write\n");
}
} else {
if (!inflateBuffer(fd, ptr, uncompLen, compLen))
- goto unmap;
+ goto bail;
}
result = true;
-unmap:
- file->release();
bail:
return result;
}
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index 507fa5adbe12..c204a949746c 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -106,7 +106,12 @@ static inline size_t ALIGN(size_t x, size_t alignment) {
void SoftwareRenderer::render(
const void *data, size_t size, void *platformPrivate) {
android_native_buffer_t *buf;
- CHECK_EQ(0, mSurface->dequeueBuffer(mSurface.get(), &buf));
+ int err;
+ if ((err = mSurface->dequeueBuffer(mSurface.get(), &buf)) != 0) {
+ LOGW("Surface::dequeueBuffer returned error %d", err);
+ return;
+ }
+
CHECK_EQ(0, mSurface->lockBuffer(mSurface.get(), buf));
GraphicBufferMapper &mapper = GraphicBufferMapper::get();
@@ -186,7 +191,9 @@ void SoftwareRenderer::render(
CHECK_EQ(0, mapper.unlock(buf->handle));
- CHECK_EQ(0, mSurface->queueBuffer(mSurface.get(), buf));
+ if ((err = mSurface->queueBuffer(mSurface.get(), buf)) != 0) {
+ LOGW("Surface::queueBuffer returned error %d", err);
+ }
buf = NULL;
}
diff --git a/native/android/input.cpp b/native/android/input.cpp
index 379960a27c29..c79f913237ae 100644
--- a/native/android/input.cpp
+++ b/native/android/input.cpp
@@ -246,8 +246,8 @@ float AMotionEvent_getHistoricalOrientation(AInputEvent* motion_event, size_t po
void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper,
- ALooper_callbackFunc* callback, void* data) {
- queue->attachLooper(looper, callback, data);
+ int ident, ALooper_callbackFunc* callback, void* data) {
+ queue->attachLooper(looper, ident, callback, data);
}
void AInputQueue_detachLooper(AInputQueue* queue) {
diff --git a/native/android/looper.cpp b/native/android/looper.cpp
index 1564c477d29e..0aeed7776efe 100644
--- a/native/android/looper.cpp
+++ b/native/android/looper.cpp
@@ -72,9 +72,9 @@ void ALooper_release(ALooper* looper) {
static_cast<PollLoop*>(looper)->decStrong((void*)ALooper_acquire);
}
-void ALooper_addFd(ALooper* looper, int fd, int events,
+void ALooper_addFd(ALooper* looper, int fd, int ident, int events,
ALooper_callbackFunc* callback, void* data) {
- static_cast<PollLoop*>(looper)->setLooperCallback(fd, events, callback, data);
+ static_cast<PollLoop*>(looper)->setLooperCallback(fd, ident, events, callback, data);
}
int32_t ALooper_removeFd(ALooper* looper, int fd) {
diff --git a/native/android/sensor.cpp b/native/android/sensor.cpp
index db534e09dab8..cf7635d2027f 100644
--- a/native/android/sensor.cpp
+++ b/native/android/sensor.cpp
@@ -60,12 +60,12 @@ ASensor const* ASensorManager_getDefaultSensor(ASensorManager* manager, int type
}
ASensorEventQueue* ASensorManager_createEventQueue(ASensorManager* manager,
- ALooper* looper, ALooper_callbackFunc* callback, void* data)
+ ALooper* looper, int ident, ALooper_callbackFunc* callback, void* data)
{
sp<SensorEventQueue> queue =
static_cast<SensorManager*>(manager)->createEventQueue();
if (queue != 0) {
- ALooper_addFd(looper, queue->getFd(), POLLIN, callback, data);
+ ALooper_addFd(looper, queue->getFd(), ident, POLLIN, callback, data);
queue->looper = looper;
queue->incStrong(manager);
}
diff --git a/native/include/android/input.h b/native/include/android/input.h
index 418f6095530e..5b62da44336e 100644
--- a/native/include/android/input.h
+++ b/native/include/android/input.h
@@ -623,10 +623,10 @@ typedef struct AInputQueue AInputQueue;
/*
* Add this input queue to a looper for processing. See
- * ALooper_addFd() for information on the callback and data params.
+ * ALooper_addFd() for information on the ident, callback, and data params.
*/
void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper,
- ALooper_callbackFunc* callback, void* data);
+ int ident, ALooper_callbackFunc* callback, void* data);
/*
* Remove the input queue from the looper it is currently attached to.
diff --git a/native/include/android/looper.h b/native/include/android/looper.h
index 291721624644..287bcd5f0034 100644
--- a/native/include/android/looper.h
+++ b/native/include/android/looper.h
@@ -111,7 +111,7 @@ enum {
*
* Returns ALOPER_POLL_ERROR if an error occurred.
*
- * Returns a value >= 0 containing a file descriptor if it has data
+ * Returns a value >= 0 containing an identifier if its file descriptor has data
* and it has no callback function (requiring the caller here to handle it).
* In this (and only this) case outEvents and outData will contain the poll
* events and data associated with the fd.
@@ -145,10 +145,12 @@ void ALooper_release(ALooper* looper);
* descriptor was previously added, it is replaced.
*
* "fd" is the file descriptor to be added.
+ * "ident" is an identifier for this event, which is returned from
+ * ALooper_pollOnce(). Must be >= 0, or ALOOPER_POLL_CALLBACK if
+ * providing a non-NULL callback.
* "events" are the poll events to wake up on. Typically this is POLLIN.
* "callback" is the function to call when there is an event on the file
* descriptor.
- * "id" is an identifier to associated with this file descriptor, or 0.
* "data" is a private data pointer to supply to the callback.
*
* There are two main uses of this function:
@@ -156,13 +158,13 @@ void ALooper_release(ALooper* looper);
* (1) If "callback" is non-NULL, then
* this function will be called when there is data on the file descriptor. It
* should execute any events it has pending, appropriately reading from the
- * file descriptor.
+ * file descriptor. The 'ident' is ignored in this case.
*
- * (2) If "callback" is NULL, the fd will be returned by ALooper_pollOnce
- * when it has data available, requiring the caller to take care of processing
- * it.
+ * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce
+ * when its file descriptor has data available, requiring the caller to take
+ * care of processing it.
*/
-void ALooper_addFd(ALooper* looper, int fd, int events,
+void ALooper_addFd(ALooper* looper, int fd, int ident, int events,
ALooper_callbackFunc* callback, void* data);
/**
diff --git a/native/include/android/sensor.h b/native/include/android/sensor.h
index b4ce0242682d..a102d43c7fcc 100644
--- a/native/include/android/sensor.h
+++ b/native/include/android/sensor.h
@@ -166,7 +166,7 @@ ASensor const* ASensorManager_getDefaultSensor(ASensorManager* manager, int type
* Creates a new sensor event queue and associate it with a looper.
*/
ASensorEventQueue* ASensorManager_createEventQueue(ASensorManager* manager,
- ALooper* looper, ALooper_callbackFunc* callback, void* data);
+ ALooper* looper, int ident, ALooper_callbackFunc* callback, void* data);
/*
* Destroys the event queue and free all resources associated to it.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
index 33acecb09347..48243ff957d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
@@ -39,6 +39,7 @@ import android.os.Binder;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
+import android.text.TextUtils;
import android.util.Slog;
import android.util.Log;
import android.view.Display;
@@ -468,7 +469,11 @@ public class PhoneStatusBarService extends StatusBarService {
}
// Restart the ticker if it's still running
- tick(notification);
+ if (notification.notification.tickerText != null
+ && !TextUtils.equals(notification.notification.tickerText,
+ oldEntry.notification.notification.tickerText)) {
+ tick(notification);
+ }
// Recalculate the position of the sliding windows and the titles.
setAreThereNotifications();
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
index e7428877d4cc..5f26af4eeb40 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
@@ -175,8 +175,7 @@ abstract class SipPhoneBase extends PhoneBase {
}
public int getPhoneType() {
- // FIXME: add SIP phone type
- return Phone.PHONE_TYPE_GSM;
+ return Phone.PHONE_TYPE_SIP;
}
public SignalStrength getSignalStrength() {
diff --git a/test-runner/src/android/test/ProviderTestCase2.java b/test-runner/src/android/test/ProviderTestCase2.java
index 64d11c56ea92..2811b0d4cf5d 100644
--- a/test-runner/src/android/test/ProviderTestCase2.java
+++ b/test-runner/src/android/test/ProviderTestCase2.java
@@ -74,7 +74,7 @@ public abstract class ProviderTestCase2<T extends ContentProvider> extends Andro
private IsolatedContext mProviderContext;
private MockContentResolver mResolver;
- private class MockContext2 extends MockContext {
+ private class MockContext2 extends MockContext {
@Override
public Resources getResources() {
@@ -87,6 +87,11 @@ public abstract class ProviderTestCase2<T extends ContentProvider> extends Andro
// one created through the regular Context
return getContext().getDir("mockcontext2_" + name, mode);
}
+
+ @Override
+ public Context getApplicationContext() {
+ return this;
+ }
}
/**
* Constructor.
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
index 4cff3de22d37..65da2100e633 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
@@ -81,8 +81,10 @@ public class FileFilter {
// http://b/issue?id=2889595
"ietestcenter/Javascript/15.4.4.15-3-29.html", // hangs the layout tests
// http://b/issue?id=2889596
- "ietestcenter/Javascript/15.4.4.15-3-8.html" // hangs the layout tests
+ "ietestcenter/Javascript/15.4.4.15-3-8.html", // hangs the layout tests
// http://b/issue?id=2889598
+ "http/tests/xmlhttprequest/simple-cross-origin-progress-events.html", // runs webcore into bad state
+ // http://b/2982500
};
static void fillIgnoreResultList() {
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 34cbc44efe11..db1e5eff0d26 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -31,6 +31,16 @@
</activity>
<activity
+ android:name="ResizeActivity"
+ android:label="_Resize"
+ android:windowSoftInputMode="adjustResize">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
android:name="TextGammaActivity"
android:label="_Gamma"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
diff --git a/tests/HwAccelerationTest/res/layout/form.xml b/tests/HwAccelerationTest/res/layout/form.xml
new file mode 100644
index 000000000000..0b17db186cd0
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/form.xml
@@ -0,0 +1,66 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="First name" />
+
+ <EditText
+ android:layout_width="0dip"
+ android:layout_weight="1.0"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="3dip"
+ android:hint="Enter your first name" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Last name" />
+
+ <EditText
+ android:layout_width="0dip"
+ android:layout_weight="1.0"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="3dip"
+ android:hint="Enter your last name" />
+
+ </LinearLayout>
+
+ <EditText
+ android:layout_width="match_parent"
+ android:layout_weight="1.0"
+ android:layout_height="0dip"
+ android:background="#ff7f0000" />
+
+</LinearLayout>
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/ResizeActivity.java b/tests/HwAccelerationTest/src/com/google/android/test/hwui/ResizeActivity.java
new file mode 100644
index 000000000000..e5771b860f47
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/google/android/test/hwui/ResizeActivity.java
@@ -0,0 +1,30 @@
+/*
+ * 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.google.android.test.hwui;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class ResizeActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.form);
+ }
+}